Compare commits

...

62 Commits

Author SHA1 Message Date
Bogdan Ungureanu
9d13d75d29 chore: remove swagger-files from current project in favor of github.com/swaggo/files 2022-06-11 09:49:35 +03:00
Bogdan U
01231131c7 chore: update swagger-ui to 4.11.0 (#214) 2022-06-11 00:58:29 +03:00
Elon Chen
a0f71d471b Update README.md (#213)
corrected grammar mistakes
2022-05-30 23:34:59 +03:00
liaol
de2344d4fd doc: update See Declarative Comments Format URL (#212) 2022-05-20 16:28:17 +03:00
stepbystep2
eb1f2ffcfc docs: starting in Go 1.17, use go install. (#210) 2022-05-12 09:21:43 +03:00
Josh Strohminger
bdcc4ec34b Configure the default OAuth2 ClientID (#209) 2022-05-04 17:13:38 +03:00
Bogdan U
64d8dea07f chore: dependencies (#208) 2022-04-27 18:39:20 +03:00
Bogdan U
88c9ed2643 chore: add multiple api example (#207)
* chore: add multiple api example
* chore: update README.md
2022-04-22 16:50:33 +03:00
Bogdan U
bd7f2153bf chore: linting (#206) 2022-04-22 14:41:42 +03:00
Bogdan U
f844160fb7 chore: security improvement (#203) 2022-04-16 10:34:09 +03:00
Nishith Savla
2ae0634528 fix: typo in word DocExpansion in Readme (#198) 2022-02-22 14:04:11 +02:00
Jakub Mikłasz
cb6be4cbcf feat: add support for swagger-ui persist-authorization (#195) 2022-02-06 13:05:35 +02:00
Bogdan U
0bb2c39427 chore: preserve compatibility with swagger (#194) 2022-02-06 11:18:16 +02:00
Bogdan U
77495f6d48 chore: drop go1.14 support (#193)
* chore: drop go1.14 support
* chore: update go.mod
2022-02-06 11:07:28 +02:00
Bogdan U
872c67c751 chore: drop go1.13 (#190) 2022-01-18 20:34:08 +02:00
Link Duan
74c905c98f feat: enable customization of HTML title (#180) 2021-11-19 12:00:42 +02:00
Jasper
301224e3df fix: incomplete sentences in README (#179) 2021-11-15 14:15:10 +02:00
h44z
8ae7504f84 feat: allow multiple Swagger documents (#168) 2021-11-05 00:49:34 +02:00
alvaro garcia fernandez
498deb2d90 fix: oauth2-redirect outside of the base swagger path (#177) 2021-11-04 22:25:29 +02:00
Ben Wolfaardt
7da8e84293 doc: correct syntax (#175) 2021-11-02 22:10:35 +02:00
Bogdan U
3e21b5982b add png content-type headers (#169) 2021-10-12 22:35:19 +03:00
Bogdan U
c14c0debe8 add goreleaser support (#165)
* add goreleaser.yml
add README.md

* update goreleaser
2021-09-25 15:24:06 +03:00
Bogdan U
5ef0958c32 update swagger ui to 3.52.0 (#164) 2021-09-25 14:33:53 +03:00
Bogdan U
b388ffa3dd add docExpansion feature (#163)
* add docExpansion feature

* add pull request template
2021-09-25 14:14:03 +03:00
Anton Troyanov
6433b1c297 feat(ui): configure default expansion depth for models (#158)
* feat(ui): configure default expansion depth for models

This commit adds possibility to configure defaultModelsExpandDepth,
which controls how models (at the bottom of the API doc) are displayed.

Default value is 1, but it can be set to -1 completely hide the models.

https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md#display

* doc: update README.md

Added Configuration section describing available configuration options.
2021-09-25 01:45:34 +03:00
Xieyuschen
92cfa4c8ef Edit readme to makes it more friendly to newer (#132)
* edit readme to makes it more friendly to newer

* Fix for reviewing

* Fix comment format

Co-authored-by: Xieyuschen <Xieyuschen@users.noreply.github.com>
2021-09-25 00:25:27 +03:00
Bogdan U
f617c815c8 Update ci.yml (#161) 2021-09-23 23:07:29 +03:00
Bogdan U
36e8ef67b6 Add missing pipeline condition 2021-09-23 22:22:51 +03:00
Bogdan U
560c440e4a GitHub actions workflow (#159)
* migrate to GitHub actions

* update example

* update README.md
2021-09-23 22:20:10 +03:00
Bogdan U
d7814aa1af chore: add go 1.15 and go 1.16 to travis (#153) 2021-08-12 15:15:06 +03:00
singhwang
6322a8f797 Solve the integration swagger into the gin framework, access the Chinese garbled problem in the json returned by swagger/doc.json. (#78)
enable UTF8 for swagger json documentation
2021-08-11 23:26:37 +03:00
Bogdan U
8c37e9f279 Update README.md 2021-08-04 23:44:53 +03:00
Bogdan U
71be2548eb improve unit test (#152) 2021-08-04 23:19:30 +03:00
dependabot[bot]
f5258e93ab chore(deps): bump github.com/gin-gonic/gin from 1.4.0 to 1.7.0 (#151)
Bumps [github.com/gin-gonic/gin](https://github.com/gin-gonic/gin) from 1.4.0 to 1.7.0.
- [Release notes](https://github.com/gin-gonic/gin/releases)
- [Changelog](https://github.com/gin-gonic/gin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gin-gonic/gin/compare/v1.4.0...v1.7.0)

---
updated-dependencies:
- dependency-name: github.com/gin-gonic/gin
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-03 15:48:07 +03:00
Liu Yuan
0e6b4ac19e fix data race while set prefix (#125)
fix data race in gin handler
2020-11-03 12:09:07 +02:00
Bogdan U
06d1cc765b Merge pull request #131 from ffenix113/master
Update ugorji/go dependency v1.1.5-pre -> v1.1.13
2020-10-28 09:15:15 +02:00
Yevhen Sylenko
3fc6e81599 Update ugorji/go dependency
Fixes #128
2020-10-27 20:49:40 +01:00
Bogdan U
a30e726acf Remove go1.11 build dependecy (#130) 2020-10-24 17:18:15 +08:00
Bogdan U
68c62b3122 Merge pull request #120 from V-know/master
fix the syntax error in readme
2020-10-24 11:46:15 +03:00
Bogdan U
39399e5d75 Merge pull request #129 from alexandregv/master
Fix typos in README
2020-10-24 11:44:07 +03:00
Alexandre GV
d6f84722fb Fix typos in README 2020-10-23 20:06:14 +02:00
Eason Lin
0be48022e8 chore(travis): drop go 1.11/1.12 (#124) 2020-08-03 19:46:42 +08:00
Anton Dzyk
4199ce8e17 fix working example/basic/api function (#123) 2020-08-03 19:17:43 +08:00
Woen
36fb1b522f fix the syntax error in readme 2020-07-16 18:24:49 +08:00
Bo-Yi Wu
bbeaf5b73c fix import path (#80)
Co-authored-by: Eason Lin <easonlin404@gmail.com>
2020-05-10 01:03:32 +08:00
Eason Lin
819800e541 chore: add go1.12,1.13,1.14 testing (#102) 2020-03-28 14:51:47 +08:00
Eason Lin
bcaba835e4 chore: drop go1.10 test (#103) 2020-03-14 16:22:33 +08:00
adibiarsotp
3db8327ddb feat: implement deeplinking (#86) 2019-11-28 13:27:09 +08:00
Menghan Zheng
d488a69274 fix import in examples (#70) 2019-07-17 15:42:06 +08:00
Bogdan U
4b6a25595f Merge pull request #69 from swaggo/update-readme
chore: update generated doc import
2019-07-16 14:31:56 +03:00
easonlin
e40184058e chore: update generated doc import 2019-07-16 17:23:33 +08:00
Eason Lin
2bdb1e51dc fix(doc): fix go get imported pkg (#68) 2019-07-05 22:50:31 +08:00
Eason Lin
08f491371f feat: update swagger embedded files (#66) 2019-07-05 15:56:58 +08:00
Eason Lin
2d58c08c49 chore(travis): remove go 1.8/1.9 (#67) 2019-07-05 15:30:38 +08:00
Tang Weizhi
ddb1576126 chore: improved readme (#61) 2019-06-13 15:24:37 +08:00
Eason Lin
6495b29b49 chore(mod): update gin v1.4.0 and swag v1.5.1 (#60) 2019-06-13 10:33:36 +09:00
Josef Hák
dbf6ef4100 feat: support for gzip middleware (#53) 2019-04-03 10:59:18 +08:00
Eason Lin
9668210ca1 feat(WrapHandler): add config using functional options (#52)
* feat(WrapHandler): add config using functional options

* refine comment
2019-03-29 10:46:37 +09:00
Eason Lin
f9b4e464b0 doc(readme): fix canonical example (#49) 2019-03-24 21:20:11 +09:00
pei
db2fafd4b0 feat: support swagger configuration (#48) 2019-03-24 09:56:13 +08:00
pei
acdcd7f6da Revert "feat: support swagger configuration (#46)" (#47)
This reverts commit 814845170e.
2019-03-23 19:16:08 +09:00
Eason Lin
814845170e feat: support swagger configuration (#46) 2019-03-23 17:04:42 +08:00
46 changed files with 1640 additions and 814 deletions

24
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
name: build
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
test:
strategy:
matrix:
go: [ '1.15.x', '1.16.x', '1.17.x', '1.18.x' ]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Set up Go
uses: actions/setup-go@v1
with:
go-version: ${{ matrix.go }}
- name: test
run: go test -coverprofile=coverage.txt -covermode=atomic
- name: coverage
run: bash <(curl -s https://codecov.io/bash)

6
.gitignore vendored
View File

@@ -9,4 +9,8 @@
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
dist
dist
.idea
vendor
.envrc

10
.goreleaser.yml Normal file
View File

@@ -0,0 +1,10 @@
builds:
- skip: true
snapshot:
name_template: "{{ .Tag }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'

View File

@@ -1,19 +0,0 @@
language: go
go:
- 1.8.x
- 1.9.x
- 1.10.x
- 1.11.x
matrix:
fast_finish: true
include:
- go: 1.11.x
env: GO111MODULE=on
script:
- go test -coverprofile=coverage.txt -covermode=atomic
after_success:
- bash <(curl -s https://codecov.io/bash)

8
PULL_REQUEST_TEMPLATE.md Normal file
View File

@@ -0,0 +1,8 @@
**Describe the PR**
e.g. add cool parser.
**Relation issue**
e.g. https://github.com/swaggo/gin-swagger/pull/123/files
**Additional context**
Add any other context about the problem here.

185
README.md
View File

@@ -2,117 +2,178 @@
gin middleware to automatically generate RESTful API documentation with Swagger 2.0.
[![Travis branch](https://img.shields.io/travis/swaggo/gin-swagger/master.svg)](https://travis-ci.org/swaggo/gin-swagger)
[![Build Status](https://github.com/swaggo/gin-swagger/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/features/actions)
[![Codecov branch](https://img.shields.io/codecov/c/github/swaggo/gin-swagger/master.svg)](https://codecov.io/gh/swaggo/gin-swagger)
[![Go Report Card](https://goreportcard.com/badge/github.com/swaggo/gin-swagger)](https://goreportcard.com/report/github.com/swaggo/gin-swagger)
[![GoDoc](https://godoc.org/github.com/swaggo/gin-swagger?status.svg)](https://godoc.org/github.com/swaggo/gin-swagger)
[![Release](https://img.shields.io/github/release/swaggo/gin-swagger.svg?style=flat-square)](https://github.com/swaggo/gin-swagger/releases)
## Usage
### Start using it
1. Add comments to your API source code, [See Declarative Comments Format](https://swaggo.github.io/swaggo.io/declarative_comments_format/).
1. Add comments to your API source code, [See Declarative Comments Format](https://github.com/swaggo/swag/blob/master/README.md#declarative-comments-format).
2. Download [Swag](https://github.com/swaggo/swag) for Go by using:
```sh
$ go get -u github.com/swaggo/swag/cmd/swag
go get -u github.com/swaggo/swag/cmd/swag
```
3. Run the [Swag](https://github.com/swaggo/swag) in your Go project root folder which contains `main.go` file, [Swag](https://github.com/swaggo/swag) will parse comments and generate required files(`docs` folder and `docs/doc.go`).
Starting in Go 1.17, installing executables with `go get` is deprecated. `go install` may be used instead:
```sh
$ swag init
go install github.com/swaggo/swag/cmd/swag
```
4.Download [gin-swagger](https://github.com/swaggo/gin-swagger) by using:
3. Run the [Swag](https://github.com/swaggo/swag) at your Go project root path(for instance `~/root/go-peoject-name`),
[Swag](https://github.com/swaggo/swag) will parse comments and generate required files(`docs` folder and `docs/doc.go`)
at `~/root/go-peoject-name/docs`.
```sh
$ go get -u github.com/swaggo/gin-swagger
$ go get -u github.com/swaggo/gin-swagger/swaggerFiles
swag init
```
And import following in your code:
4. Download [gin-swagger](https://github.com/swaggo/gin-swagger) by using:
```sh
go get -u github.com/swaggo/gin-swagger
go get -u github.com/swaggo/files
```
Import following in your code:
```go
import "github.com/swaggo/gin-swagger" // gin-swagger middleware
import "github.com/swaggo/gin-swagger/swaggerFiles" // swagger embed files
import "github.com/swaggo/files" // swagger embed files
```
### Canonical example:
Now assume you have implemented a simple api as following:
```go
package main
// A get function which returns a hello world string by json
func Helloworld(g *gin.Context) {
g.JSON(http.StatusOK,"helloworld")
}
import (
"github.com/gin-gonic/gin"
"github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/swaggerFiles"
```
_ "./docs" // docs is generated by Swag CLI, you have to import it.
)
So how to use gin-swagger on api above? Just follow the following guide.
// @title Swagger Example API
// @version 1.0
// @description This is a sample server Petstore server.
// @termsOfService http://swagger.io/terms/
1. Add Comments for apis and main function with gin-swagger rules like following:
// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io
```go
// @BasePath /api/v1
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @host petstore.swagger.io
// @BasePath /v2
func main() {
r := gin.New()
// use ginSwagger middleware to
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
r.Run()
// PingExample godoc
// @Summary ping example
// @Schemes
// @Description do ping
// @Tags example
// @Accept json
// @Produce json
// @Success 200 {string} Helloworld
// @Router /example/helloworld [get]
func Helloworld(g *gin.Context) {
g.JSON(http.StatusOK,"helloworld")
}
```
5. Run it, and browser to http://localhost:8080/swagger/index.html, you can see Swagger 2.0 Api documents.
2. Use `swag init` command to generate a docs, docs generated will be stored at `docs/`.
3. import the docs like this:
I assume your project named `github.com/go-project-name/docs`.
![swagger_index.html](https://user-images.githubusercontent.com/8943871/31943004-dd08a10e-b88c-11e7-9e77-19d2c759a586.png)
```go
import (
docs "github.com/go-project-name/docs"
)
```
6. If you want to disable swagger when some environment variable is set, use `DisablingWrapHandler`
4. build your application and after that, go to http://localhost:8080/swagger/index.html ,you to see your Swagger UI.
### Example with disabling:
5. The full code and folder relatives here:
```go
package main
import (
"github.com/gin-gonic/gin"
"github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/swaggerFiles"
_ "./docs" // docs is generated by Swag CLI, you have to import it.
"github.com/gin-gonic/gin"
docs "github.com/go-project-name/docs"
swaggerfiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
"net/http"
)
// @BasePath /api/v1
// @title Swagger Example API
// @version 1.0
// @description This is a sample server Petstore server.
// @termsOfService http://swagger.io/terms/
// PingExample godoc
// @Summary ping example
// @Schemes
// @Description do ping
// @Tags example
// @Accept json
// @Produce json
// @Success 200 {string} Helloworld
// @Router /example/helloworld [get]
func Helloworld(g *gin.Context) {
g.JSON(http.StatusOK,"helloworld")
}
// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io
func main() {
r := gin.Default()
docs.SwaggerInfo.BasePath = "/api/v1"
v1 := r.Group("/api/v1")
{
eg := v1.Group("/example")
{
eg.GET("/helloworld",Helloworld)
}
}
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))
r.Run(":8080")
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
}
```
// @host petstore.swagger.io
// @BasePath /v2
Demo project tree, `swag init` is run at relative `.`
```
.
├── docs
│   ├── docs.go
│   ├── swagger.json
│   └── swagger.yaml
├── go.mod
├── go.sum
└── main.go
```
## Multiple APIs
This feature was introduced in swag v1.7.9
## Configuration
You can configure Swagger using different configuration options
```go
func main() {
r := gin.New()
// use ginSwagger middleware to
r.GET("/swagger/*any", ginSwagger.DisablingWrapHandler(swaggerFiles.Handler, "NAME_OF_ENV_VARIABLE"))
ginSwagger.WrapHandler(swaggerFiles.Handler,
ginSwagger.URL("http://localhost:8080/swagger/doc.json"),
ginSwagger.DefaultModelsExpandDepth(-1))
r.Run()
}
```
Then, if you set envioment variable `NAME_OF_ENV_VARIABLE` to anything, `/swagger/*any`
will respond 404, just like when route unspecified.
| Option | Type | Default | Description |
| ------------------------ | ------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| URL | string | "doc.json" | URL pointing to API definition |
| DocExpansion | string | "list" | Controls the default expansion setting for the operations and tags. It can be 'list' (expands only the tags), 'full' (expands the tags and operations) or 'none' (expands nothing). |
| DeepLinking | bool | true | If set to true, enables deep linking for tags and operations. See the Deep Linking documentation for more information. |
| DefaultModelsExpandDepth | int | 1 | Default expansion depth for models (set to -1 completely hide the models). |
| InstanceName | string | "swagger" | The instance name of the swagger document. If multiple different swagger instances should be deployed on one gin router, ensure that each instance has a unique name (use the _--instanceName_ parameter to generate swagger documents with _swag init_). |
| PersistAuthorization | bool | false | If set to true, it persists authorization data and it would not be lost on browser close/refresh. |
| Oauth2DefaultClientID | string | "" | If set, it's used to prepopulate the *client_id* field of the OAuth2 Authorization dialog. |

84
b0x.yml
View File

@@ -1,84 +0,0 @@
# all folders and files are relative to the path
# where fileb0x was run at!
# default: main
pkg: swaggerFiles
# destination
dest: "./swaggerFiles/"
# gofmt
# type: bool
# default: false
fmt: true
# compress files
# at the moment, only supports gzip
#
# type: object
compression:
# activates the compression
#
# type: bool
# default: false
compress: false
# valid values are:
# -> "NoCompression"
# -> "BestSpeed"
# -> "BestCompression"
# -> "DefaultCompression" or ""
#
# type: string
# default: "DefaultCompression" # when: Compress == true && Method == ""
method: ""
# true = do it yourself (the file is written as gzip compressed file into the memory file system)
# false = decompress files at run time (while writing file into memory file system)
#
# type: bool
# default: false
keep: false
# ---------------
# -- DANGEROUS --
# ---------------
#
# cleans the destination folder (only b0xfiles)
# you should use this when using the spread function
# type: bool
# default: false
clean: true
# default: ab0x.go
output: "ab0x.go"
# [unexporTed] builds non-exporTed functions, variables and types...
# type: bool
# default: false
unexporTed: false
# [spread] means it will make a file to hold all fileb0x data
# and each file into a separaTed .go file
#
# example:
# theres 2 files in the folder assets, they're: hello.json and world.txt
# when spread is activaTed, fileb0x will make a file:
# b0x.go or [output]'s data, assets_hello.json.go and assets_world.txt.go
#
#
# type: bool
# default: false
spread: true
# type: array of objects
custom:
- files:
# everything inside the folder
# type: array of strings
- "./dist/"
# base is the path that will be removed from all files' path
# type: string
base: "dist"

153
example/basic/docs/docs.go Normal file
View File

@@ -0,0 +1,153 @@
// Package docs GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
// This file was generated by swaggo/swag
package docs
import "github.com/swaggo/swag"
const docTemplate_swagger = `{
"schemes": {{ marshal .Schemes }},
"swagger": "2.0",
"info": {
"description": "{{escape .Description}}",
"title": "{{.Title}}",
"termsOfService": "http://swagger.io/terms/",
"contact": {
"name": "API Support",
"url": "http://www.swagger.io/support",
"email": "support@swagger.io"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
},
"version": "{{.Version}}"
},
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/testapi/get-string-by-int/{some_id}": {
"get": {
"description": "get string by ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"summary": "Add a new pet to the store",
"parameters": [
{
"type": "integer",
"description": "Some ID",
"name": "some_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "ok",
"schema": {
"type": "string"
}
},
"400": {
"description": "We need ID!!",
"schema": {
"$ref": "#/definitions/web.APIError"
}
},
"404": {
"description": "Can not find ID",
"schema": {
"$ref": "#/definitions/web.APIError"
}
}
}
}
},
"/testapi/get-struct-array-by-string/{some_id}": {
"get": {
"description": "get struct array by ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"parameters": [
{
"type": "string",
"description": "Some ID",
"name": "some_id",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "Offset",
"name": "offset",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Offset",
"name": "limit",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "ok",
"schema": {
"type": "string"
}
},
"400": {
"description": "We need ID!!",
"schema": {
"$ref": "#/definitions/web.APIError"
}
},
"404": {
"description": "Can not find ID",
"schema": {
"$ref": "#/definitions/web.APIError"
}
}
}
}
}
},
"definitions": {
"web.APIError": {
"type": "object",
"properties": {
"errorCode": {
"type": "integer"
},
"errorMessage": {
"type": "string"
}
}
}
}
}`
// SwaggerInfo_swagger holds exported Swagger Info so clients can modify it
var SwaggerInfo_swagger = &swag.Spec{
Version: "1.0",
Host: "petstore.swagger.io:8080",
BasePath: "/v2",
Schemes: []string{},
Title: "Swagger Example API",
Description: "This is a sample server Petstore server.",
InfoInstanceName: "swagger",
SwaggerTemplate: docTemplate_swagger,
}
func init() {
swag.Register(SwaggerInfo_swagger.InstanceName(), SwaggerInfo_swagger)
}

View File

@@ -1,14 +1,4 @@
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
// This file was generated by swaggo/swag at
// 2017-06-25 01:25:37.872454531 +0800 CST
package docs
import (
"github.com/swaggo/swag"
)
var doc = `{
{
"swagger": "2.0",
"info": {
"description": "This is a sample server Petstore server.",
@@ -25,7 +15,7 @@ var doc = `{
},
"version": "1.0"
},
"host": "petstore.swagger.io",
"host": "petstore.swagger.io:8080",
"basePath": "/v2",
"paths": {
"/testapi/get-string-by-int/{some_id}": {
@@ -40,13 +30,11 @@ var doc = `{
"summary": "Add a new pet to the store",
"parameters": [
{
"type": "integer",
"description": "Some ID",
"name": "some_id",
"in": "path",
"required": true,
"schema": {
"type": "int"
}
"required": true
}
],
"responses": {
@@ -59,14 +47,12 @@ var doc = `{
"400": {
"description": "We need ID!!",
"schema": {
"type": "object",
"$ref": "#/definitions/web.APIError"
}
},
"404": {
"description": "Can not find ID",
"schema": {
"type": "object",
"$ref": "#/definitions/web.APIError"
}
}
@@ -84,31 +70,25 @@ var doc = `{
],
"parameters": [
{
"type": "string",
"description": "Some ID",
"name": "some_id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
"required": true
},
{
"type": "integer",
"description": "Offset",
"name": "offset",
"in": "query",
"required": true,
"schema": {
"type": "int"
}
"required": true
},
{
"type": "integer",
"description": "Offset",
"name": "limit",
"in": "query",
"required": true,
"schema": {
"type": "int"
}
"required": true
}
],
"responses": {
@@ -121,14 +101,12 @@ var doc = `{
"400": {
"description": "We need ID!!",
"schema": {
"type": "object",
"$ref": "#/definitions/web.APIError"
}
},
"404": {
"description": "Can not find ID",
"schema": {
"type": "object",
"$ref": "#/definitions/web.APIError"
}
}
@@ -140,22 +118,13 @@ var doc = `{
"web.APIError": {
"type": "object",
"properties": {
"ErrorCode": {
"type": "int"
"errorCode": {
"type": "integer"
},
"ErrorMessage": {
"errorMessage": {
"type": "string"
}
}
}
}
}`
type s struct{}
func (s *s) ReadDoc() string {
return doc
}
func init() {
swag.Register(swag.Name, &s{})
}
}

View File

@@ -0,0 +1,87 @@
basePath: /v2
definitions:
web.APIError:
properties:
errorCode:
type: integer
errorMessage:
type: string
type: object
host: petstore.swagger.io:8080
info:
contact:
email: support@swagger.io
name: API Support
url: http://www.swagger.io/support
description: This is a sample server Petstore server.
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
termsOfService: http://swagger.io/terms/
title: Swagger Example API
version: "1.0"
paths:
/testapi/get-string-by-int/{some_id}:
get:
consumes:
- application/json
description: get string by ID
parameters:
- description: Some ID
in: path
name: some_id
required: true
type: integer
produces:
- application/json
responses:
"200":
description: ok
schema:
type: string
"400":
description: We need ID!!
schema:
$ref: '#/definitions/web.APIError'
"404":
description: Can not find ID
schema:
$ref: '#/definitions/web.APIError'
summary: Add a new pet to the store
/testapi/get-struct-array-by-string/{some_id}:
get:
consumes:
- application/json
description: get struct array by ID
parameters:
- description: Some ID
in: path
name: some_id
required: true
type: string
- description: Offset
in: query
name: offset
required: true
type: integer
- description: Offset
in: query
name: limit
required: true
type: integer
produces:
- application/json
responses:
"200":
description: ok
schema:
type: string
"400":
description: We need ID!!
schema:
$ref: '#/definitions/web.APIError'
"404":
description: Can not find ID
schema:
$ref: '#/definitions/web.APIError'
swagger: "2.0"

37
example/basic/main.go Normal file
View File

@@ -0,0 +1,37 @@
package main
import (
"github.com/gin-gonic/gin"
swaggerFiles "github.com/swaggo/files"
"github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/example/basic/api"
_ "github.com/swaggo/gin-swagger/example/basic/docs"
)
// @title Swagger Example API
// @version 1.0
// @description This is a sample server Petstore server.
// @termsOfService http://swagger.io/terms/
// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @host petstore.swagger.io:8080
// @BasePath /v2
func main() {
r := gin.New()
r.GET("/v2/testapi/get-string-by-int/:some_id", api.GetStringByInt)
r.GET("/v2/testapi/get-struct-array-by-string/:some_id", api.GetStructArrayByString)
url := ginSwagger.URL("http://petstore.swagger.io:8080/swagger/doc.json") // The url pointing to API definition
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, url))
r.Run()
}

View File

@@ -0,0 +1,44 @@
// Package docs GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
// This file was generated by swaggo/swag
package docs
import "github.com/swaggo/swag"
const docTemplate_swagger = `{
"schemes": {{ marshal .Schemes }},
"swagger": "2.0",
"info": {
"description": "{{escape .Description}}",
"title": "{{.Title}}",
"termsOfService": "http://swagger.io/terms/",
"contact": {
"name": "API Support",
"url": "http://www.swagger.io/support",
"email": "support@swagger.io"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
},
"version": "{{.Version}}"
},
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {}
}`
// SwaggerInfo_swagger holds exported Swagger Info so clients can modify it
var SwaggerInfo_swagger = &swag.Spec{
Version: "1.0",
Host: "petstore.swagger.io",
BasePath: "/v2",
Schemes: []string{},
Title: "Swagger Example API",
Description: "This is a sample server Petstore server.",
InfoInstanceName: "swagger",
SwaggerTemplate: docTemplate_swagger,
}
func init() {
swag.Register(SwaggerInfo_swagger.InstanceName(), SwaggerInfo_swagger)
}

View File

@@ -0,0 +1,21 @@
{
"swagger": "2.0",
"info": {
"description": "This is a sample server Petstore server.",
"title": "Swagger Example API",
"termsOfService": "http://swagger.io/terms/",
"contact": {
"name": "API Support",
"url": "http://www.swagger.io/support",
"email": "support@swagger.io"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
},
"version": "1.0"
},
"host": "petstore.swagger.io",
"basePath": "/v2",
"paths": {}
}

View File

@@ -0,0 +1,16 @@
basePath: /v2
host: petstore.swagger.io
info:
contact:
email: support@swagger.io
name: API Support
url: http://www.swagger.io/support
description: This is a sample server Petstore server.
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
termsOfService: http://swagger.io/terms/
title: Swagger Example API
version: "1.0"
paths: {}
swagger: "2.0"

View File

@@ -1,11 +1,12 @@
package main
import (
"github.com/gin-contrib/gzip"
"github.com/gin-gonic/gin"
swaggerFiles "github.com/swaggo/files"
"github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/swaggerFiles"
_ "github.com/swaggo/gin-swagger/example/docs"
_ "github.com/swaggo/gin-swagger/example/basic/docs"
)
// @title Swagger Example API
@@ -25,7 +26,10 @@ import (
func main() {
r := gin.New()
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
r.Use(gzip.Gzip(gzip.BestSpeed))
url := ginSwagger.URL("http://localhost:8080/swagger/doc.json") // The url pointing to API definition
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, url))
r.Run()
}

View File

@@ -0,0 +1,23 @@
# Multiple API feature
Since swag 1.7.9 we are allowing registration of multiple endpoints into the same server.
Generate documentation for v1 endpoints
```shell
swag i -g main.go -dir api/v1 --instanceName v1
```
Generate documentation for v2 endpoints
```shell
swag i -g main.go -dir api/v2 --instanceName v2
```
Run example
```shell
go run main.go
```
Now you can access the v1 swagger here [http://localhost:8080/swagger/v1/index.html](http://localhost:8080/swagger/v1/index.html) ,
and v2 swagger here [http://localhost:8080/swagger/v2/index.html](http://localhost:8080/swagger/v2/index.html)

View File

@@ -0,0 +1,26 @@
package v1
import (
"github.com/gin-gonic/gin"
)
type Book struct {
ID int `json:"id,omitempty"`
Title string `json:"title"`
Author string `json:"author"`
Year *uint16 `json:"year"`
}
//
// @Summary Get a list of books in the the store
// @Description get string by ID
// @Accept json
// @Produce json
// @Success 200 {array} Book "ok"
// @Router /books [get]
func GetBooks(ctx *gin.Context) {
ctx.JSON(200, []Book{
{ID: 1, Title: "Book 1", Author: "Author 1", Year: nil},
{ID: 2, Title: "Book 2", Author: "Author 2", Year: nil},
})
}

View File

@@ -0,0 +1,25 @@
package v1
import (
"github.com/gin-gonic/gin"
)
// @title Swagger Example API
// @version 1.0
// @description This is a sample server.
// @termsOfService http://swagger.io/terms/
// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @BasePath /v1
func Register(router *gin.Engine) {
v1 := router.Group("v1")
v1.GET("/books", GetBooks)
}

View File

@@ -0,0 +1,26 @@
package v2
import (
"github.com/gin-gonic/gin"
)
type Book struct {
ID int `json:"id,omitempty"`
Title string `json:"title"`
Author string `json:"author"`
Year *uint16 `json:"year"`
}
//
// @Summary Get a list of books in the the store
// @Description get string by ID
// @Accept json
// @Produce json
// @Success 200 {array} Book "ok"
// @Router /books [get]
func GetBooks(ctx *gin.Context) {
ctx.JSON(200, []Book{
{ID: 1, Title: "Book 3", Author: "Author 3", Year: nil},
{ID: 2, Title: "Book 4", Author: "Author 4", Year: nil},
})
}

View File

@@ -0,0 +1,25 @@
package v2
import (
"github.com/gin-gonic/gin"
)
// @title Swagger Example API
// @version 2.0
// @description This is a sample server.
// @termsOfService http://swagger.io/terms/
// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @BasePath /v2
func Register(router *gin.Engine) {
v2 := router.Group("v2")
v2.GET("/books", GetBooks)
}

View File

@@ -0,0 +1,87 @@
// Package docs GENERATED BY SWAG; DO NOT EDIT
// This file was generated by swaggo/swag
package docs
import "github.com/swaggo/swag"
const docTemplatev1 = `{
"schemes": {{ marshal .Schemes }},
"swagger": "2.0",
"info": {
"description": "{{escape .Description}}",
"title": "{{.Title}}",
"termsOfService": "http://swagger.io/terms/",
"contact": {
"name": "API Support",
"url": "http://www.swagger.io/support",
"email": "support@swagger.io"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
},
"version": "{{.Version}}"
},
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/books": {
"get": {
"description": "get string by ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"summary": "Get a list of books in the the store",
"responses": {
"200": {
"description": "ok",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/v1.Book"
}
}
}
}
}
}
},
"definitions": {
"v1.Book": {
"type": "object",
"properties": {
"author": {
"type": "string"
},
"id": {
"type": "integer"
},
"title": {
"type": "string"
},
"year": {
"type": "integer"
}
}
}
}
}`
// SwaggerInfov1 holds exported Swagger Info so clients can modify it
var SwaggerInfov1 = &swag.Spec{
Version: "1.0",
Host: "",
BasePath: "/v1",
Schemes: []string{},
Title: "Swagger Example API",
Description: "This is a sample server.",
InfoInstanceName: "v1",
SwaggerTemplate: docTemplatev1,
}
func init() {
swag.Register(SwaggerInfov1.InstanceName(), SwaggerInfov1)
}

View File

@@ -0,0 +1,63 @@
{
"swagger": "2.0",
"info": {
"description": "This is a sample server.",
"title": "Swagger Example API",
"termsOfService": "http://swagger.io/terms/",
"contact": {
"name": "API Support",
"url": "http://www.swagger.io/support",
"email": "support@swagger.io"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
},
"version": "1.0"
},
"basePath": "/v1",
"paths": {
"/books": {
"get": {
"description": "get string by ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"summary": "Get a list of books in the the store",
"responses": {
"200": {
"description": "ok",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/v1.Book"
}
}
}
}
}
}
},
"definitions": {
"v1.Book": {
"type": "object",
"properties": {
"author": {
"type": "string"
},
"id": {
"type": "integer"
},
"title": {
"type": "string"
},
"year": {
"type": "integer"
}
}
}
}
}

View File

@@ -0,0 +1,42 @@
basePath: /v1
definitions:
v1.Book:
properties:
author:
type: string
id:
type: integer
title:
type: string
year:
type: integer
type: object
info:
contact:
email: support@swagger.io
name: API Support
url: http://www.swagger.io/support
description: This is a sample server.
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
termsOfService: http://swagger.io/terms/
title: Swagger Example API
version: "1.0"
paths:
/books:
get:
consumes:
- application/json
description: get string by ID
produces:
- application/json
responses:
"200":
description: ok
schema:
items:
$ref: '#/definitions/v1.Book'
type: array
summary: Get a list of books in the the store
swagger: "2.0"

View File

@@ -0,0 +1,87 @@
// Package docs GENERATED BY SWAG; DO NOT EDIT
// This file was generated by swaggo/swag
package docs
import "github.com/swaggo/swag"
const docTemplatev2 = `{
"schemes": {{ marshal .Schemes }},
"swagger": "2.0",
"info": {
"description": "{{escape .Description}}",
"title": "{{.Title}}",
"termsOfService": "http://swagger.io/terms/",
"contact": {
"name": "API Support",
"url": "http://www.swagger.io/support",
"email": "support@swagger.io"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
},
"version": "{{.Version}}"
},
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/books": {
"get": {
"description": "get string by ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"summary": "Get a list of books in the the store",
"responses": {
"200": {
"description": "ok",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/v2.Book"
}
}
}
}
}
}
},
"definitions": {
"v2.Book": {
"type": "object",
"properties": {
"author": {
"type": "string"
},
"id": {
"type": "integer"
},
"title": {
"type": "string"
},
"year": {
"type": "integer"
}
}
}
}
}`
// SwaggerInfov2 holds exported Swagger Info so clients can modify it
var SwaggerInfov2 = &swag.Spec{
Version: "2.0",
Host: "",
BasePath: "/v2",
Schemes: []string{},
Title: "Swagger Example API",
Description: "This is a sample server.",
InfoInstanceName: "v2",
SwaggerTemplate: docTemplatev2,
}
func init() {
swag.Register(SwaggerInfov2.InstanceName(), SwaggerInfov2)
}

View File

@@ -0,0 +1,63 @@
{
"swagger": "2.0",
"info": {
"description": "This is a sample server.",
"title": "Swagger Example API",
"termsOfService": "http://swagger.io/terms/",
"contact": {
"name": "API Support",
"url": "http://www.swagger.io/support",
"email": "support@swagger.io"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
},
"version": "2.0"
},
"basePath": "/v2",
"paths": {
"/books": {
"get": {
"description": "get string by ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"summary": "Get a list of books in the the store",
"responses": {
"200": {
"description": "ok",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/v2.Book"
}
}
}
}
}
}
},
"definitions": {
"v2.Book": {
"type": "object",
"properties": {
"author": {
"type": "string"
},
"id": {
"type": "integer"
},
"title": {
"type": "string"
},
"year": {
"type": "integer"
}
}
}
}
}

View File

@@ -0,0 +1,42 @@
basePath: /v2
definitions:
v2.Book:
properties:
author:
type: string
id:
type: integer
title:
type: string
year:
type: integer
type: object
info:
contact:
email: support@swagger.io
name: API Support
url: http://www.swagger.io/support
description: This is a sample server.
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
termsOfService: http://swagger.io/terms/
title: Swagger Example API
version: "2.0"
paths:
/books:
get:
consumes:
- application/json
description: get string by ID
produces:
- application/json
responses:
"200":
description: ok
schema:
items:
$ref: '#/definitions/v2.Book'
type: array
summary: Get a list of books in the the store
swagger: "2.0"

26
example/multiple/main.go Normal file
View File

@@ -0,0 +1,26 @@
package main
import (
"github.com/gin-gonic/gin"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
v1 "github.com/swaggo/gin-swagger/example/multiple/api/v1"
v2 "github.com/swaggo/gin-swagger/example/multiple/api/v2"
_ "github.com/swaggo/gin-swagger/example/multiple/docs"
)
func main() {
// New gin router
router := gin.New()
// Register api/v1 endpoints
v1.Register(router)
router.GET("/swagger/v1/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, ginSwagger.InstanceName("v1")))
// Register api/v2 endpoints
v2.Register(router)
router.GET("/swagger/v2/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, ginSwagger.InstanceName("v2")))
// Listen and Server in
_ = router.Run()
}

22
go.mod
View File

@@ -1,18 +1,12 @@
module github.com/swaggo/gin-swagger
go 1.15
require (
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7 // indirect
github.com/gin-gonic/gin v1.3.0
github.com/go-openapi/jsonreference v0.18.0 // indirect
github.com/go-openapi/spec v0.18.0 // indirect
github.com/golang/protobuf v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.4 // indirect
github.com/pkg/errors v0.8.1 // indirect
github.com/stretchr/testify v1.3.0
github.com/swaggo/swag v1.4.0
github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2 // indirect
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e
golang.org/x/tools v0.0.0-20190110015856-aa033095749b // indirect
gopkg.in/go-playground/validator.v8 v8.18.2 // indirect
gopkg.in/yaml.v2 v2.2.2 // indirect
github.com/gin-contrib/gzip v0.0.5
github.com/gin-gonic/gin v1.7.7
github.com/stretchr/testify v1.7.0
github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe
github.com/swaggo/swag v1.8.1
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4
)

185
go.sum
View File

@@ -1,52 +1,157 @@
github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4=
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/agiledragon/gomonkey/v2 v2.3.1 h1:k+UnUY0EMNYUFUAQVETGY9uUTxjMdnUkP0ARyJS1zzs=
github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7 h1:AzN37oI0cOS+cougNAV9szl6CVoj2RYwzS3DpUQNtlY=
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-gonic/gin v1.3.0 h1:kCmZyPklC0gVdL728E6Aj20uYBJV93nj/TkwBTKhFbs=
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0=
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.18.0 h1:oP2OUNdG1l2r5kYhrfVMXO54gWmzcfAwP/GFuHpNTkE=
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/spec v0.18.0 h1:aIjeyG5mo5/FrvDkpKKEGZPmF9MPHahS72mzfVqeQXQ=
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/swag v0.17.0 h1:iqrgMg7Q7SvtbWLlltPrkMs0UBJI6oTSs79JFRUi880=
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/gzip v0.0.3 h1:etUaeesHhEORpZMp18zoOhepboiWnFtXrBZxszWUn4k=
github.com/gin-contrib/gzip v0.0.3/go.mod h1:YxxswVZIqOvcHEQpsSn+QF5guQtO1dCfy0shBPy4jFc=
github.com/gin-contrib/gzip v0.0.5 h1:mhnVU32YnnBh2LPH2iqRqsA/eR7SAqRaD388jL2s/j0=
github.com/gin-contrib/gzip v0.0.5/go.mod h1:OPIK6HR0Um2vNmBUTlayD7qle4yVVRZT0PyhdUigrKk=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs=
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE=
github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U=
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
github.com/otiai10/curr v1.0.0 h1:TJIWdbX0B+kpNagQrjgq8bCMrbhiuX73M2XwgtDMoOI=
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
github.com/otiai10/mint v1.3.3 h1:7JgpsBaN0uMkyju4tbYHu0mnM55hNKVYLsXmwr15NQI=
github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/swaggo/swag v1.4.0 h1:exX5ES4CdJWCCKmVPE+FAIN66cnHeMHU3i2SCMibBZc=
github.com/swaggo/swag v1.4.0/go.mod h1:hog2WgeMOrQ/LvQ+o1YGTeT+vWVrbi0SiIslBtxKTyM=
github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2 h1:EICbibRW4JNKMcY+LsWmuwob+CRS1BmdRdjphAm9mH4=
github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2 h1:+iNTcqQJy0OZ5jk6a5NLib47eqXK8uYcPX+O4+cBpEM=
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w=
github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe h1:K8pHPVoTgxFJt1lXuIzzOX7zZhZFldJQK/CgKx9BFIc=
github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w=
github.com/swaggo/swag v1.8.1 h1:JuARzFX1Z1njbCGz+ZytBR15TFJwF2Q7fu8puJHhQYI=
github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190110015856-aa033095749b h1:G5tsw1T5VA7PD7VmXyGtX/hQp3ABPSCPRKVfsdUcVxs=
golang.org/x/tools v0.0.0-20190110015856-aa033095749b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -2,8 +2,11 @@ package ginSwagger
import (
"html/template"
"net/http"
"os"
"path/filepath"
"regexp"
"sync"
"golang.org/x/net/webdav"
@@ -11,70 +14,219 @@ import (
"github.com/swaggo/swag"
)
// WrapHandler wraps `http.Handler` into `gin.HandlerFunc`.
func WrapHandler(h *webdav.Handler) gin.HandlerFunc {
//create a template with name
t := template.New("swagger_index.html")
index, _ := t.Parse(swagger_index_templ)
type swaggerConfig struct {
URL string
DocExpansion string
Title string
Oauth2RedirectURL template.JS
DefaultModelsExpandDepth int
DeepLinking bool
PersistAuthorization bool
Oauth2DefaultClientID string
}
type pro struct {
Host string
// Config stores ginSwagger configuration variables.
type Config struct {
// The url pointing to API definition (normally swagger.json or swagger.yaml). Default is `doc.json`.
URL string
DocExpansion string
InstanceName string
Title string
DefaultModelsExpandDepth int
DeepLinking bool
PersistAuthorization bool
Oauth2DefaultClientID string
}
func (config Config) toSwaggerConfig() swaggerConfig {
return swaggerConfig{
URL: config.URL,
DeepLinking: config.DeepLinking,
DocExpansion: config.DocExpansion,
DefaultModelsExpandDepth: config.DefaultModelsExpandDepth,
Oauth2RedirectURL: "`${window.location.protocol}//${window.location.host}$" +
"{window.location.pathname.split('/').slice(0, window.location.pathname.split('/').length - 1).join('/')}" +
"/oauth2-redirect.html`",
Title: config.Title,
PersistAuthorization: config.PersistAuthorization,
Oauth2DefaultClientID: config.Oauth2DefaultClientID,
}
}
// URL presents the url pointing to API definition (normally swagger.json or swagger.yaml).
func URL(url string) func(*Config) {
return func(c *Config) {
c.URL = url
}
}
// DocExpansion list, full, none.
func DocExpansion(docExpansion string) func(*Config) {
return func(c *Config) {
c.DocExpansion = docExpansion
}
}
// DeepLinking set the swagger deep linking configuration.
func DeepLinking(deepLinking bool) func(*Config) {
return func(c *Config) {
c.DeepLinking = deepLinking
}
}
// DefaultModelsExpandDepth set the default expansion depth for models
// (set to -1 completely hide the models).
func DefaultModelsExpandDepth(depth int) func(*Config) {
return func(c *Config) {
c.DefaultModelsExpandDepth = depth
}
}
// InstanceName set the instance name that was used to generate the swagger documents
// Defaults to swag.Name ("swagger").
func InstanceName(name string) func(*Config) {
return func(c *Config) {
c.InstanceName = name
}
}
// PersistAuthorization Persist authorization information over browser close/refresh.
// Defaults to false.
func PersistAuthorization(persistAuthorization bool) func(*Config) {
return func(c *Config) {
c.PersistAuthorization = persistAuthorization
}
}
// Oauth2DefaultClientID set the default client ID used for OAuth2
func Oauth2DefaultClientID(oauth2DefaultClientID string) func(*Config) {
return func(c *Config) {
c.Oauth2DefaultClientID = oauth2DefaultClientID
}
}
// WrapHandler wraps `http.Handler` into `gin.HandlerFunc`.
func WrapHandler(handler *webdav.Handler, options ...func(*Config)) gin.HandlerFunc {
var config = Config{
URL: "doc.json",
DocExpansion: "list",
InstanceName: swag.Name,
Title: "Swagger UI",
DefaultModelsExpandDepth: 1,
DeepLinking: true,
PersistAuthorization: false,
Oauth2DefaultClientID: "",
}
var re = regexp.MustCompile(`(.*)(index\.html|doc\.json|favicon-16x16\.png|favicon-32x32\.png|/oauth2-redirect\.html|swagger-ui\.css|swagger-ui\.css\.map|swagger-ui\.js|swagger-ui\.js\.map|swagger-ui-bundle\.js|swagger-ui-bundle\.js\.map|swagger-ui-standalone-preset\.js|swagger-ui-standalone-preset\.js\.map)[\?|.]*`)
for _, c := range options {
c(&config)
}
return CustomWrapHandler(&config, handler)
}
// CustomWrapHandler wraps `http.Handler` into `gin.HandlerFunc`.
func CustomWrapHandler(config *Config, handler *webdav.Handler) gin.HandlerFunc {
var once sync.Once
if config.InstanceName == "" {
config.InstanceName = swag.Name
}
if config.Title == "" {
config.Title = "Swagger UI"
}
// create a template with name
index, _ := template.New("swagger_index.html").Parse(swaggerIndexTpl)
var matcher = regexp.MustCompile(`(.*)(index\.html|doc\.json|favicon-16x16\.png|favicon-32x32\.png|/oauth2-redirect\.html|swagger-ui\.css|swagger-ui\.css\.map|swagger-ui\.js|swagger-ui\.js\.map|swagger-ui-bundle\.js|swagger-ui-bundle\.js\.map|swagger-ui-standalone-preset\.js|swagger-ui-standalone-preset\.js\.map)[?|.]*`)
return func(ctx *gin.Context) {
if ctx.Request.Method != http.MethodGet {
ctx.AbortWithStatus(http.StatusMethodNotAllowed)
return func(c *gin.Context) {
var matches []string
if matches = re.FindStringSubmatch(c.Request.RequestURI); len(matches) != 3 {
c.Status(404)
c.Writer.Write([]byte("404 page not found"))
return
}
matches := matcher.FindStringSubmatch(ctx.Request.RequestURI)
if len(matches) != 3 {
ctx.String(http.StatusNotFound, http.StatusText(http.StatusNotFound))
return
}
path := matches[2]
prefix := matches[1]
h.Prefix = prefix
once.Do(func() {
handler.Prefix = matches[1]
})
switch filepath.Ext(path) {
case ".html":
ctx.Header("Content-Type", "text/html; charset=utf-8")
case ".css":
ctx.Header("Content-Type", "text/css; charset=utf-8")
case ".js":
ctx.Header("Content-Type", "application/javascript")
case ".png":
ctx.Header("Content-Type", "image/png")
case ".json":
ctx.Header("Content-Type", "application/json; charset=utf-8")
}
switch path {
case "index.html":
s := &pro{
Host: "doc.json", //TODO: provide to customs?
}
index.Execute(c.Writer, s)
_ = index.Execute(ctx.Writer, config.toSwaggerConfig())
case "doc.json":
doc, err := swag.ReadDoc()
doc, err := swag.ReadDoc(config.InstanceName)
if err != nil {
panic(err)
}
c.Writer.Write([]byte(doc))
return
default:
h.ServeHTTP(c.Writer, c.Request)
ctx.AbortWithStatus(http.StatusInternalServerError)
return
}
ctx.String(http.StatusOK, doc)
default:
handler.ServeHTTP(ctx.Writer, ctx.Request)
}
}
}
// DisablingWrapHandler turn handler off
// if specified environment variable passed
func DisablingWrapHandler(h *webdav.Handler, envName string) gin.HandlerFunc {
eFlag := os.Getenv(envName)
if eFlag != "" {
// if specified environment variable passed.
func DisablingWrapHandler(handler *webdav.Handler, envName string) gin.HandlerFunc {
if os.Getenv(envName) != "" {
return func(c *gin.Context) {
// Simulate behavior when route unspecified and
// return 404 HTTP code
c.String(404, "")
c.String(http.StatusNotFound, "")
}
}
return WrapHandler(h)
return WrapHandler(handler)
}
const swagger_index_templ = `<!-- HTML for static distribution bundle build -->
// DisablingCustomWrapHandler turn handler off
// if specified environment variable passed.
func DisablingCustomWrapHandler(config *Config, handler *webdav.Handler, envName string) gin.HandlerFunc {
if os.Getenv(envName) != "" {
return func(c *gin.Context) {
// Simulate behavior when route unspecified and
// return 404 HTTP code
c.String(http.StatusNotFound, "")
}
}
return CustomWrapHandler(config, handler)
}
const swaggerIndexTpl = `<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<title>{{.Title}}</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
@@ -144,9 +296,11 @@ const swagger_index_templ = `<!-- HTML for static distribution bundle build -->
window.onload = function() {
// Build a system
const ui = SwaggerUIBundle({
url: "{{.Host}}",
url: "{{.URL}}",
dom_id: '#swagger-ui',
validatorUrl: null,
oauth2RedirectUrl: {{.Oauth2RedirectURL}},
persistAuthorization: {{.PersistAuthorization}},
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
@@ -154,9 +308,19 @@ window.onload = function() {
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
layout: "StandaloneLayout",
docExpansion: "{{.DocExpansion}}",
deepLinking: {{.DeepLinking}},
defaultModelsExpandDepth: {{.DefaultModelsExpandDepth}}
})
const defaultClientId = "{{.Oauth2DefaultClientID}}";
if (defaultClientId) {
ui.initOAuth({
clientId: defaultClientId
})
}
window.ui = ui
}
</script>

View File

@@ -1,131 +0,0 @@
// Code generated by fileb0x at "2017-11-26 17:57:18.000591466 +0600 +06 m=+3.756909921" from config file "b0x.yml" DO NOT EDIT.
package swaggerFiles
import (
"bytes"
"io"
"log"
"net/http"
"os"
"path"
"golang.org/x/net/context"
"golang.org/x/net/webdav"
)
var (
// CTX is a context for webdav vfs
CTX = context.Background()
// FS is a virtual memory file system
FS = webdav.NewMemFS()
// Handler is used to server files through a http handler
Handler *webdav.Handler
// HTTP is the http file system
HTTP http.FileSystem = new(HTTPFS)
)
// HTTPFS implements http.FileSystem
type HTTPFS struct{}
func init() {
if CTX.Err() != nil {
log.Fatal(CTX.Err())
}
//var err error
Handler = &webdav.Handler{
FileSystem: FS,
LockSystem: webdav.NewMemLS(),
}
}
// Open a file
func (hfs *HTTPFS) Open(path string) (http.File, error) {
f, err := FS.OpenFile(CTX, path, os.O_RDONLY, 0644)
if err != nil {
return nil, err
}
return f, nil
}
// ReadFile is adapTed from ioutil
func ReadFile(path string) ([]byte, error) {
f, err := FS.OpenFile(CTX, path, os.O_RDONLY, 0644)
if err != nil {
return nil, err
}
buf := bytes.NewBuffer(make([]byte, 0, bytes.MinRead))
// If the buffer overflows, we will get bytes.ErrTooLarge.
// Return that as an error. Any other panic remains.
defer func() {
e := recover()
if e == nil {
return
}
if panicErr, ok := e.(error); ok && panicErr == bytes.ErrTooLarge {
err = panicErr
} else {
panic(e)
}
}()
_, err = buf.ReadFrom(f)
return buf.Bytes(), err
}
// WriteFile is adapTed from ioutil
func WriteFile(filename string, data []byte, perm os.FileMode) error {
f, err := FS.OpenFile(CTX, filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
if err != nil {
return err
}
n, err := f.Write(data)
if err == nil && n < len(data) {
err = io.ErrShortWrite
}
if err1 := f.Close(); err == nil {
err = err1
}
return err
}
// WalkDirs looks for files in the given dir and returns a list of files in it
// usage for all files in the b0x: WalkDirs("", false)
func WalkDirs(name string, includeDirsInList bool, files ...string) ([]string, error) {
f, err := FS.OpenFile(CTX, name, os.O_RDONLY, 0)
if err != nil {
return nil, err
}
fileInfos, err := f.Readdir(0)
f.Close()
if err != nil {
return nil, err
}
for _, info := range fileInfos {
filename := path.Join(name, info.Name())
if includeDirsInList || !info.IsDir() {
files = append(files, filename)
}
if info.IsDir() {
files, err = WalkDirs(filename, includeDirsInList, files...)
if err != nil {
return nil, err
}
}
}
return files, nil
}

View File

@@ -1,29 +0,0 @@
// Code generaTed by fileb0x at "2017-11-26 17:57:23.142282087 +0600 +06 m=+8.898600553" from config file "b0x.yml" DO NOT EDIT.
package swaggerFiles
import (
"log"
"os"
)
// FileFavicon16x16Png is "/favicon-16x16.png"
var FileFavicon16x16Png = []byte("\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\x00\x00\x01\x84\x49\x44\x41\x54\x78\x01\x95\x53\x03\x4c\x75\x71\x1c\xfd\x8c\xf1\xc3\xec\x30\xa7\x29\xcd\x61\xb6\x6b\x36\xb2\x9b\xf9\xb2\x6b\xc8\x35\x2f\xdb\x8d\x71\x78\xc6\x94\x6d\xcc\x7b\xef\x7f\x4f\xff\xf3\x6c\xdc\xed\xf2\xe0\xfe\xf8\xc9\xff\x50\x14\x11\x2f\x14\x5b\xa3\x50\xc4\xa1\xbc\x3f\xf1\x74\x3e\x37\x12\x73\x13\x03\x85\xca\x37\x49\x52\x09\x61\xb5\x6a\x8f\xa7\x31\xbe\x5d\x88\xf6\xb9\x4c\xf0\x1c\x93\xcf\xda\xe3\x29\x10\x93\x66\x8d\xe4\x06\x13\xcf\xde\x3c\x9b\xd1\x34\x95\x8a\x92\x81\x4f\x41\xcf\x46\x89\xdd\x3c\x9b\x20\x4d\xe6\x7d\x4c\xe4\x07\x15\xc5\xf5\xe3\xff\x49\x0c\x7b\xd6\x8d\xff\x73\x99\x34\xba\x73\x66\x68\xae\x3f\xaf\x6b\x1a\x70\x72\x77\x10\x20\x3c\xb9\xdb\xc7\x86\xa6\xd1\x19\x49\x0a\xa8\xb1\xd7\x84\x79\x33\x67\x17\x31\x54\x24\xb5\x63\x7f\x71\xfb\x62\x71\xbf\x6b\x8e\x27\x1d\x51\xb0\xc2\x2c\x92\x0b\x78\x7c\x3b\x46\xe5\xf0\xef\x00\x83\xf2\xa1\x1f\x78\x7c\x3f\x71\xbd\xcb\xc2\x16\x80\x5a\x46\xf0\xc4\x4a\xf3\xe3\xe4\x6e\x31\xcc\x17\x6b\x60\x3a\x7d\xcb\x79\xe8\x98\xcb\x42\xc7\x7c\x36\x7a\x97\x72\xd1\x34\x9d\x06\xd3\xf9\x8a\xe4\x94\x90\x8b\xb6\xd9\x0c\x50\xeb\x63\x40\xd0\x7c\xbe\x2a\xc9\x34\xc8\xa7\x98\x27\xcd\x68\x00\xe3\xd9\x32\xa6\x76\x4b\x7d\x0c\x42\xa4\xf0\x2b\x44\x0a\xc7\x81\x29\xb0\x10\x9a\xe3\xa9\xd8\x8b\x78\xe4\x28\xa2\xbb\x8d\x6c\x0d\x01\xb6\x8a\x2d\xf3\x37\x38\xbe\xdd\xc7\xa6\xb6\xc9\xd9\xc6\x64\xd8\x5c\x6d\xf4\x0c\x92\x09\x75\x51\x0e\xd2\xf5\xb3\xd1\xf1\x77\xdf\x51\x16\xb3\x34\x61\x24\xa1\xc4\xc4\x28\x56\xbc\x46\xd9\xdf\xa4\x91\xe9\xb0\x26\x2c\x12\x2b\xcd\x93\xcf\x1c\x1c\x62\xdc\xca\x00\x71\x74\xeb\xcc\x2d\x14\x89\xfe\xfc\x0f\x6d\x32\x6a\x88\xec\xcc\x73\x18\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82")
func init() {
f, err := FS.OpenFile(CTX, "/favicon-16x16.png", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0777)
if err != nil {
log.Fatal(err)
}
_, err = f.Write(FileFavicon16x16Png)
if err != nil {
log.Fatal(err)
}
err = f.Close()
if err != nil {
log.Fatal(err)
}
}

View File

@@ -1,29 +0,0 @@
// Code generaTed by fileb0x at "2017-11-26 17:57:18.759175324 +0600 +06 m=+4.515493805" from config file "b0x.yml" DO NOT EDIT.
package swaggerFiles
import (
"log"
"os"
)
// FileFavicon32x32Png is "/favicon-32x32.png"
var FileFavicon32x32Png = []byte("\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\x00\x00\x04\x3c\x49\x44\x41\x54\x78\x01\xbd\x57\x03\xcc\x65\x59\x0c\x7e\x6b\xdb\xb6\x6d\xc4\x5e\xc7\x5e\xdb\xb6\x3d\x46\xf0\xdb\xb6\x6d\xdb\xb6\x6d\xf3\xa2\xd3\x6f\xf2\xce\x33\x7f\x35\x69\xee\x61\xdb\x5b\x1f\x8d\xa3\xa0\xaa\xea\xa9\xb2\xb2\xf9\xa4\xac\x48\x3f\xf2\x37\x42\x92\xd7\xab\x78\x3c\x02\x94\xe4\x8d\x1a\xfe\x46\x61\x0f\x67\x70\x56\xb3\x53\xa0\xa8\xf2\x85\x4c\xf8\x7b\x45\x91\xfa\x88\x54\x72\x04\x70\x96\x05\xf9\x91\xef\x5e\x6c\x8f\xbe\x9d\x3f\x96\xde\x66\x22\x53\x82\x30\xaf\xd1\xf0\x74\x03\x95\xb4\x7a\x52\x62\xe5\xcf\x14\x5e\xf4\x21\x90\xc7\x3f\x51\x71\xab\x07\xef\xd5\x13\xce\x08\xc0\x5d\xa6\xf1\x2e\x68\x39\xc9\x5c\xb9\x98\xff\x20\x4e\x10\x5b\xdf\x5c\xa6\xbc\xa6\xe3\xf4\x6f\xc4\xdd\xf4\x99\xa7\xc6\x26\xfe\x13\x71\x17\xe5\x36\x1e\xe3\x3b\x4b\x3a\xa1\x59\x88\x04\xd0\x74\x94\xf9\xd5\x7c\xa1\x41\x5c\xae\xea\x0a\xa1\x5f\x82\xaf\x01\x71\xa7\xf0\x97\xa0\xab\xa9\xb2\x33\x08\x34\x84\x59\x9a\x98\xf6\xb5\x76\xff\x5c\x30\x67\xc7\xa2\x90\xfc\xb7\x41\x6c\x5b\x18\x9c\xff\x26\xb1\xc3\x1a\x08\xa1\x5e\x6c\xcb\xe6\x71\x82\xb9\x47\xc6\x2b\x20\xb0\x23\xe8\x9e\xf6\xa2\xa1\x10\x09\x16\x7d\x02\x0e\x07\x75\x01\x43\xf2\xdf\xc2\xc5\x1d\xc5\xa0\xbc\x37\x48\xd0\x87\x63\x9a\xaa\xfe\x42\xf6\xd8\x09\x62\xa8\xea\x0a\x36\xba\xf8\xb5\xcf\x39\x54\xd1\x11\x40\xab\xeb\x73\x34\x34\x55\x6b\x97\xd1\xe0\x54\x0d\xad\x6e\xcc\xc3\xfe\xf4\xb5\xef\xb9\x46\x7b\x15\x9d\x01\xba\xe8\x30\x0a\x51\xc4\xb9\xf0\x76\x53\x87\x8b\x2e\xfd\x82\x00\xe3\x73\x6d\x94\xdd\x70\xc8\xae\x00\xd9\xf5\x07\x69\x6c\xb6\x85\x00\xb1\x65\x5f\x1b\xed\xfd\x1c\x74\x95\x2e\x3a\x90\xb4\x74\xb6\x67\xbb\xf4\x60\x31\x8f\xc3\xc7\x94\x20\xa2\x00\xb0\x3f\xfa\x21\x87\xd5\xfd\x5f\xd4\x7d\x04\xa8\xed\x89\x30\xdb\xcb\x69\x38\xa2\xf5\x05\xb9\xef\xa4\x2f\x20\x75\x8a\x90\x43\x0c\x9b\x5e\x68\x19\x4c\x21\xc0\xef\xa1\x37\x39\x2c\x00\xb4\x08\x68\x1d\x4c\x33\xdb\xfb\x3b\xfc\x0e\x5d\x68\x32\xef\xa7\x35\x50\x05\x26\xc8\x62\x38\x60\x2e\x40\x1a\x01\x7e\x0b\xb9\xde\x61\x01\x7e\x0c\xbc\x1c\x4c\xa8\x75\x28\xdd\xd2\x3e\x7c\x49\x44\xc4\xcf\xd0\x40\x04\x26\x25\xad\x1e\x16\x0f\xf7\x8d\x97\x41\x52\xfa\xca\xe7\x6c\x87\x05\xf8\xd2\xfb\x0c\x84\x1d\x0d\x4c\x56\x59\xdc\x2f\x6a\x75\x13\x1a\x88\xd2\xa0\xaa\x61\x82\x7c\x6e\x7a\x70\x5f\xf4\x03\xc8\x09\xd4\x3b\x5e\x8a\x39\x7d\xee\x75\x9a\x91\x20\x60\x04\x14\x73\xec\xe1\x0c\xc6\x5d\xa3\x05\x60\x60\xd1\x77\x12\x2a\x7e\x20\x00\xf3\xae\xd3\xa0\x9c\x62\x82\xa2\x62\x78\x28\xb3\x6e\x1f\x71\x78\xd2\xf2\xda\x34\x1d\x8a\x7d\x1c\x6b\xd4\x3e\x9c\x49\x2b\xeb\xb3\xf4\x6b\xc8\x75\x60\x4c\x93\xf3\x5d\x34\xb5\xd0\xc3\xe3\x33\xd9\xee\xd7\xf2\xd9\x19\xea\x18\xc9\xc1\x59\x3a\x18\xfb\x28\x2d\xad\x4e\x82\x06\x65\xd5\x1f\x30\xa2\x1d\x56\xf8\xbe\x30\xc1\x98\x35\x01\xf8\xd2\x7e\x5c\xa6\xa5\xb5\x29\x26\xf6\x98\x56\x80\x6c\xe4\x03\xf8\x03\x04\x00\x73\x9a\x5e\xec\x85\x00\xf4\x2b\x0b\x00\xe1\x3a\x47\xf2\x70\x96\x0e\xc4\x3c\x42\x8b\xab\x13\xa0\x81\xd0\xb4\x2e\x00\xab\xd8\xaa\x09\xf6\xc7\x3c\xac\x35\x41\x09\xe6\xf4\x05\xab\xf7\x6b\x23\x13\x9c\x09\x34\x32\xc1\x17\x3a\x13\xe4\xc3\x04\x10\xde\xae\x09\x22\x30\x29\xb6\xe6\x84\x13\xc2\x09\xcf\x72\xda\x09\xfb\x27\x2b\x2d\x3b\x61\x8b\x70\x42\x29\x66\x77\xc2\x30\xc0\x66\x18\x22\x5d\x0b\x01\x10\x86\x92\x41\x22\xba\x73\x0f\x12\xd1\xed\x06\x89\x48\x7a\x5a\x9b\x8a\xe5\x3e\x2c\xe4\x36\x1e\x35\xbb\x50\xdd\x15\x4a\x80\x7d\xce\xa4\xe2\xc8\x7b\x6d\xa4\xe2\xc3\xc2\x01\x07\xc0\xdb\xa4\x18\x2d\xa1\x93\x31\xba\x10\x53\xfa\x25\xb6\x50\x60\x10\x19\x76\x99\x23\x7c\x47\x67\x9b\x09\x10\x57\xf6\x8d\x49\x31\xba\x92\xd6\x36\x17\x45\x12\xfa\xd9\xa8\xf3\x55\x54\x65\x0a\x1b\x95\x9d\x81\x66\xe5\x18\xa5\x75\x6d\x63\x81\x86\xa6\xeb\xec\x09\x80\x34\xcb\x67\x17\xa1\x39\xfa\xc6\xf7\x3c\xa3\xbd\xf2\x0e\x7f\x02\x80\x97\x59\xc7\xac\x18\x34\x24\x68\xa3\x76\xba\x21\x09\xcc\x7b\xcd\xb4\x21\xb1\xd8\x92\x25\x68\xe3\x93\xdc\xd3\x5f\xda\x31\xe6\xae\x69\xcf\x83\xa6\x70\xbc\x24\xf0\xb2\xda\x94\xa2\x71\x14\x42\x40\x13\xdb\xff\xf3\xd7\x0d\xfa\x41\xb9\xc5\x6e\x7b\x8e\xd6\x59\x08\x01\x75\xc1\x27\x7e\x16\x8e\xe9\x04\xa2\xfb\x41\x2b\xc7\x34\x0c\x98\xab\xd7\x3a\xfc\x30\xd1\x76\xaf\x24\xa2\x23\xb7\xf1\x08\xfd\x6d\x21\x4f\x58\x68\x38\x10\x6a\x7c\x67\xd1\xe0\x61\xb2\x99\x04\x9a\x5b\x79\x9a\xbd\x6b\xf2\x34\x43\x24\xa0\x9e\x23\x9f\xa3\xa8\x00\x31\xc6\x1a\x22\xc0\xe4\x69\xa6\xcc\x30\xf3\xf7\xb7\xf5\x58\x45\xb8\xe0\xa1\xc9\xc2\x0c\x90\x83\x80\x24\x83\x38\xdf\xd6\xe3\xd4\x82\x46\x4e\x47\x0f\x87\x36\x8a\xbf\x31\xa8\x64\x28\xa7\x40\x8c\x51\x58\x90\xdb\x19\x9f\xc5\x59\x47\xe9\x9e\x00\xa5\x79\x33\x5d\x9a\x4a\xe1\x22\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82")
func init() {
f, err := FS.OpenFile(CTX, "/favicon-32x32.png", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0777)
if err != nil {
log.Fatal(err)
}
_, err = f.Write(FileFavicon32x32Png)
if err != nil {
log.Fatal(err)
}
err = f.Close()
if err != nil {
log.Fatal(err)
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,29 +0,0 @@
// Code generaTed by fileb0x at "2017-11-26 17:57:18.489607614 +0600 +06 m=+4.245926076" from config file "b0x.yml" DO NOT EDIT.
package swaggerFiles
import (
"log"
"os"
)
// FileSwaggerUICSSMap is "/swagger-ui.css.map"
var FileSwaggerUICSSMap = []byte("\x7b\x22\x76\x65\x72\x73\x69\x6f\x6e\x22\x3a\x33\x2c\x22\x73\x6f\x75\x72\x63\x65\x73\x22\x3a\x5b\x5d\x2c\x22\x6e\x61\x6d\x65\x73\x22\x3a\x5b\x5d\x2c\x22\x6d\x61\x70\x70\x69\x6e\x67\x73\x22\x3a\x22\x22\x2c\x22\x66\x69\x6c\x65\x22\x3a\x22\x73\x77\x61\x67\x67\x65\x72\x2d\x75\x69\x2e\x63\x73\x73\x22\x2c\x22\x73\x6f\x75\x72\x63\x65\x52\x6f\x6f\x74\x22\x3a\x22\x22\x7d")
func init() {
f, err := FS.OpenFile(CTX, "/swagger-ui.css.map", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0777)
if err != nil {
log.Fatal(err)
}
_, err = f.Write(FileSwaggerUICSSMap)
if err != nil {
log.Fatal(err)
}
err = f.Close()
if err != nil {
log.Fatal(err)
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,34 +1,77 @@
package ginSwagger
import (
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"testing"
"github.com/gin-contrib/gzip"
"github.com/swaggo/swag"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"github.com/swaggo/gin-swagger/swaggerFiles"
_ "github.com/swaggo/gin-swagger/example/docs"
swaggerFiles "github.com/swaggo/files"
)
type mockedSwag struct{}
func (s *mockedSwag) ReadDoc() string {
return `{
}`
}
func TestWrapHandler(t *testing.T) {
gin.SetMode(gin.TestMode)
router := gin.New()
router.GET("/*any", WrapHandler(swaggerFiles.Handler))
router.GET("/*any", WrapHandler(swaggerFiles.Handler, URL("https://github.com/swaggo/gin-swagger")))
w1 := performRequest("GET", "/index.html", router)
assert.Equal(t, 200, w1.Code)
assert.Equal(t, http.StatusOK, performRequest("GET", "/index.html", router).Code)
}
w2 := performRequest("GET", "/doc.json", router)
assert.Equal(t, 200, w2.Code)
func TestWrapCustomHandler(t *testing.T) {
gin.SetMode(gin.TestMode)
router := gin.New()
w3 := performRequest("GET", "/favicon-16x16.png", router)
assert.Equal(t, 200, w3.Code)
router.Any("/*any", CustomWrapHandler(&Config{}, swaggerFiles.Handler))
w4 := performRequest("GET", "/notfound", router)
assert.Equal(t, 404, w4.Code)
w1 := performRequest(http.MethodGet, "/index.html", router)
assert.Equal(t, http.StatusOK, w1.Code)
assert.Equal(t, w1.Header()["Content-Type"][0], "text/html; charset=utf-8")
assert.Equal(t, http.StatusInternalServerError, performRequest(http.MethodGet, "/doc.json", router).Code)
doc := &mockedSwag{}
swag.Register(swag.Name, doc)
w2 := performRequest(http.MethodGet, "/doc.json", router)
assert.Equal(t, http.StatusOK, w2.Code)
assert.Equal(t, w2.Header()["Content-Type"][0], "application/json; charset=utf-8")
// Perform body rendering validation
w2Body, err := ioutil.ReadAll(w2.Body)
assert.NoError(t, err)
assert.Equal(t, doc.ReadDoc(), string(w2Body))
w3 := performRequest(http.MethodGet, "/favicon-16x16.png", router)
assert.Equal(t, http.StatusOK, w3.Code)
assert.Equal(t, w3.Header()["Content-Type"][0], "image/png")
w4 := performRequest(http.MethodGet, "/swagger-ui.css", router)
assert.Equal(t, http.StatusOK, w4.Code)
assert.Equal(t, w4.Header()["Content-Type"][0], "text/css; charset=utf-8")
w5 := performRequest(http.MethodGet, "/swagger-ui-bundle.js", router)
assert.Equal(t, http.StatusOK, w5.Code)
assert.Equal(t, w5.Header()["Content-Type"][0], "application/javascript")
assert.Equal(t, http.StatusNotFound, performRequest(http.MethodGet, "/notfound", router).Code)
assert.Equal(t, http.StatusMethodNotAllowed, performRequest(http.MethodPost, "/index.html", router).Code)
assert.Equal(t, http.StatusMethodNotAllowed, performRequest(http.MethodPut, "/index.html", router).Code)
}
func TestDisablingWrapHandler(t *testing.T) {
@@ -39,33 +82,62 @@ func TestDisablingWrapHandler(t *testing.T) {
router.GET("/simple/*any", DisablingWrapHandler(swaggerFiles.Handler, disablingKey))
w1 := performRequest("GET", "/simple/index.html", router)
assert.Equal(t, 200, w1.Code)
assert.Equal(t, http.StatusOK, performRequest(http.MethodGet, "/simple/index.html", router).Code)
assert.Equal(t, http.StatusOK, performRequest(http.MethodGet, "/simple/doc.json", router).Code)
w2 := performRequest("GET", "/simple/doc.json", router)
assert.Equal(t, 200, w2.Code)
assert.Equal(t, http.StatusOK, performRequest(http.MethodGet, "/simple/favicon-16x16.png", router).Code)
assert.Equal(t, http.StatusNotFound, performRequest(http.MethodGet, "/simple/notfound", router).Code)
w3 := performRequest("GET", "/simple/favicon-16x16.png", router)
assert.Equal(t, 200, w3.Code)
w4 := performRequest("GET", "/simple/notfound", router)
assert.Equal(t, 404, w4.Code)
os.Setenv(disablingKey, "true")
_ = os.Setenv(disablingKey, "true")
router.GET("/disabling/*any", DisablingWrapHandler(swaggerFiles.Handler, disablingKey))
w11 := performRequest("GET", "/disabling/index.html", router)
assert.Equal(t, 404, w11.Code)
assert.Equal(t, http.StatusNotFound, performRequest(http.MethodGet, "/disabling/index.html", router).Code)
assert.Equal(t, http.StatusNotFound, performRequest(http.MethodGet, "/disabling/doc.json", router).Code)
assert.Equal(t, http.StatusNotFound, performRequest(http.MethodGet, "/disabling/oauth2-redirect.html", router).Code)
assert.Equal(t, http.StatusNotFound, performRequest(http.MethodGet, "/disabling/notfound", router).Code)
}
w22 := performRequest("GET", "/disabling/doc.json", router)
assert.Equal(t, 404, w22.Code)
func TestDisablingCustomWrapHandler(t *testing.T) {
gin.SetMode(gin.TestMode)
w33 := performRequest("GET", "/disabling/favicon-16x16.png", router)
assert.Equal(t, 404, w33.Code)
router := gin.New()
disablingKey := "SWAGGER_DISABLE2"
w44 := performRequest("GET", "/disabling/notfound", router)
assert.Equal(t, 404, w44.Code)
router.GET("/simple/*any", DisablingCustomWrapHandler(&Config{}, swaggerFiles.Handler, disablingKey))
assert.Equal(t, http.StatusOK, performRequest(http.MethodGet, "/simple/index.html", router).Code)
_ = os.Setenv(disablingKey, "true")
router.GET("/disabling/*any", DisablingCustomWrapHandler(&Config{}, swaggerFiles.Handler, disablingKey))
assert.Equal(t, http.StatusNotFound, performRequest(http.MethodGet, "/disabling/index.html", router).Code)
}
func TestWithGzipMiddleware(t *testing.T) {
gin.SetMode(gin.TestMode)
router := gin.New()
router.Use(gzip.Gzip(gzip.BestSpeed))
router.GET("/*any", WrapHandler(swaggerFiles.Handler))
w1 := performRequest(http.MethodGet, "/index.html", router)
assert.Equal(t, http.StatusOK, w1.Code)
assert.Equal(t, w1.Header()["Content-Type"][0], "text/html; charset=utf-8")
w2 := performRequest(http.MethodGet, "/swagger-ui.css", router)
assert.Equal(t, http.StatusOK, w2.Code)
assert.Equal(t, w2.Header()["Content-Type"][0], "text/css; charset=utf-8")
w3 := performRequest(http.MethodGet, "/swagger-ui-bundle.js", router)
assert.Equal(t, http.StatusOK, w3.Code)
assert.Equal(t, w3.Header()["Content-Type"][0], "application/javascript")
w4 := performRequest(http.MethodGet, "/doc.json", router)
assert.Equal(t, http.StatusOK, w4.Code)
assert.Equal(t, w4.Header()["Content-Type"][0], "application/json; charset=utf-8")
}
func performRequest(method, target string, router *gin.Engine) *httptest.ResponseRecorder {
@@ -74,3 +146,103 @@ func performRequest(method, target string, router *gin.Engine) *httptest.Respons
router.ServeHTTP(w, r)
return w
}
func TestURL(t *testing.T) {
cfg := Config{}
expected := "https://github.com/swaggo/http-swagger"
configFunc := URL(expected)
configFunc(&cfg)
assert.Equal(t, expected, cfg.URL)
}
func TestDocExpansion(t *testing.T) {
var cfg Config
expected := "list"
configFunc := DocExpansion(expected)
configFunc(&cfg)
assert.Equal(t, expected, cfg.DocExpansion)
expected = "full"
configFunc = DocExpansion(expected)
configFunc(&cfg)
assert.Equal(t, expected, cfg.DocExpansion)
expected = "none"
configFunc = DocExpansion(expected)
configFunc(&cfg)
assert.Equal(t, expected, cfg.DocExpansion)
}
func TestDeepLinking(t *testing.T) {
var cfg Config
assert.Equal(t, false, cfg.DeepLinking)
configFunc := DeepLinking(true)
configFunc(&cfg)
assert.Equal(t, true, cfg.DeepLinking)
configFunc = DeepLinking(false)
configFunc(&cfg)
assert.Equal(t, false, cfg.DeepLinking)
}
func TestDefaultModelsExpandDepth(t *testing.T) {
var cfg Config
assert.Equal(t, 0, cfg.DefaultModelsExpandDepth)
expected := -1
configFunc := DefaultModelsExpandDepth(expected)
configFunc(&cfg)
assert.Equal(t, expected, cfg.DefaultModelsExpandDepth)
expected = 1
configFunc = DefaultModelsExpandDepth(expected)
configFunc(&cfg)
assert.Equal(t, expected, cfg.DefaultModelsExpandDepth)
}
func TestInstanceName(t *testing.T) {
var cfg Config
assert.Equal(t, "", cfg.InstanceName)
expected := swag.Name
configFunc := InstanceName(expected)
configFunc(&cfg)
assert.Equal(t, expected, cfg.InstanceName)
expected = "custom_name"
configFunc = InstanceName(expected)
configFunc(&cfg)
assert.Equal(t, expected, cfg.InstanceName)
}
func TestPersistAuthorization(t *testing.T) {
var cfg Config
assert.Equal(t, false, cfg.PersistAuthorization)
configFunc := PersistAuthorization(true)
configFunc(&cfg)
assert.Equal(t, true, cfg.PersistAuthorization)
configFunc = PersistAuthorization(false)
configFunc(&cfg)
assert.Equal(t, false, cfg.PersistAuthorization)
}
func TestOauth2DefaultClientID(t *testing.T) {
var cfg Config
assert.Equal(t, "", cfg.Oauth2DefaultClientID)
configFunc := Oauth2DefaultClientID("default_client_id")
configFunc(&cfg)
assert.Equal(t, "default_client_id", cfg.Oauth2DefaultClientID)
configFunc = Oauth2DefaultClientID("")
configFunc(&cfg)
assert.Equal(t, "", cfg.Oauth2DefaultClientID)
}