mirror of
https://github.com/muety/wakapi.git
synced 2023-08-10 21:12:56 +03:00
feat: add swagger docs (resolve #40)
This commit is contained in:
parent
6f30272b8c
commit
8fc39f23fa
13
README.md
13
README.md
@ -186,14 +186,13 @@ Wakapi uses [GORM](https://gorm.io) as an ORM. As a consequence, a set of differ
|
||||
See the [advanced setup instructions](docs/advanced_setup.md).
|
||||
|
||||
## 🔧 API Endpoints
|
||||
The following API endpoints are available. A more detailed Swagger documentation is about to come ([#40](https://github.com/muety/wakapi/issues/40)).
|
||||
See our [Swagger API Documentation](https://wakapi.dev/swagger-ui).
|
||||
|
||||
* `POST /api/heartbeat`
|
||||
* `GET /api/summary`
|
||||
* `string` parameter `interval`: One of `today`, `day`, `week`, `month`, `year`, `any`
|
||||
* `GET /api/compat/wakatime/v1/users/current/all_time_since_today` (see [Wakatime API docs](https://wakatime.com/developers#all_time_since_today))
|
||||
* `GET /api/compat/wakatime/v1/users/current/summaries` (see [Wakatime API docs](https://wakatime.com/developers#summaries))
|
||||
* `GET /api/health`
|
||||
### Generating Swagger docs
|
||||
```bash
|
||||
$ go get -u github.com/swaggo/swag/cmd/swag
|
||||
$ swag init -o static/docs
|
||||
```
|
||||
|
||||
## 🤝 Integrations
|
||||
### Prometheus Export
|
||||
|
12
go.mod
12
go.mod
@ -3,27 +3,29 @@ module github.com/muety/wakapi
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
|
||||
github.com/emvi/logbuch v1.1.1
|
||||
github.com/go-co-op/gocron v0.3.3
|
||||
github.com/go-openapi/spec v0.20.2 // indirect
|
||||
github.com/gorilla/handlers v1.4.2
|
||||
github.com/gorilla/mux v1.7.3
|
||||
github.com/gorilla/schema v1.1.0
|
||||
github.com/gorilla/securecookie v1.1.1
|
||||
github.com/jinzhu/configor v1.2.0
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/markbates/pkger v0.17.1
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.1
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/rubenv/sql-migrate v0.0.0-20200402132117-435005d389bc
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/swaggo/swag v1.7.0
|
||||
go.uber.org/atomic v1.6.0
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
gopkg.in/yaml.v2 v2.2.8 // indirect
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c // indirect
|
||||
golang.org/x/tools v0.1.0 // indirect
|
||||
gorm.io/driver/mysql v1.0.3
|
||||
gorm.io/driver/postgres v1.0.5
|
||||
gorm.io/driver/sqlite v1.1.3
|
||||
|
81
go.sum
81
go.sum
@ -3,11 +3,18 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
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/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
@ -42,7 +49,9 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
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.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
@ -65,6 +74,7 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
|
||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-co-op/gocron v0.3.3 h1:QnarcMZWWKrEP25uCbtDiLsnnGw+PhCjL3wNITdWJOs=
|
||||
github.com/go-co-op/gocron v0.3.3/go.mod h1:Y9PWlYqDChf2Nbgg7kfS+ZsXHDTZbMZYPEQ0MILqH+M=
|
||||
@ -74,6 +84,23 @@ github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgO
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
||||
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.4 h1:3Vw+rh13uq2JFNxgnMTGE1rnoieU9FmyE1gvnyylsYg=
|
||||
github.com/go-openapi/jsonreference v0.19.4/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
|
||||
github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM=
|
||||
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
|
||||
github.com/go-openapi/spec v0.19.14 h1:r4fbYFo6N4ZelmSX8G6p+cv/hZRXzcuqQIADGT1iNKM=
|
||||
github.com/go-openapi/spec v0.19.14/go.mod h1:gwrgJS15eCUgjLpMjBJmbZezCsw88LmgeEip0M63doA=
|
||||
github.com/go-openapi/spec v0.20.2 h1:pFPUZsiIbZ20kLUcuCGeuQWG735fPMxW7wHF9BWlnQU=
|
||||
github.com/go-openapi/spec v0.20.2/go.mod h1:RW6Xcbs6LOyWLU/mXGdzn2Qc+3aj+ASfI7rvSZh1Vls=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.11 h1:RFTu/dlFySpyVvJDfp/7674JY4SDglYWKztbiIGFpmc=
|
||||
github.com/go-openapi/swag v0.19.11/go.mod h1:Uc0gKkdR+ojzsEpjh39QChyu92vPgIr72POcgHMAgSY=
|
||||
github.com/go-openapi/swag v0.19.13 h1:233UVgMy1DlmCYYfOiFpta6e2urloh+sEs5id6lyzog=
|
||||
github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-redis/redis v6.15.5+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
@ -219,6 +246,8 @@ github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht
|
||||
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
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.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
@ -246,6 +275,12 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-b
|
||||
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/markbates/pkger v0.17.1 h1:/MKEtWqtc0mZvu9OinB9UzVN9iYCwLWuyUv4Bw+PCno=
|
||||
github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
@ -355,7 +390,9 @@ github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OK
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
github.com/rubenv/sql-migrate v0.0.0-20200402132117-435005d389bc h1:+2DdDcxVYlarHjYcZTt8dZ4Ec8cXZirzL5ko0mkKPjU=
|
||||
github.com/rubenv/sql-migrate v0.0.0-20200402132117-435005d389bc/go.mod h1:DCgfY80j8GYL7MLEfvcpSFvjD0L5yZq/aZUJmhZklyg=
|
||||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
@ -365,6 +402,7 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc h1:jUIKcSPO9MoMJBbEoyE/RJoE8vz7Mb8AjvifMMwSyvY=
|
||||
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
@ -397,12 +435,18 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/swaggo/swag v1.7.0 h1:5bCA/MTLQoIqDXXyHfOpMeDvL9j68OY/udlK4pQoo4E=
|
||||
github.com/swaggo/swag v1.7.0/go.mod h1:BdPIL73gvS9NBsdi7M1JOxLvlbfvNRaBP8m6WT6Aajo=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
|
||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||
@ -447,6 +491,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -463,7 +509,13 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -473,6 +525,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -496,10 +550,21 @@ golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@ -517,14 +582,21 @@ golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114 h1:DnSr2mCsxyCE6ZgIkmcWUQY2R5cH/6wL7eIxEmQOMSE=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20201120155355-20be4ac4bd6e h1:t96dS3DO8DGjawSLJL/HIdz8CycAd2v07XxqB3UPTi0=
|
||||
golang.org/x/tools v0.0.0-20201120155355-20be4ac4bd6e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
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-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/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=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@ -562,12 +634,17 @@ gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
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.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/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 h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
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=
|
||||
gorm.io/driver/mysql v1.0.3 h1:+JKBYPfn1tygR1/of/Fh2T8iwuVwzt+PEJmKaXzMQXg=
|
||||
gorm.io/driver/mysql v1.0.3/go.mod h1:twGxftLBlFgNVNakL7F+P/x9oYqoymG3YYT8cAfI9oI=
|
||||
gorm.io/driver/postgres v1.0.5 h1:raX6ezL/ciUmaYTvOq48jq1GE95aMC0CmxQYbxQ4Ufw=
|
||||
|
25
main.go
25
main.go
@ -56,6 +56,26 @@ var (
|
||||
|
||||
// TODO: Refactor entire project to be structured after business domains
|
||||
|
||||
// @title Wakapi API
|
||||
// @version 1.0
|
||||
// @description REST API to interact with [Wakapi](https://wakapi.dev)
|
||||
// @description
|
||||
// @description ## Authentication
|
||||
// @description Set header `Authorization` to your API Key encoded as Base64 and prefixed with `Basic`
|
||||
// @description **Example:** `Basic ODY2NDhkNzQtMTljNS00NTJiLWJhMDEtZmIzZWM3MGQ0YzJmCg==`
|
||||
|
||||
// @contact.name Ferdinand Mütsch
|
||||
// @contact.url https://github.com/muety
|
||||
// @contact.email ferdinand@muetsch.io
|
||||
|
||||
// @license.name GPL-3.0
|
||||
// @license.url https://github.com/muety/wakapi/blob/master/LICENSE
|
||||
|
||||
// @securitydefinitions.apikey ApiKeyAuth
|
||||
// @in header
|
||||
// @name Authorization
|
||||
|
||||
// @BasePath /api
|
||||
func main() {
|
||||
config = conf.Load()
|
||||
|
||||
@ -173,7 +193,10 @@ func main() {
|
||||
shieldV1BadgeHandler.RegisterRoutes(apiRouter)
|
||||
|
||||
// Static Routes
|
||||
router.PathPrefix("/assets").Handler(http.FileServer(pkger.Dir("/static")))
|
||||
fileServer := http.FileServer(pkger.Dir("/static"))
|
||||
router.PathPrefix("/assets").Handler(fileServer)
|
||||
router.PathPrefix("/swagger-ui").Handler(fileServer)
|
||||
router.PathPrefix("/docs").Handler(fileServer)
|
||||
|
||||
// Listen HTTP
|
||||
listen(router)
|
||||
|
@ -22,7 +22,7 @@ type Heartbeat struct {
|
||||
Editor string `json:"editor" hash:"ignore"` // ignored because editor might be parsed differently by wakatime
|
||||
OperatingSystem string `json:"operating_system" hash:"ignore"` // ignored because os might be parsed differently by wakatime
|
||||
Machine string `json:"machine" hash:"ignore"` // ignored because wakatime api doesn't return machines currently
|
||||
Time CustomTime `json:"time" gorm:"type:timestamp; default:CURRENT_TIMESTAMP; index:idx_time,idx_time_user"`
|
||||
Time CustomTime `json:"time" gorm:"type:timestamp; default:CURRENT_TIMESTAMP; index:idx_time,idx_time_user" swaggertype:"primitive,number"`
|
||||
Hash string `json:"-" gorm:"type:varchar(17); uniqueIndex"`
|
||||
Origin string `json:"-" hash:"ignore"`
|
||||
OriginId string `json:"-" hash:"ignore"`
|
||||
|
@ -14,48 +14,14 @@ const (
|
||||
SummaryMachine uint8 = 4
|
||||
)
|
||||
|
||||
// Support Wakapi and WakaTime range / interval identifiers
|
||||
// See https://wakatime.com/developers/#summaries
|
||||
var (
|
||||
IntervalToday = &IntervalKey{"today", "Today"}
|
||||
IntervalYesterday = &IntervalKey{"day", "yesterday", "Yesterday"}
|
||||
IntervalThisWeek = &IntervalKey{"week", "This Week"}
|
||||
IntervalLastWeek = &IntervalKey{"Last Week"}
|
||||
IntervalThisMonth = &IntervalKey{"month", "This Month"}
|
||||
IntervalLastMonth = &IntervalKey{"Last Month"}
|
||||
IntervalThisYear = &IntervalKey{"year"}
|
||||
IntervalPast7Days = &IntervalKey{"7_days", "last_7_days", "Last 7 Days"}
|
||||
IntervalPast7DaysYesterday = &IntervalKey{"Last 7 Days from Yesterday"}
|
||||
IntervalPast14Days = &IntervalKey{"Last 14 Days"}
|
||||
IntervalPast30Days = &IntervalKey{"30_days", "last_30_days", "Last 30 Days"}
|
||||
IntervalPast12Months = &IntervalKey{"12_months", "last_12_months"}
|
||||
IntervalAny = &IntervalKey{"any"}
|
||||
)
|
||||
|
||||
var AllIntervals = []*IntervalKey{
|
||||
IntervalToday,
|
||||
IntervalYesterday,
|
||||
IntervalThisWeek,
|
||||
IntervalLastWeek,
|
||||
IntervalThisMonth,
|
||||
IntervalLastMonth,
|
||||
IntervalThisYear,
|
||||
IntervalPast7Days,
|
||||
IntervalPast7DaysYesterday,
|
||||
IntervalPast14Days,
|
||||
IntervalPast30Days,
|
||||
IntervalPast12Months,
|
||||
IntervalAny,
|
||||
}
|
||||
|
||||
const UnknownSummaryKey = "unknown"
|
||||
|
||||
type Summary struct {
|
||||
ID uint `json:"-" gorm:"primary_key"`
|
||||
User *User `json:"-" gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
|
||||
UserID string `json:"user_id" gorm:"not null; index:idx_time_summary_user"`
|
||||
FromTime CustomTime `json:"from" gorm:"not null; type:timestamp; default:CURRENT_TIMESTAMP; index:idx_time_summary_user"`
|
||||
ToTime CustomTime `json:"to" gorm:"not null; type:timestamp; default:CURRENT_TIMESTAMP; index:idx_time_summary_user"`
|
||||
FromTime CustomTime `json:"from" gorm:"not null; type:timestamp; default:CURRENT_TIMESTAMP; index:idx_time_summary_user" swaggertype:"string" format:"date" example:"2006-01-02 15:04:05.000"`
|
||||
ToTime CustomTime `json:"to" gorm:"not null; type:timestamp; default:CURRENT_TIMESTAMP; index:idx_time_summary_user" swaggertype:"string" format:"date" example:"2006-01-02 15:04:05.000"`
|
||||
Projects SummaryItems `json:"projects" gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
|
||||
Languages SummaryItems `json:"languages" gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
|
||||
Editors SummaryItems `json:"editors" gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
|
||||
@ -71,7 +37,7 @@ type SummaryItem struct {
|
||||
SummaryID uint `json:"-"`
|
||||
Type uint8 `json:"-"`
|
||||
Key string `json:"key"`
|
||||
Total time.Duration `json:"total"`
|
||||
Total time.Duration `json:"total" swaggertype:"primitive,integer"`
|
||||
}
|
||||
|
||||
type SummaryItemContainer struct {
|
||||
|
@ -4,8 +4,8 @@ type User struct {
|
||||
ID string `json:"id" gorm:"primary_key"`
|
||||
ApiKey string `json:"api_key" gorm:"unique"`
|
||||
Password string `json:"-"`
|
||||
CreatedAt CustomTime `gorm:"type:timestamp; default:CURRENT_TIMESTAMP"`
|
||||
LastLoggedInAt CustomTime `gorm:"type:timestamp; default:CURRENT_TIMESTAMP"`
|
||||
CreatedAt CustomTime `gorm:"type:timestamp; default:CURRENT_TIMESTAMP" swaggertype:"string" format:"date" example:"2006-01-02 15:04:05.000"`
|
||||
LastLoggedInAt CustomTime `gorm:"type:timestamp; default:CURRENT_TIMESTAMP" swaggertype:"string" format:"date" example:"2006-01-02 15:04:05.000"`
|
||||
ShareDataMaxDays int `json:"-" gorm:"default:0"`
|
||||
ShareEditors bool `json:"-" gorm:"default:false; type:bool"`
|
||||
ShareLanguages bool `json:"-" gorm:"default:false; type:bool"`
|
||||
@ -34,7 +34,7 @@ type CredentialsReset struct {
|
||||
|
||||
type TimeByUser struct {
|
||||
User string
|
||||
Time CustomTime
|
||||
Time CustomTime `swaggertype:"string" format:"date" example:"2006-01-02 15:04:05.000"`
|
||||
}
|
||||
|
||||
func (c *CredentialsReset) IsValid() bool {
|
||||
|
@ -20,6 +20,12 @@ func (h *HealthApiHandler) RegisterRoutes(router *mux.Router) {
|
||||
r.Methods(http.MethodGet).HandlerFunc(h.Get)
|
||||
}
|
||||
|
||||
// @Summary Check the application's health status
|
||||
// @ID get-health
|
||||
// @Tags misc
|
||||
// @Produce plain
|
||||
// @Success 200 {string} string
|
||||
// @Router /health [get]
|
||||
func (h *HealthApiHandler) Get(w http.ResponseWriter, r *http.Request) {
|
||||
var dbStatus int
|
||||
if sqlDb, err := h.db.DB(); err == nil {
|
||||
|
@ -43,6 +43,14 @@ func (h *HeartbeatApiHandler) RegisterRoutes(router *mux.Router) {
|
||||
r.Methods(http.MethodPost).HandlerFunc(h.Post)
|
||||
}
|
||||
|
||||
// @Summary Push a new heartbeat
|
||||
// @ID post-heartbeat
|
||||
// @Tags heartbeat
|
||||
// @Accept json
|
||||
// @Param heartbeat body models.Heartbeat true "A heartbeat"
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 201
|
||||
// @Router /heartbeat [post]
|
||||
func (h *HeartbeatApiHandler) Post(w http.ResponseWriter, r *http.Request) {
|
||||
var heartbeats []*models.Heartbeat
|
||||
user := r.Context().Value(models.UserKey).(*models.User)
|
||||
|
@ -32,6 +32,17 @@ func (h *SummaryApiHandler) RegisterRoutes(router *mux.Router) {
|
||||
r.Methods(http.MethodGet).HandlerFunc(h.Get)
|
||||
}
|
||||
|
||||
// @Summary Retrieve a summary
|
||||
// @ID get-summary
|
||||
// @Tags summary
|
||||
// @Produce json
|
||||
// @Param interval query string false "Interval identifier" Enums(today, yesterday, week, month, year, 7_days, last_7_days, 30_days, last_30_days, 12_months, last_12_months, any)
|
||||
// @Param from query string false "Start date (e.g. '2021-02-07')"
|
||||
// @Param to query string false "End date (e.g. '2021-02-08')"
|
||||
// @Param recompute query bool false "Whether to recompute the summary from raw heartbeat or use cache"
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} models.Summary
|
||||
// @Router /summary [get]
|
||||
func (h *SummaryApiHandler) Get(w http.ResponseWriter, r *http.Request) {
|
||||
summary, err, status := su.LoadUserSummary(h.summarySrvc, r)
|
||||
if err != nil {
|
||||
|
@ -38,6 +38,16 @@ func (h *BadgeHandler) RegisterRoutes(router *mux.Router) {
|
||||
r.Methods(http.MethodGet).HandlerFunc(h.Get)
|
||||
}
|
||||
|
||||
// @Summary Get badge data
|
||||
// @Description Retrieve total time for a given entity (e.g. a project) within a given range (e.g. one week) in a format compatible with [Shields.io](https://shields.io/endpoint). Requires public data access to be allowed.
|
||||
// @ID get-badge
|
||||
// @Tags badges
|
||||
// @Produce json
|
||||
// @Param user path string true "User ID to fetch data for"
|
||||
// @Param interval path string true "Interval to aggregate data for" Enums(today, yesterday, week, month, year, 7_days, last_7_days, 30_days, last_30_days, 12_months, last_12_months, any)
|
||||
// @Param filter path string true "Filter to apply (e.g. 'project:wakapi' or 'language:Go')"
|
||||
// @Success 200 {object} v1.BadgeData
|
||||
// @Router /compat/shields/v1/{user}/{interval}/{filter} [get]
|
||||
func (h *BadgeHandler) Get(w http.ResponseWriter, r *http.Request) {
|
||||
intervalReg := regexp.MustCompile(intervalPattern)
|
||||
entityFilterReg := regexp.MustCompile(entityFilterPattern)
|
||||
|
@ -35,6 +35,15 @@ func (h *AllTimeHandler) RegisterRoutes(router *mux.Router) {
|
||||
r.Methods(http.MethodGet).HandlerFunc(h.Get)
|
||||
}
|
||||
|
||||
// @Summary Retrieve summary for all time
|
||||
// @Description Mimics https://wakatime.com/developers#all_time_since_today
|
||||
// @ID get-all-time
|
||||
// @Tags wakatime
|
||||
// @Produce json
|
||||
// @Param user path string true "User ID to fetch data for (or 'current')"
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} v1.AllTimeViewModel
|
||||
// @Router /compat/wakatime/v1/users/{user}/all_time_since_today [get]
|
||||
func (h *AllTimeHandler) Get(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
values, _ := url.ParseQuery(r.URL.RawQuery)
|
||||
|
@ -41,6 +41,18 @@ func (h *SummariesHandler) RegisterRoutes(router *mux.Router) {
|
||||
// Timezone can be specified via an offset suffix (e.g. +02:00) in date strings.
|
||||
// Requires https://github.com/muety/wakapi/issues/108.
|
||||
|
||||
// @Summary Retrieve WakaTime-compatible summaries
|
||||
// @Description Mimics https://wakatime.com/developers#summaries.
|
||||
// @ID get-wakatime-summaries
|
||||
// @Tags wakatime
|
||||
// @Produce json
|
||||
// @Param user path string true "User ID to fetch data for (or 'current')"
|
||||
// @Param range query string false "Range interval identifier" Enums(today, yesterday, week, month, year, 7_days, last_7_days, 30_days, last_30_days, 12_months, last_12_months, any)
|
||||
// @Param start query string false "Start date (e.g. '2021-02-07')"
|
||||
// @Param end query string false "End date (e.g. '2021-02-08')"
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} v1.SummariesViewModel
|
||||
// @Router /compat/wakatime/v1/users/{user}/summaries [get]
|
||||
func (h *SummariesHandler) Get(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
requestedUser := vars["user"]
|
||||
|
769
static/docs/docs.go
Normal file
769
static/docs/docs.go
Normal file
@ -0,0 +1,769 @@
|
||||
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||
// This file was generated by swaggo/swag
|
||||
|
||||
package docs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/template"
|
||||
"github.com/swaggo/swag"
|
||||
)
|
||||
|
||||
var doc = `{
|
||||
"schemes": {{ marshal .Schemes }},
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"description": "{{.Description}}",
|
||||
"title": "{{.Title}}",
|
||||
"contact": {
|
||||
"name": "Ferdinand Mütsch",
|
||||
"url": "https://github.com/muety",
|
||||
"email": "ferdinand@muetsch.io"
|
||||
},
|
||||
"license": {
|
||||
"name": "GPL-3.0",
|
||||
"url": "https://github.com/muety/wakapi/blob/master/LICENSE"
|
||||
},
|
||||
"version": "{{.Version}}"
|
||||
},
|
||||
"host": "{{.Host}}",
|
||||
"basePath": "{{.BasePath}}",
|
||||
"paths": {
|
||||
"/compat/shields/v1/{user}/{interval}/{filter}": {
|
||||
"get": {
|
||||
"description": "Retrieve total time for a given entity (e.g. a project) within a given range (e.g. one week) in a format compatible with [Shields.io](https://shields.io/endpoint). Requires public data access to be allowed.",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"badges"
|
||||
],
|
||||
"summary": "Get badge data",
|
||||
"operationId": "get-badge",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "User ID to fetch data for",
|
||||
"name": "user",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"today",
|
||||
"yesterday",
|
||||
"week",
|
||||
"month",
|
||||
"year",
|
||||
"7_days",
|
||||
"last_7_days",
|
||||
"30_days",
|
||||
"last_30_days",
|
||||
"12_months",
|
||||
"last_12_months",
|
||||
"any"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "Interval to aggregate data for",
|
||||
"name": "interval",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Filter to apply (e.g. 'project:wakapi' or 'language:Go')",
|
||||
"name": "filter",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.BadgeData"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/compat/wakatime/v1/users/{user}/all_time_since_today": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Mimics https://wakatime.com/developers#all_time_since_today",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"wakatime"
|
||||
],
|
||||
"summary": "Retrieve summary for all time",
|
||||
"operationId": "get-all-time",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "User ID to fetch data for (or 'current')",
|
||||
"name": "user",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.AllTimeViewModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/compat/wakatime/v1/users/{user}/summaries": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Mimics https://wakatime.com/developers#summaries.",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"wakatime"
|
||||
],
|
||||
"summary": "Retrieve WakaTime-compatible summaries",
|
||||
"operationId": "get-wakatime-summaries",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "User ID to fetch data for (or 'current')",
|
||||
"name": "user",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"today",
|
||||
"yesterday",
|
||||
"week",
|
||||
"month",
|
||||
"year",
|
||||
"7_days",
|
||||
"last_7_days",
|
||||
"30_days",
|
||||
"last_30_days",
|
||||
"12_months",
|
||||
"last_12_months",
|
||||
"any"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "Range interval identifier",
|
||||
"name": "range",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Start date (e.g. '2021-02-07')",
|
||||
"name": "start",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "End date (e.g. '2021-02-08')",
|
||||
"name": "end",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.SummariesViewModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/health": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"text/plain"
|
||||
],
|
||||
"tags": [
|
||||
"misc"
|
||||
],
|
||||
"summary": "Check the application's health status",
|
||||
"operationId": "get-health",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/heartbeat": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"heartbeat"
|
||||
],
|
||||
"summary": "Push a new heartbeat",
|
||||
"operationId": "post-heartbeat",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "A heartbeat",
|
||||
"name": "heartbeat",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.Heartbeat"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/summary": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"summary"
|
||||
],
|
||||
"summary": "Retrieve a summary",
|
||||
"operationId": "get-summary",
|
||||
"parameters": [
|
||||
{
|
||||
"enum": [
|
||||
"today",
|
||||
"yesterday",
|
||||
"week",
|
||||
"month",
|
||||
"year",
|
||||
"7_days",
|
||||
"last_7_days",
|
||||
"30_days",
|
||||
"last_30_days",
|
||||
"12_months",
|
||||
"last_12_months",
|
||||
"any"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "Interval identifier",
|
||||
"name": "interval",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Start date (e.g. '2021-02-07')",
|
||||
"name": "from",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "End date (e.g. '2021-02-08')",
|
||||
"name": "to",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"description": "Whether to recompute the summary from raw heartbeat or use cache",
|
||||
"name": "recompute",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.Summary"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/users/{user}/stats/{range}": {
|
||||
"get": {
|
||||
"description": "Mimics https://wakatime.com/developers#stats. Requires public data access to be allowed.",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"wakatime"
|
||||
],
|
||||
"summary": "Retrieve stats",
|
||||
"operationId": "get-stats",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "User ID to fetch data for (or 'current')",
|
||||
"name": "user",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"today",
|
||||
"yesterday",
|
||||
"week",
|
||||
"month",
|
||||
"year",
|
||||
"7_days",
|
||||
"last_7_days",
|
||||
"30_days",
|
||||
"last_30_days",
|
||||
"12_months",
|
||||
"last_12_months",
|
||||
"any"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "Range interval identifier",
|
||||
"name": "range",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.StatsViewModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"models.Heartbeat": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"branch": {
|
||||
"type": "string"
|
||||
},
|
||||
"category": {
|
||||
"type": "string"
|
||||
},
|
||||
"editor": {
|
||||
"description": "ignored because editor might be parsed differently by wakatime",
|
||||
"type": "string"
|
||||
},
|
||||
"entity": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"is_write": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"language": {
|
||||
"type": "string"
|
||||
},
|
||||
"machine": {
|
||||
"description": "ignored because wakatime api doesn't return machines currently",
|
||||
"type": "string"
|
||||
},
|
||||
"operating_system": {
|
||||
"description": "ignored because os might be parsed differently by wakatime",
|
||||
"type": "string"
|
||||
},
|
||||
"project": {
|
||||
"type": "string"
|
||||
},
|
||||
"time": {
|
||||
"type": "number"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.Summary": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"editors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.SummaryItem"
|
||||
}
|
||||
},
|
||||
"from": {
|
||||
"type": "string",
|
||||
"format": "date",
|
||||
"example": "2006-01-02 15:04:05.000"
|
||||
},
|
||||
"languages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.SummaryItem"
|
||||
}
|
||||
},
|
||||
"machines": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.SummaryItem"
|
||||
}
|
||||
},
|
||||
"operating_systems": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.SummaryItem"
|
||||
}
|
||||
},
|
||||
"projects": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.SummaryItem"
|
||||
}
|
||||
},
|
||||
"to": {
|
||||
"type": "string",
|
||||
"format": "date",
|
||||
"example": "2006-01-02 15:04:05.000"
|
||||
},
|
||||
"user_id": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.SummaryItem": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"total": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.AllTimeData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"is_up_to_date": {
|
||||
"description": "true if the stats are up to date; when false, a 202 response code is returned and stats will be refreshed soon\u003e",
|
||||
"type": "boolean"
|
||||
},
|
||||
"text": {
|
||||
"description": "total time logged since account created as human readable string\u003e",
|
||||
"type": "string"
|
||||
},
|
||||
"total_seconds": {
|
||||
"description": "total number of seconds logged since account created",
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.AllTimeViewModel": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/v1.AllTimeData"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.BadgeData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"color": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"schemaVersion": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.StatsData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"daily_average": {
|
||||
"type": "number"
|
||||
},
|
||||
"days_including_holidays": {
|
||||
"type": "integer"
|
||||
},
|
||||
"editors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"end": {
|
||||
"type": "string"
|
||||
},
|
||||
"languages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"machines": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"operating_systems": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"projects": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"start": {
|
||||
"type": "string"
|
||||
},
|
||||
"total_seconds": {
|
||||
"type": "number"
|
||||
},
|
||||
"user_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.StatsViewModel": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/v1.StatsData"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.SummariesData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"categories": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"editors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"grand_total": {
|
||||
"$ref": "#/definitions/v1.SummariesGrandTotal"
|
||||
},
|
||||
"languages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"machines": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"operating_systems": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"projects": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"range": {
|
||||
"$ref": "#/definitions/v1.SummariesRange"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.SummariesEntry": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"digital": {
|
||||
"type": "string"
|
||||
},
|
||||
"hours": {
|
||||
"type": "integer"
|
||||
},
|
||||
"minutes": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"percent": {
|
||||
"type": "number"
|
||||
},
|
||||
"seconds": {
|
||||
"type": "integer"
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"total_seconds": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.SummariesGrandTotal": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"digital": {
|
||||
"type": "string"
|
||||
},
|
||||
"hours": {
|
||||
"type": "integer"
|
||||
},
|
||||
"minutes": {
|
||||
"type": "integer"
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"total_seconds": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.SummariesRange": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"date": {
|
||||
"type": "string"
|
||||
},
|
||||
"end": {
|
||||
"type": "string"
|
||||
},
|
||||
"start": {
|
||||
"type": "string"
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"timezone": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.SummariesViewModel": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesData"
|
||||
}
|
||||
},
|
||||
"end": {
|
||||
"type": "string"
|
||||
},
|
||||
"start": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"securityDefinitions": {
|
||||
"ApiKeyAuth": {
|
||||
"type": "apiKey",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
type swaggerInfo struct {
|
||||
Version string
|
||||
Host string
|
||||
BasePath string
|
||||
Schemes []string
|
||||
Title string
|
||||
Description string
|
||||
}
|
||||
|
||||
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||
var SwaggerInfo = swaggerInfo{
|
||||
Version: "1.0",
|
||||
Host: "",
|
||||
BasePath: "/api",
|
||||
Schemes: []string{},
|
||||
Title: "Wakapi API",
|
||||
Description: "REST API to interact with [Wakapi](https://wakapi.dev)\n\n## Authentication\nSet header `Authorization` to your API Key encoded as Base64 and prefixed with `Basic`\n**Example:** `Basic ODY2NDhkNzQtMTljNS00NTJiLWJhMDEtZmIzZWM3MGQ0YzJmCg==`",
|
||||
}
|
||||
|
||||
type s struct{}
|
||||
|
||||
func (s *s) ReadDoc() string {
|
||||
sInfo := SwaggerInfo
|
||||
sInfo.Description = strings.Replace(sInfo.Description, "\n", "\\n", -1)
|
||||
|
||||
t, err := template.New("swagger_info").Funcs(template.FuncMap{
|
||||
"marshal": func(v interface{}) string {
|
||||
a, _ := json.Marshal(v)
|
||||
return string(a)
|
||||
},
|
||||
}).Parse(doc)
|
||||
if err != nil {
|
||||
return doc
|
||||
}
|
||||
|
||||
var tpl bytes.Buffer
|
||||
if err := t.Execute(&tpl, sInfo); err != nil {
|
||||
return doc
|
||||
}
|
||||
|
||||
return tpl.String()
|
||||
}
|
||||
|
||||
func init() {
|
||||
swag.Register(swag.Name, &s{})
|
||||
}
|
706
static/docs/swagger.json
Normal file
706
static/docs/swagger.json
Normal file
@ -0,0 +1,706 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"description": "REST API to interact with [Wakapi](https://wakapi.dev)\n\n## Authentication\nSet header `Authorization` to your API Key encoded as Base64 and prefixed with `Basic`\n**Example:** `Basic ODY2NDhkNzQtMTljNS00NTJiLWJhMDEtZmIzZWM3MGQ0YzJmCg==`",
|
||||
"title": "Wakapi API",
|
||||
"contact": {
|
||||
"name": "Ferdinand Mütsch",
|
||||
"url": "https://github.com/muety",
|
||||
"email": "ferdinand@muetsch.io"
|
||||
},
|
||||
"license": {
|
||||
"name": "GPL-3.0",
|
||||
"url": "https://github.com/muety/wakapi/blob/master/LICENSE"
|
||||
},
|
||||
"version": "1.0"
|
||||
},
|
||||
"basePath": "/api",
|
||||
"paths": {
|
||||
"/compat/shields/v1/{user}/{interval}/{filter}": {
|
||||
"get": {
|
||||
"description": "Retrieve total time for a given entity (e.g. a project) within a given range (e.g. one week) in a format compatible with [Shields.io](https://shields.io/endpoint). Requires public data access to be allowed.",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"badges"
|
||||
],
|
||||
"summary": "Get badge data",
|
||||
"operationId": "get-badge",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "User ID to fetch data for",
|
||||
"name": "user",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"today",
|
||||
"yesterday",
|
||||
"week",
|
||||
"month",
|
||||
"year",
|
||||
"7_days",
|
||||
"last_7_days",
|
||||
"30_days",
|
||||
"last_30_days",
|
||||
"12_months",
|
||||
"last_12_months",
|
||||
"any"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "Interval to aggregate data for",
|
||||
"name": "interval",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Filter to apply (e.g. 'project:wakapi' or 'language:Go')",
|
||||
"name": "filter",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.BadgeData"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/compat/wakatime/v1/users/{user}/all_time_since_today": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Mimics https://wakatime.com/developers#all_time_since_today",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"wakatime"
|
||||
],
|
||||
"summary": "Retrieve summary for all time",
|
||||
"operationId": "get-all-time",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "User ID to fetch data for (or 'current')",
|
||||
"name": "user",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.AllTimeViewModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/compat/wakatime/v1/users/{user}/summaries": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Mimics https://wakatime.com/developers#summaries.",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"wakatime"
|
||||
],
|
||||
"summary": "Retrieve WakaTime-compatible summaries",
|
||||
"operationId": "get-wakatime-summaries",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "User ID to fetch data for (or 'current')",
|
||||
"name": "user",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"today",
|
||||
"yesterday",
|
||||
"week",
|
||||
"month",
|
||||
"year",
|
||||
"7_days",
|
||||
"last_7_days",
|
||||
"30_days",
|
||||
"last_30_days",
|
||||
"12_months",
|
||||
"last_12_months",
|
||||
"any"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "Range interval identifier",
|
||||
"name": "range",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Start date (e.g. '2021-02-07')",
|
||||
"name": "start",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "End date (e.g. '2021-02-08')",
|
||||
"name": "end",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.SummariesViewModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/health": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"text/plain"
|
||||
],
|
||||
"tags": [
|
||||
"misc"
|
||||
],
|
||||
"summary": "Check the application's health status",
|
||||
"operationId": "get-health",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/heartbeat": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"heartbeat"
|
||||
],
|
||||
"summary": "Push a new heartbeat",
|
||||
"operationId": "post-heartbeat",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "A heartbeat",
|
||||
"name": "heartbeat",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.Heartbeat"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/summary": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"summary"
|
||||
],
|
||||
"summary": "Retrieve a summary",
|
||||
"operationId": "get-summary",
|
||||
"parameters": [
|
||||
{
|
||||
"enum": [
|
||||
"today",
|
||||
"yesterday",
|
||||
"week",
|
||||
"month",
|
||||
"year",
|
||||
"7_days",
|
||||
"last_7_days",
|
||||
"30_days",
|
||||
"last_30_days",
|
||||
"12_months",
|
||||
"last_12_months",
|
||||
"any"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "Interval identifier",
|
||||
"name": "interval",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Start date (e.g. '2021-02-07')",
|
||||
"name": "from",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "End date (e.g. '2021-02-08')",
|
||||
"name": "to",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"description": "Whether to recompute the summary from raw heartbeat or use cache",
|
||||
"name": "recompute",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.Summary"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/users/{user}/stats/{range}": {
|
||||
"get": {
|
||||
"description": "Mimics https://wakatime.com/developers#stats. Requires public data access to be allowed.",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"wakatime"
|
||||
],
|
||||
"summary": "Retrieve stats",
|
||||
"operationId": "get-stats",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "User ID to fetch data for (or 'current')",
|
||||
"name": "user",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"today",
|
||||
"yesterday",
|
||||
"week",
|
||||
"month",
|
||||
"year",
|
||||
"7_days",
|
||||
"last_7_days",
|
||||
"30_days",
|
||||
"last_30_days",
|
||||
"12_months",
|
||||
"last_12_months",
|
||||
"any"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "Range interval identifier",
|
||||
"name": "range",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.StatsViewModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"models.Heartbeat": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"branch": {
|
||||
"type": "string"
|
||||
},
|
||||
"category": {
|
||||
"type": "string"
|
||||
},
|
||||
"editor": {
|
||||
"description": "ignored because editor might be parsed differently by wakatime",
|
||||
"type": "string"
|
||||
},
|
||||
"entity": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"is_write": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"language": {
|
||||
"type": "string"
|
||||
},
|
||||
"machine": {
|
||||
"description": "ignored because wakatime api doesn't return machines currently",
|
||||
"type": "string"
|
||||
},
|
||||
"operating_system": {
|
||||
"description": "ignored because os might be parsed differently by wakatime",
|
||||
"type": "string"
|
||||
},
|
||||
"project": {
|
||||
"type": "string"
|
||||
},
|
||||
"time": {
|
||||
"type": "number"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.Summary": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"editors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.SummaryItem"
|
||||
}
|
||||
},
|
||||
"from": {
|
||||
"type": "string",
|
||||
"format": "date",
|
||||
"example": "2006-01-02 15:04:05.000"
|
||||
},
|
||||
"languages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.SummaryItem"
|
||||
}
|
||||
},
|
||||
"machines": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.SummaryItem"
|
||||
}
|
||||
},
|
||||
"operating_systems": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.SummaryItem"
|
||||
}
|
||||
},
|
||||
"projects": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.SummaryItem"
|
||||
}
|
||||
},
|
||||
"to": {
|
||||
"type": "string",
|
||||
"format": "date",
|
||||
"example": "2006-01-02 15:04:05.000"
|
||||
},
|
||||
"user_id": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.SummaryItem": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"total": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.AllTimeData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"is_up_to_date": {
|
||||
"description": "true if the stats are up to date; when false, a 202 response code is returned and stats will be refreshed soon\u003e",
|
||||
"type": "boolean"
|
||||
},
|
||||
"text": {
|
||||
"description": "total time logged since account created as human readable string\u003e",
|
||||
"type": "string"
|
||||
},
|
||||
"total_seconds": {
|
||||
"description": "total number of seconds logged since account created",
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.AllTimeViewModel": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/v1.AllTimeData"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.BadgeData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"color": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"schemaVersion": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.StatsData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"daily_average": {
|
||||
"type": "number"
|
||||
},
|
||||
"days_including_holidays": {
|
||||
"type": "integer"
|
||||
},
|
||||
"editors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"end": {
|
||||
"type": "string"
|
||||
},
|
||||
"languages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"machines": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"operating_systems": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"projects": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"start": {
|
||||
"type": "string"
|
||||
},
|
||||
"total_seconds": {
|
||||
"type": "number"
|
||||
},
|
||||
"user_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.StatsViewModel": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/v1.StatsData"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.SummariesData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"categories": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"editors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"grand_total": {
|
||||
"$ref": "#/definitions/v1.SummariesGrandTotal"
|
||||
},
|
||||
"languages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"machines": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"operating_systems": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"projects": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesEntry"
|
||||
}
|
||||
},
|
||||
"range": {
|
||||
"$ref": "#/definitions/v1.SummariesRange"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.SummariesEntry": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"digital": {
|
||||
"type": "string"
|
||||
},
|
||||
"hours": {
|
||||
"type": "integer"
|
||||
},
|
||||
"minutes": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"percent": {
|
||||
"type": "number"
|
||||
},
|
||||
"seconds": {
|
||||
"type": "integer"
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"total_seconds": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.SummariesGrandTotal": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"digital": {
|
||||
"type": "string"
|
||||
},
|
||||
"hours": {
|
||||
"type": "integer"
|
||||
},
|
||||
"minutes": {
|
||||
"type": "integer"
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"total_seconds": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.SummariesRange": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"date": {
|
||||
"type": "string"
|
||||
},
|
||||
"end": {
|
||||
"type": "string"
|
||||
},
|
||||
"start": {
|
||||
"type": "string"
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"timezone": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.SummariesViewModel": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.SummariesData"
|
||||
}
|
||||
},
|
||||
"end": {
|
||||
"type": "string"
|
||||
},
|
||||
"start": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"securityDefinitions": {
|
||||
"ApiKeyAuth": {
|
||||
"type": "apiKey",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
}
|
||||
}
|
||||
}
|
488
static/docs/swagger.yaml
Normal file
488
static/docs/swagger.yaml
Normal file
@ -0,0 +1,488 @@
|
||||
basePath: /api
|
||||
definitions:
|
||||
models.Heartbeat:
|
||||
properties:
|
||||
branch:
|
||||
type: string
|
||||
category:
|
||||
type: string
|
||||
editor:
|
||||
description: ignored because editor might be parsed differently by wakatime
|
||||
type: string
|
||||
entity:
|
||||
type: string
|
||||
id:
|
||||
type: integer
|
||||
is_write:
|
||||
type: boolean
|
||||
language:
|
||||
type: string
|
||||
machine:
|
||||
description: ignored because wakatime api doesn't return machines currently
|
||||
type: string
|
||||
operating_system:
|
||||
description: ignored because os might be parsed differently by wakatime
|
||||
type: string
|
||||
project:
|
||||
type: string
|
||||
time:
|
||||
type: number
|
||||
type:
|
||||
type: string
|
||||
type: object
|
||||
models.Summary:
|
||||
properties:
|
||||
editors:
|
||||
items:
|
||||
$ref: '#/definitions/models.SummaryItem'
|
||||
type: array
|
||||
from:
|
||||
example: "2006-01-02 15:04:05.000"
|
||||
format: date
|
||||
type: string
|
||||
languages:
|
||||
items:
|
||||
$ref: '#/definitions/models.SummaryItem'
|
||||
type: array
|
||||
machines:
|
||||
items:
|
||||
$ref: '#/definitions/models.SummaryItem'
|
||||
type: array
|
||||
operating_systems:
|
||||
items:
|
||||
$ref: '#/definitions/models.SummaryItem'
|
||||
type: array
|
||||
projects:
|
||||
items:
|
||||
$ref: '#/definitions/models.SummaryItem'
|
||||
type: array
|
||||
to:
|
||||
example: "2006-01-02 15:04:05.000"
|
||||
format: date
|
||||
type: string
|
||||
user_id:
|
||||
type: string
|
||||
type: object
|
||||
models.SummaryItem:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
total:
|
||||
type: integer
|
||||
type: object
|
||||
v1.AllTimeData:
|
||||
properties:
|
||||
is_up_to_date:
|
||||
description: true if the stats are up to date; when false, a 202 response
|
||||
code is returned and stats will be refreshed soon>
|
||||
type: boolean
|
||||
text:
|
||||
description: total time logged since account created as human readable string>
|
||||
type: string
|
||||
total_seconds:
|
||||
description: total number of seconds logged since account created
|
||||
type: number
|
||||
type: object
|
||||
v1.AllTimeViewModel:
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/definitions/v1.AllTimeData'
|
||||
type: object
|
||||
v1.BadgeData:
|
||||
properties:
|
||||
color:
|
||||
type: string
|
||||
label:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
schemaVersion:
|
||||
type: integer
|
||||
type: object
|
||||
v1.StatsData:
|
||||
properties:
|
||||
daily_average:
|
||||
type: number
|
||||
days_including_holidays:
|
||||
type: integer
|
||||
editors:
|
||||
items:
|
||||
$ref: '#/definitions/v1.SummariesEntry'
|
||||
type: array
|
||||
end:
|
||||
type: string
|
||||
languages:
|
||||
items:
|
||||
$ref: '#/definitions/v1.SummariesEntry'
|
||||
type: array
|
||||
machines:
|
||||
items:
|
||||
$ref: '#/definitions/v1.SummariesEntry'
|
||||
type: array
|
||||
operating_systems:
|
||||
items:
|
||||
$ref: '#/definitions/v1.SummariesEntry'
|
||||
type: array
|
||||
projects:
|
||||
items:
|
||||
$ref: '#/definitions/v1.SummariesEntry'
|
||||
type: array
|
||||
start:
|
||||
type: string
|
||||
total_seconds:
|
||||
type: number
|
||||
user_id:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
type: object
|
||||
v1.StatsViewModel:
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/definitions/v1.StatsData'
|
||||
type: object
|
||||
v1.SummariesData:
|
||||
properties:
|
||||
categories:
|
||||
items:
|
||||
$ref: '#/definitions/v1.SummariesEntry'
|
||||
type: array
|
||||
dependencies:
|
||||
items:
|
||||
$ref: '#/definitions/v1.SummariesEntry'
|
||||
type: array
|
||||
editors:
|
||||
items:
|
||||
$ref: '#/definitions/v1.SummariesEntry'
|
||||
type: array
|
||||
grand_total:
|
||||
$ref: '#/definitions/v1.SummariesGrandTotal'
|
||||
languages:
|
||||
items:
|
||||
$ref: '#/definitions/v1.SummariesEntry'
|
||||
type: array
|
||||
machines:
|
||||
items:
|
||||
$ref: '#/definitions/v1.SummariesEntry'
|
||||
type: array
|
||||
operating_systems:
|
||||
items:
|
||||
$ref: '#/definitions/v1.SummariesEntry'
|
||||
type: array
|
||||
projects:
|
||||
items:
|
||||
$ref: '#/definitions/v1.SummariesEntry'
|
||||
type: array
|
||||
range:
|
||||
$ref: '#/definitions/v1.SummariesRange'
|
||||
type: object
|
||||
v1.SummariesEntry:
|
||||
properties:
|
||||
digital:
|
||||
type: string
|
||||
hours:
|
||||
type: integer
|
||||
minutes:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
percent:
|
||||
type: number
|
||||
seconds:
|
||||
type: integer
|
||||
text:
|
||||
type: string
|
||||
total_seconds:
|
||||
type: number
|
||||
type: object
|
||||
v1.SummariesGrandTotal:
|
||||
properties:
|
||||
digital:
|
||||
type: string
|
||||
hours:
|
||||
type: integer
|
||||
minutes:
|
||||
type: integer
|
||||
text:
|
||||
type: string
|
||||
total_seconds:
|
||||
type: number
|
||||
type: object
|
||||
v1.SummariesRange:
|
||||
properties:
|
||||
date:
|
||||
type: string
|
||||
end:
|
||||
type: string
|
||||
start:
|
||||
type: string
|
||||
text:
|
||||
type: string
|
||||
timezone:
|
||||
type: string
|
||||
type: object
|
||||
v1.SummariesViewModel:
|
||||
properties:
|
||||
data:
|
||||
items:
|
||||
$ref: '#/definitions/v1.SummariesData'
|
||||
type: array
|
||||
end:
|
||||
type: string
|
||||
start:
|
||||
type: string
|
||||
type: object
|
||||
info:
|
||||
contact:
|
||||
email: ferdinand@muetsch.io
|
||||
name: Ferdinand Mütsch
|
||||
url: https://github.com/muety
|
||||
description: |-
|
||||
REST API to interact with [Wakapi](https://wakapi.dev)
|
||||
|
||||
## Authentication
|
||||
Set header `Authorization` to your API Key encoded as Base64 and prefixed with `Basic`
|
||||
**Example:** `Basic ODY2NDhkNzQtMTljNS00NTJiLWJhMDEtZmIzZWM3MGQ0YzJmCg==`
|
||||
license:
|
||||
name: GPL-3.0
|
||||
url: https://github.com/muety/wakapi/blob/master/LICENSE
|
||||
title: Wakapi API
|
||||
version: "1.0"
|
||||
paths:
|
||||
/compat/shields/v1/{user}/{interval}/{filter}:
|
||||
get:
|
||||
description: Retrieve total time for a given entity (e.g. a project) within
|
||||
a given range (e.g. one week) in a format compatible with [Shields.io](https://shields.io/endpoint).
|
||||
Requires public data access to be allowed.
|
||||
operationId: get-badge
|
||||
parameters:
|
||||
- description: User ID to fetch data for
|
||||
in: path
|
||||
name: user
|
||||
required: true
|
||||
type: string
|
||||
- description: Interval to aggregate data for
|
||||
enum:
|
||||
- today
|
||||
- yesterday
|
||||
- week
|
||||
- month
|
||||
- year
|
||||
- 7_days
|
||||
- last_7_days
|
||||
- 30_days
|
||||
- last_30_days
|
||||
- 12_months
|
||||
- last_12_months
|
||||
- any
|
||||
in: path
|
||||
name: interval
|
||||
required: true
|
||||
type: string
|
||||
- description: Filter to apply (e.g. 'project:wakapi' or 'language:Go')
|
||||
in: path
|
||||
name: filter
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/v1.BadgeData'
|
||||
summary: Get badge data
|
||||
tags:
|
||||
- badges
|
||||
/compat/wakatime/v1/users/{user}/all_time_since_today:
|
||||
get:
|
||||
description: Mimics https://wakatime.com/developers#all_time_since_today
|
||||
operationId: get-all-time
|
||||
parameters:
|
||||
- description: User ID to fetch data for (or 'current')
|
||||
in: path
|
||||
name: user
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/v1.AllTimeViewModel'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Retrieve summary for all time
|
||||
tags:
|
||||
- wakatime
|
||||
/compat/wakatime/v1/users/{user}/summaries:
|
||||
get:
|
||||
description: Mimics https://wakatime.com/developers#summaries.
|
||||
operationId: get-wakatime-summaries
|
||||
parameters:
|
||||
- description: User ID to fetch data for (or 'current')
|
||||
in: path
|
||||
name: user
|
||||
required: true
|
||||
type: string
|
||||
- description: Range interval identifier
|
||||
enum:
|
||||
- today
|
||||
- yesterday
|
||||
- week
|
||||
- month
|
||||
- year
|
||||
- 7_days
|
||||
- last_7_days
|
||||
- 30_days
|
||||
- last_30_days
|
||||
- 12_months
|
||||
- last_12_months
|
||||
- any
|
||||
in: query
|
||||
name: range
|
||||
type: string
|
||||
- description: Start date (e.g. '2021-02-07')
|
||||
in: query
|
||||
name: start
|
||||
type: string
|
||||
- description: End date (e.g. '2021-02-08')
|
||||
in: query
|
||||
name: end
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/v1.SummariesViewModel'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Retrieve WakaTime-compatible summaries
|
||||
tags:
|
||||
- wakatime
|
||||
/health:
|
||||
get:
|
||||
operationId: get-health
|
||||
produces:
|
||||
- text/plain
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
type: string
|
||||
summary: Check the application's health status
|
||||
tags:
|
||||
- misc
|
||||
/heartbeat:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
operationId: post-heartbeat
|
||||
parameters:
|
||||
- description: A heartbeat
|
||||
in: body
|
||||
name: heartbeat
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/models.Heartbeat'
|
||||
responses:
|
||||
"201":
|
||||
description: ""
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Push a new heartbeat
|
||||
tags:
|
||||
- heartbeat
|
||||
/summary:
|
||||
get:
|
||||
operationId: get-summary
|
||||
parameters:
|
||||
- description: Interval identifier
|
||||
enum:
|
||||
- today
|
||||
- yesterday
|
||||
- week
|
||||
- month
|
||||
- year
|
||||
- 7_days
|
||||
- last_7_days
|
||||
- 30_days
|
||||
- last_30_days
|
||||
- 12_months
|
||||
- last_12_months
|
||||
- any
|
||||
in: query
|
||||
name: interval
|
||||
type: string
|
||||
- description: Start date (e.g. '2021-02-07')
|
||||
in: query
|
||||
name: from
|
||||
type: string
|
||||
- description: End date (e.g. '2021-02-08')
|
||||
in: query
|
||||
name: to
|
||||
type: string
|
||||
- description: Whether to recompute the summary from raw heartbeat or use cache
|
||||
in: query
|
||||
name: recompute
|
||||
type: boolean
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.Summary'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Retrieve a summary
|
||||
tags:
|
||||
- summary
|
||||
/v1/users/{user}/stats/{range}:
|
||||
get:
|
||||
description: Mimics https://wakatime.com/developers#stats. Requires public data
|
||||
access to be allowed.
|
||||
operationId: get-stats
|
||||
parameters:
|
||||
- description: User ID to fetch data for (or 'current')
|
||||
in: path
|
||||
name: user
|
||||
required: true
|
||||
type: string
|
||||
- description: Range interval identifier
|
||||
enum:
|
||||
- today
|
||||
- yesterday
|
||||
- week
|
||||
- month
|
||||
- year
|
||||
- 7_days
|
||||
- last_7_days
|
||||
- 30_days
|
||||
- last_30_days
|
||||
- 12_months
|
||||
- last_12_months
|
||||
- any
|
||||
in: path
|
||||
name: range
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/v1.StatsViewModel'
|
||||
summary: Retrieve stats
|
||||
tags:
|
||||
- wakatime
|
||||
securityDefinitions:
|
||||
ApiKeyAuth:
|
||||
in: header
|
||||
name: Authorization
|
||||
type: apiKey
|
||||
swagger: "2.0"
|
BIN
static/swagger-ui/favicon-16x16.png
Normal file
BIN
static/swagger-ui/favicon-16x16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 665 B |
BIN
static/swagger-ui/favicon-32x32.png
Normal file
BIN
static/swagger-ui/favicon-32x32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 628 B |
60
static/swagger-ui/index.html
Normal file
60
static/swagger-ui/index.html
Normal file
@ -0,0 +1,60 @@
|
||||
<!-- HTML for static distribution bundle build -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Swagger UI</title>
|
||||
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
|
||||
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
|
||||
<style>
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="./swagger-ui-bundle.js" charset="UTF-8"> </script>
|
||||
<script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
// Begin Swagger UI call region
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "/docs/swagger.json",
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
// End Swagger UI call region
|
||||
|
||||
window.ui = ui
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
75
static/swagger-ui/oauth2-redirect.html
Normal file
75
static/swagger-ui/oauth2-redirect.html
Normal file
@ -0,0 +1,75 @@
|
||||
<!doctype html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<title>Swagger UI: OAuth2 Redirect</title>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
<script>
|
||||
'use strict';
|
||||
function run () {
|
||||
var oauth2 = window.opener.swaggerUIRedirectOauth2;
|
||||
var sentState = oauth2.state;
|
||||
var redirectUrl = oauth2.redirectUrl;
|
||||
var isValid, qp, arr;
|
||||
|
||||
if (/code|token|error/.test(window.location.hash)) {
|
||||
qp = window.location.hash.substring(1);
|
||||
} else {
|
||||
qp = location.search.substring(1);
|
||||
}
|
||||
|
||||
arr = qp.split("&")
|
||||
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';})
|
||||
qp = qp ? JSON.parse('{' + arr.join() + '}',
|
||||
function (key, value) {
|
||||
return key === "" ? value : decodeURIComponent(value)
|
||||
}
|
||||
) : {}
|
||||
|
||||
isValid = qp.state === sentState
|
||||
|
||||
if ((
|
||||
oauth2.auth.schema.get("flow") === "accessCode" ||
|
||||
oauth2.auth.schema.get("flow") === "authorizationCode" ||
|
||||
oauth2.auth.schema.get("flow") === "authorization_code"
|
||||
) && !oauth2.auth.code) {
|
||||
if (!isValid) {
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "warning",
|
||||
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
|
||||
});
|
||||
}
|
||||
|
||||
if (qp.code) {
|
||||
delete oauth2.state;
|
||||
oauth2.auth.code = qp.code;
|
||||
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
|
||||
} else {
|
||||
let oauthErrorMsg
|
||||
if (qp.error) {
|
||||
oauthErrorMsg = "["+qp.error+"]: " +
|
||||
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
|
||||
(qp.error_uri ? "More info: "+qp.error_uri : "");
|
||||
}
|
||||
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "error",
|
||||
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
|
||||
});
|
||||
}
|
||||
} else {
|
||||
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
|
||||
}
|
||||
window.close();
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', function () {
|
||||
run();
|
||||
});
|
||||
</script>
|
3
static/swagger-ui/swagger-ui-bundle.js
Normal file
3
static/swagger-ui/swagger-ui-bundle.js
Normal file
File diff suppressed because one or more lines are too long
1
static/swagger-ui/swagger-ui-bundle.js.map
Normal file
1
static/swagger-ui/swagger-ui-bundle.js.map
Normal file
File diff suppressed because one or more lines are too long
3
static/swagger-ui/swagger-ui-es-bundle-core.js
Normal file
3
static/swagger-ui/swagger-ui-es-bundle-core.js
Normal file
File diff suppressed because one or more lines are too long
1
static/swagger-ui/swagger-ui-es-bundle-core.js.map
Normal file
1
static/swagger-ui/swagger-ui-es-bundle-core.js.map
Normal file
File diff suppressed because one or more lines are too long
3
static/swagger-ui/swagger-ui-es-bundle.js
Normal file
3
static/swagger-ui/swagger-ui-es-bundle.js
Normal file
File diff suppressed because one or more lines are too long
1
static/swagger-ui/swagger-ui-es-bundle.js.map
Normal file
1
static/swagger-ui/swagger-ui-es-bundle.js.map
Normal file
File diff suppressed because one or more lines are too long
3
static/swagger-ui/swagger-ui-standalone-preset.js
Normal file
3
static/swagger-ui/swagger-ui-standalone-preset.js
Normal file
File diff suppressed because one or more lines are too long
1
static/swagger-ui/swagger-ui-standalone-preset.js.map
Normal file
1
static/swagger-ui/swagger-ui-standalone-preset.js.map
Normal file
File diff suppressed because one or more lines are too long
4
static/swagger-ui/swagger-ui.css
Normal file
4
static/swagger-ui/swagger-ui.css
Normal file
File diff suppressed because one or more lines are too long
1
static/swagger-ui/swagger-ui.css.map
Normal file
1
static/swagger-ui/swagger-ui.css.map
Normal file
File diff suppressed because one or more lines are too long
3
static/swagger-ui/swagger-ui.js
Normal file
3
static/swagger-ui/swagger-ui.js
Normal file
File diff suppressed because one or more lines are too long
1
static/swagger-ui/swagger-ui.js.map
Normal file
1
static/swagger-ui/swagger-ui.js.map
Normal file
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
1.23.0
|
||||
1.23.1
|
Loading…
x
Reference in New Issue
Block a user