From 3b96bd3723a2642980d78720ab307ec7a68ef45a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferdinand=20M=C3=BCtsch?= Date: Wed, 13 Oct 2021 17:47:18 +0200 Subject: [PATCH] docs: include relay endpoint in swagger docs --- routes/api/diagnostics.go | 2 +- routes/api/health.go | 2 +- routes/api/heartbeat.go | 16 +- routes/api/summary.go | 2 +- routes/compat/shields/v1/badge.go | 2 +- routes/compat/wakatime/v1/all_time.go | 2 +- routes/compat/wakatime/v1/projects.go | 2 +- routes/compat/wakatime/v1/stats.go | 2 +- routes/compat/wakatime/v1/statusbar.go | 4 +- routes/compat/wakatime/v1/summaries.go | 2 +- routes/compat/wakatime/v1/users.go | 2 +- routes/relay/relay.go | 45 +++++ static/docs/docs.go | 235 +++++++++++++++++++++++-- static/docs/swagger.json | 235 +++++++++++++++++++++++-- static/docs/swagger.yaml | 167 ++++++++++++++++-- 15 files changed, 650 insertions(+), 70 deletions(-) diff --git a/routes/api/diagnostics.go b/routes/api/diagnostics.go index 8cc16ea..7ba37a7 100644 --- a/routes/api/diagnostics.go +++ b/routes/api/diagnostics.go @@ -41,7 +41,7 @@ func (h *DiagnosticsApiHandler) RegisterRoutes(router *mux.Router) { // @Param diagnostics body models.Diagnostics true "A single diagnostics object sent by WakaTime CLI" // @Security ApiKeyAuth // @Success 201 -// @Router /plugins/errors [post] +// @Router /api/plugins/errors [post] func (h *DiagnosticsApiHandler) Post(w http.ResponseWriter, r *http.Request) { var diagnostics models.Diagnostics diff --git a/routes/api/health.go b/routes/api/health.go index 5409cac..58d061e 100644 --- a/routes/api/health.go +++ b/routes/api/health.go @@ -25,7 +25,7 @@ func (h *HealthApiHandler) RegisterRoutes(router *mux.Router) { // @Tags misc // @Produce plain // @Success 200 {string} string -// @Router /health [get] +// @Router /api/health [get] func (h *HealthApiHandler) Get(w http.ResponseWriter, r *http.Request) { var dbStatus int if sqlDb, err := h.db.DB(); err == nil { diff --git a/routes/api/heartbeat.go b/routes/api/heartbeat.go index 0d67642..f0e387b 100644 --- a/routes/api/heartbeat.go +++ b/routes/api/heartbeat.go @@ -60,7 +60,7 @@ func (h *HeartbeatApiHandler) RegisterRoutes(router *mux.Router) { // @Param heartbeat body models.Heartbeat true "A single heartbeat" // @Security ApiKeyAuth // @Success 201 -// @Router /heartbeat [post] +// @Router /api/heartbeat [post] func (h *HeartbeatApiHandler) Post(w http.ResponseWriter, r *http.Request) { user, err := routeutils.CheckEffectiveUser(w, r, h.userSrvc, "current") if err != nil { @@ -182,7 +182,7 @@ func constructSuccessResponse(n int) *heartbeatResponseVm { // @Param heartbeat body models.Heartbeat true "A single heartbeat" // @Security ApiKeyAuth // @Success 201 -// @Router /v1/users/{user}/heartbeats [post] +// @Router /api/v1/users/{user}/heartbeats [post] func (h *HeartbeatApiHandler) postAlias1() {} // @Summary Push a new heartbeat @@ -192,7 +192,7 @@ func (h *HeartbeatApiHandler) postAlias1() {} // @Param heartbeat body models.Heartbeat true "A single heartbeat" // @Security ApiKeyAuth // @Success 201 -// @Router /compat/wakatime/v1/users/{user}/heartbeats [post] +// @Router /api/compat/wakatime/v1/users/{user}/heartbeats [post] func (h *HeartbeatApiHandler) postAlias2() {} // @Summary Push a new heartbeat @@ -202,7 +202,7 @@ func (h *HeartbeatApiHandler) postAlias2() {} // @Param heartbeat body models.Heartbeat true "A single heartbeat" // @Security ApiKeyAuth // @Success 201 -// @Router /users/{user}/heartbeats [post] +// @Router /api/users/{user}/heartbeats [post] func (h *HeartbeatApiHandler) postAlias3() {} // @Summary Push new heartbeats @@ -212,7 +212,7 @@ func (h *HeartbeatApiHandler) postAlias3() {} // @Param heartbeat body []models.Heartbeat true "Multiple heartbeats" // @Security ApiKeyAuth // @Success 201 -// @Router /heartbeats [post] +// @Router /api/heartbeats [post] func (h *HeartbeatApiHandler) postAlias4() {} // @Summary Push new heartbeats @@ -222,7 +222,7 @@ func (h *HeartbeatApiHandler) postAlias4() {} // @Param heartbeat body []models.Heartbeat true "Multiple heartbeats" // @Security ApiKeyAuth // @Success 201 -// @Router /v1/users/{user}/heartbeats.bulk [post] +// @Router /api/v1/users/{user}/heartbeats.bulk [post] func (h *HeartbeatApiHandler) postAlias5() {} // @Summary Push new heartbeats @@ -232,7 +232,7 @@ func (h *HeartbeatApiHandler) postAlias5() {} // @Param heartbeat body []models.Heartbeat true "Multiple heartbeats" // @Security ApiKeyAuth // @Success 201 -// @Router /compat/wakatime/v1/users/{user}/heartbeats.bulk [post] +// @Router /api/compat/wakatime/v1/users/{user}/heartbeats.bulk [post] func (h *HeartbeatApiHandler) postAlias6() {} // @Summary Push new heartbeats @@ -242,5 +242,5 @@ func (h *HeartbeatApiHandler) postAlias6() {} // @Param heartbeat body []models.Heartbeat true "Multiple heartbeats" // @Security ApiKeyAuth // @Success 201 -// @Router /users/{user}/heartbeats.bulk [post] +// @Router /api/users/{user}/heartbeats.bulk [post] func (h *HeartbeatApiHandler) postAlias7() {} diff --git a/routes/api/summary.go b/routes/api/summary.go index e46ce53..5494c96 100644 --- a/routes/api/summary.go +++ b/routes/api/summary.go @@ -42,7 +42,7 @@ func (h *SummaryApiHandler) RegisterRoutes(router *mux.Router) { // @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] +// @Router /api/summary [get] func (h *SummaryApiHandler) Get(w http.ResponseWriter, r *http.Request) { summary, err, status := su.LoadUserSummary(h.summarySrvc, r) if err != nil { diff --git a/routes/compat/shields/v1/badge.go b/routes/compat/shields/v1/badge.go index 9d41a8b..5f8a127 100644 --- a/routes/compat/shields/v1/badge.go +++ b/routes/compat/shields/v1/badge.go @@ -50,7 +50,7 @@ func (h *BadgeHandler) RegisterRoutes(router *mux.Router) { // @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] +// @Router /api/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) diff --git a/routes/compat/wakatime/v1/all_time.go b/routes/compat/wakatime/v1/all_time.go index 171a6dc..618e3a9 100644 --- a/routes/compat/wakatime/v1/all_time.go +++ b/routes/compat/wakatime/v1/all_time.go @@ -44,7 +44,7 @@ func (h *AllTimeHandler) RegisterRoutes(router *mux.Router) { // @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] +// @Router /api/compat/wakatime/v1/users/{user}/all_time_since_today [get] func (h *AllTimeHandler) Get(w http.ResponseWriter, r *http.Request) { values, _ := url.ParseQuery(r.URL.RawQuery) diff --git a/routes/compat/wakatime/v1/projects.go b/routes/compat/wakatime/v1/projects.go index ea4d8f3..5ecc86f 100644 --- a/routes/compat/wakatime/v1/projects.go +++ b/routes/compat/wakatime/v1/projects.go @@ -44,7 +44,7 @@ func (h *ProjectsHandler) RegisterRoutes(router *mux.Router) { // @Param q query string true "Query to filter projects by" // @Security ApiKeyAuth // @Success 200 {object} v1.ProjectsViewModel -// @Router /compat/wakatime/v1/users/{user}/projects [get] +// @Router /api/compat/wakatime/v1/users/{user}/projects [get] func (h *ProjectsHandler) Get(w http.ResponseWriter, r *http.Request) { user, err := routeutils.CheckEffectiveUser(w, r, h.userSrvc, "current") if err != nil { diff --git a/routes/compat/wakatime/v1/stats.go b/routes/compat/wakatime/v1/stats.go index 352675a..da1675c 100644 --- a/routes/compat/wakatime/v1/stats.go +++ b/routes/compat/wakatime/v1/stats.go @@ -50,7 +50,7 @@ func (h *StatsHandler) RegisterRoutes(router *mux.Router) { // @Param range path 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) // @Security ApiKeyAuth // @Success 200 {object} v1.StatsViewModel -// @Router /compat/wakatime/v1/users/{user}/stats/{range} [get] +// @Router /api/compat/wakatime/v1/users/{user}/stats/{range} [get] func (h *StatsHandler) Get(w http.ResponseWriter, r *http.Request) { var vars = mux.Vars(r) var authorizedUser, requestedUser *models.User diff --git a/routes/compat/wakatime/v1/statusbar.go b/routes/compat/wakatime/v1/statusbar.go index eebd148..8208f23 100644 --- a/routes/compat/wakatime/v1/statusbar.go +++ b/routes/compat/wakatime/v1/statusbar.go @@ -51,8 +51,8 @@ func (h *StatusBarHandler) RegisterRoutes(router *mux.Router) { // @Produce json // @Param user path string true "User ID to fetch data for (or 'current')" // @Security ApiKeyAuth -// @Success 200 {object} v1.StatusBarViewModel -// @Router /users/{user}/statusbar/today [get] +// @Success 200 {object} StatusBarViewModel +// @Router /api/users/{user}/statusbar/today [get] func (h *StatusBarHandler) Get(w http.ResponseWriter, r *http.Request) { user, err := routeutils.CheckEffectiveUser(w, r, h.userSrvc, "current") if err != nil { diff --git a/routes/compat/wakatime/v1/summaries.go b/routes/compat/wakatime/v1/summaries.go index 9dc4a27..c839e48 100644 --- a/routes/compat/wakatime/v1/summaries.go +++ b/routes/compat/wakatime/v1/summaries.go @@ -53,7 +53,7 @@ func (h *SummariesHandler) RegisterRoutes(router *mux.Router) { // @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] +// @Router /api/compat/wakatime/v1/users/{user}/summaries [get] func (h *SummariesHandler) Get(w http.ResponseWriter, r *http.Request) { _, err := routeutils.CheckEffectiveUser(w, r, h.userSrvc, "current") if err != nil { diff --git a/routes/compat/wakatime/v1/users.go b/routes/compat/wakatime/v1/users.go index 70f8d22..a461302 100644 --- a/routes/compat/wakatime/v1/users.go +++ b/routes/compat/wakatime/v1/users.go @@ -41,7 +41,7 @@ func (h *UsersHandler) RegisterRoutes(router *mux.Router) { // @Param user path string true "User ID to fetch (or 'current')" // @Security ApiKeyAuth // @Success 200 {object} v1.UserViewModel -// @Router /compat/wakatime/v1/users/{user} [get] +// @Router /api/compat/wakatime/v1/users/{user} [get] func (h *UsersHandler) Get(w http.ResponseWriter, r *http.Request) { wakapiUser, err := routeutils.CheckEffectiveUser(w, r, h.userSrvc, "current") if err != nil { diff --git a/routes/relay/relay.go b/routes/relay/relay.go index ce5e292..657ae77 100644 --- a/routes/relay/relay.go +++ b/routes/relay/relay.go @@ -73,3 +73,48 @@ func (h *RelayHandler) Any(w http.ResponseWriter, r *http.Request) { p.ServeHTTP(w, r) } + +// @Summary Proxy an GET API request to another Wakapi instance +// @ID relay-get +// @Tags relay +// @Param X-Target-URL header string true "Original URL to perform the request to" +// @Failure 403 {string} string "Returned if request path is not whitelisted" +// @Failure 502 {string} string "Returned if upstream host is down" +// @Router /relay [get] +func (h *RelayHandler) alias1() {} + +// @Summary Proxy an POST API request to another Wakapi instance +// @ID relay-post +// @Tags relay +// @Param X-Target-URL header string true "Original URL to perform the request to" +// @Failure 403 {string} string "Returned if request path is not whitelisted" +// @Failure 502 {string} string "Returned if upstream host is down" +// @Router /relay [post] +func (h *RelayHandler) alias2() {} + +// @Summary Proxy an PUT API request to another Wakapi instance +// @ID relay-put +// @Tags relay +// @Param X-Target-URL header string true "Original URL to perform the request to" +// @Failure 403 {string} string "Returned if request path is not whitelisted" +// @Failure 502 {string} string "Returned if upstream host is down" +// @Router /relay [put] +func (h *RelayHandler) alias3() {} + +// @Summary Proxy an PATCH API request to another Wakapi instance +// @ID relay-patch +// @Tags relay +// @Param X-Target-URL header string true "Original URL to perform the request to" +// @Failure 403 {string} string "Returned if request path is not whitelisted" +// @Failure 502 {string} string "Returned if upstream host is down" +// @Router /relay [patch] +func (h *RelayHandler) alias4() {} + +// @Summary Proxy an DELETE API request to another Wakapi instance +// @ID relay-delete +// @Tags relay +// @Param X-Target-URL header string true "Original URL to perform the request to" +// @Failure 403 {string} string "Returned if request path is not whitelisted" +// @Failure 502 {string} string "Returned if upstream host is down" +// @Router /relay [delete] +func (h *RelayHandler) alias5() {} diff --git a/static/docs/docs.go b/static/docs/docs.go index eb95ad0..5b96fbc 100644 --- a/static/docs/docs.go +++ b/static/docs/docs.go @@ -32,7 +32,7 @@ var doc = `{ "host": "{{.Host}}", "basePath": "{{.BasePath}}", "paths": { - "/compat/shields/v1/{user}/{interval}/{filter}": { + "/api/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": [ @@ -90,7 +90,7 @@ var doc = `{ } } }, - "/compat/wakatime/v1/users/{user}": { + "/api/compat/wakatime/v1/users/{user}": { "get": { "security": [ { @@ -125,7 +125,7 @@ var doc = `{ } } }, - "/compat/wakatime/v1/users/{user}/all_time_since_today": { + "/api/compat/wakatime/v1/users/{user}/all_time_since_today": { "get": { "security": [ { @@ -160,7 +160,7 @@ var doc = `{ } } }, - "/compat/wakatime/v1/users/{user}/heartbeats": { + "/api/compat/wakatime/v1/users/{user}/heartbeats": { "post": { "security": [ { @@ -193,7 +193,7 @@ var doc = `{ } } }, - "/compat/wakatime/v1/users/{user}/heartbeats.bulk": { + "/api/compat/wakatime/v1/users/{user}/heartbeats.bulk": { "post": { "security": [ { @@ -229,7 +229,7 @@ var doc = `{ } } }, - "/compat/wakatime/v1/users/{user}/projects": { + "/api/compat/wakatime/v1/users/{user}/projects": { "get": { "security": [ { @@ -271,7 +271,7 @@ var doc = `{ } } }, - "/compat/wakatime/v1/users/{user}/stats/{range}": { + "/api/compat/wakatime/v1/users/{user}/stats/{range}": { "get": { "security": [ { @@ -326,7 +326,7 @@ var doc = `{ } } }, - "/compat/wakatime/v1/users/{user}/summaries": { + "/api/compat/wakatime/v1/users/{user}/summaries": { "get": { "security": [ { @@ -393,7 +393,7 @@ var doc = `{ } } }, - "/health": { + "/api/health": { "get": { "produces": [ "text/plain" @@ -413,7 +413,7 @@ var doc = `{ } } }, - "/heartbeat": { + "/api/heartbeat": { "post": { "security": [ { @@ -446,7 +446,7 @@ var doc = `{ } } }, - "/heartbeats": { + "/api/heartbeats": { "post": { "security": [ { @@ -482,7 +482,7 @@ var doc = `{ } } }, - "/plugins/errors": { + "/api/plugins/errors": { "post": { "security": [ { @@ -515,7 +515,7 @@ var doc = `{ } } }, - "/summary": { + "/api/summary": { "get": { "security": [ { @@ -580,7 +580,7 @@ var doc = `{ } } }, - "/users/{user}/heartbeats": { + "/api/users/{user}/heartbeats": { "post": { "security": [ { @@ -613,7 +613,7 @@ var doc = `{ } } }, - "/users/{user}/heartbeats.bulk": { + "/api/users/{user}/heartbeats.bulk": { "post": { "security": [ { @@ -649,7 +649,42 @@ var doc = `{ } } }, - "/v1/users/{user}/heartbeats": { + "/api/users/{user}/statusbar/today": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Mimics https://wakatime.com/api/v1/users/current/statusbar/today. Have no official documentation", + "produces": [ + "application/json" + ], + "tags": [ + "wakatime" + ], + "summary": "Retrieve summary for statusbar", + "operationId": "statusbar", + "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.StatusBarViewModel" + } + } + } + } + }, + "/api/v1/users/{user}/heartbeats": { "post": { "security": [ { @@ -682,7 +717,7 @@ var doc = `{ } } }, - "/v1/users/{user}/heartbeats.bulk": { + "/api/v1/users/{user}/heartbeats.bulk": { "post": { "security": [ { @@ -717,6 +752,158 @@ var doc = `{ } } } + }, + "/relay": { + "get": { + "tags": [ + "relay" + ], + "summary": "Proxy an GET API request to another Wakapi instance", + "operationId": "relay-get", + "parameters": [ + { + "type": "string", + "description": "Original URL to perform the request to", + "name": "X-Target-URL", + "in": "header", + "required": true + } + ], + "responses": { + "403": { + "description": "Returned if request path is not whitelisted", + "schema": { + "type": "string" + } + }, + "502": { + "description": "Returned if upstream host is down", + "schema": { + "type": "string" + } + } + } + }, + "put": { + "tags": [ + "relay" + ], + "summary": "Proxy an PUT API request to another Wakapi instance", + "operationId": "relay-put", + "parameters": [ + { + "type": "string", + "description": "Original URL to perform the request to", + "name": "X-Target-URL", + "in": "header", + "required": true + } + ], + "responses": { + "403": { + "description": "Returned if request path is not whitelisted", + "schema": { + "type": "string" + } + }, + "502": { + "description": "Returned if upstream host is down", + "schema": { + "type": "string" + } + } + } + }, + "post": { + "tags": [ + "relay" + ], + "summary": "Proxy an POST API request to another Wakapi instance", + "operationId": "relay-post", + "parameters": [ + { + "type": "string", + "description": "Original URL to perform the request to", + "name": "X-Target-URL", + "in": "header", + "required": true + } + ], + "responses": { + "403": { + "description": "Returned if request path is not whitelisted", + "schema": { + "type": "string" + } + }, + "502": { + "description": "Returned if upstream host is down", + "schema": { + "type": "string" + } + } + } + }, + "delete": { + "tags": [ + "relay" + ], + "summary": "Proxy an DELETE API request to another Wakapi instance", + "operationId": "relay-delete", + "parameters": [ + { + "type": "string", + "description": "Original URL to perform the request to", + "name": "X-Target-URL", + "in": "header", + "required": true + } + ], + "responses": { + "403": { + "description": "Returned if request path is not whitelisted", + "schema": { + "type": "string" + } + }, + "502": { + "description": "Returned if upstream host is down", + "schema": { + "type": "string" + } + } + } + }, + "patch": { + "tags": [ + "relay" + ], + "summary": "Proxy an PATCH API request to another Wakapi instance", + "operationId": "relay-patch", + "parameters": [ + { + "type": "string", + "description": "Original URL to perform the request to", + "name": "X-Target-URL", + "in": "header", + "required": true + } + ], + "responses": { + "403": { + "description": "Returned if request path is not whitelisted", + "schema": { + "type": "string" + } + }, + "502": { + "description": "Returned if upstream host is down", + "schema": { + "type": "string" + } + } + } + } } }, "definitions": { @@ -791,6 +978,9 @@ var doc = `{ }, "type": { "type": "string" + }, + "user_agent": { + "type": "string" } } }, @@ -1014,6 +1204,17 @@ var doc = `{ } } }, + "v1.StatusBarViewModel": { + "type": "object", + "properties": { + "cached_at": { + "type": "string" + }, + "data": { + "$ref": "#/definitions/v1.SummariesData" + } + } + }, "v1.SummariesData": { "type": "object", "properties": { diff --git a/static/docs/swagger.json b/static/docs/swagger.json index 53d587d..6571d81 100644 --- a/static/docs/swagger.json +++ b/static/docs/swagger.json @@ -16,7 +16,7 @@ }, "basePath": "/api", "paths": { - "/compat/shields/v1/{user}/{interval}/{filter}": { + "/api/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": [ @@ -74,7 +74,7 @@ } } }, - "/compat/wakatime/v1/users/{user}": { + "/api/compat/wakatime/v1/users/{user}": { "get": { "security": [ { @@ -109,7 +109,7 @@ } } }, - "/compat/wakatime/v1/users/{user}/all_time_since_today": { + "/api/compat/wakatime/v1/users/{user}/all_time_since_today": { "get": { "security": [ { @@ -144,7 +144,7 @@ } } }, - "/compat/wakatime/v1/users/{user}/heartbeats": { + "/api/compat/wakatime/v1/users/{user}/heartbeats": { "post": { "security": [ { @@ -177,7 +177,7 @@ } } }, - "/compat/wakatime/v1/users/{user}/heartbeats.bulk": { + "/api/compat/wakatime/v1/users/{user}/heartbeats.bulk": { "post": { "security": [ { @@ -213,7 +213,7 @@ } } }, - "/compat/wakatime/v1/users/{user}/projects": { + "/api/compat/wakatime/v1/users/{user}/projects": { "get": { "security": [ { @@ -255,7 +255,7 @@ } } }, - "/compat/wakatime/v1/users/{user}/stats/{range}": { + "/api/compat/wakatime/v1/users/{user}/stats/{range}": { "get": { "security": [ { @@ -310,7 +310,7 @@ } } }, - "/compat/wakatime/v1/users/{user}/summaries": { + "/api/compat/wakatime/v1/users/{user}/summaries": { "get": { "security": [ { @@ -377,7 +377,7 @@ } } }, - "/health": { + "/api/health": { "get": { "produces": [ "text/plain" @@ -397,7 +397,7 @@ } } }, - "/heartbeat": { + "/api/heartbeat": { "post": { "security": [ { @@ -430,7 +430,7 @@ } } }, - "/heartbeats": { + "/api/heartbeats": { "post": { "security": [ { @@ -466,7 +466,7 @@ } } }, - "/plugins/errors": { + "/api/plugins/errors": { "post": { "security": [ { @@ -499,7 +499,7 @@ } } }, - "/summary": { + "/api/summary": { "get": { "security": [ { @@ -564,7 +564,7 @@ } } }, - "/users/{user}/heartbeats": { + "/api/users/{user}/heartbeats": { "post": { "security": [ { @@ -597,7 +597,7 @@ } } }, - "/users/{user}/heartbeats.bulk": { + "/api/users/{user}/heartbeats.bulk": { "post": { "security": [ { @@ -633,7 +633,42 @@ } } }, - "/v1/users/{user}/heartbeats": { + "/api/users/{user}/statusbar/today": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Mimics https://wakatime.com/api/v1/users/current/statusbar/today. Have no official documentation", + "produces": [ + "application/json" + ], + "tags": [ + "wakatime" + ], + "summary": "Retrieve summary for statusbar", + "operationId": "statusbar", + "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.StatusBarViewModel" + } + } + } + } + }, + "/api/v1/users/{user}/heartbeats": { "post": { "security": [ { @@ -666,7 +701,7 @@ } } }, - "/v1/users/{user}/heartbeats.bulk": { + "/api/v1/users/{user}/heartbeats.bulk": { "post": { "security": [ { @@ -701,6 +736,158 @@ } } } + }, + "/relay": { + "get": { + "tags": [ + "relay" + ], + "summary": "Proxy an GET API request to another Wakapi instance", + "operationId": "relay-get", + "parameters": [ + { + "type": "string", + "description": "Original URL to perform the request to", + "name": "X-Target-URL", + "in": "header", + "required": true + } + ], + "responses": { + "403": { + "description": "Returned if request path is not whitelisted", + "schema": { + "type": "string" + } + }, + "502": { + "description": "Returned if upstream host is down", + "schema": { + "type": "string" + } + } + } + }, + "put": { + "tags": [ + "relay" + ], + "summary": "Proxy an PUT API request to another Wakapi instance", + "operationId": "relay-put", + "parameters": [ + { + "type": "string", + "description": "Original URL to perform the request to", + "name": "X-Target-URL", + "in": "header", + "required": true + } + ], + "responses": { + "403": { + "description": "Returned if request path is not whitelisted", + "schema": { + "type": "string" + } + }, + "502": { + "description": "Returned if upstream host is down", + "schema": { + "type": "string" + } + } + } + }, + "post": { + "tags": [ + "relay" + ], + "summary": "Proxy an POST API request to another Wakapi instance", + "operationId": "relay-post", + "parameters": [ + { + "type": "string", + "description": "Original URL to perform the request to", + "name": "X-Target-URL", + "in": "header", + "required": true + } + ], + "responses": { + "403": { + "description": "Returned if request path is not whitelisted", + "schema": { + "type": "string" + } + }, + "502": { + "description": "Returned if upstream host is down", + "schema": { + "type": "string" + } + } + } + }, + "delete": { + "tags": [ + "relay" + ], + "summary": "Proxy an DELETE API request to another Wakapi instance", + "operationId": "relay-delete", + "parameters": [ + { + "type": "string", + "description": "Original URL to perform the request to", + "name": "X-Target-URL", + "in": "header", + "required": true + } + ], + "responses": { + "403": { + "description": "Returned if request path is not whitelisted", + "schema": { + "type": "string" + } + }, + "502": { + "description": "Returned if upstream host is down", + "schema": { + "type": "string" + } + } + } + }, + "patch": { + "tags": [ + "relay" + ], + "summary": "Proxy an PATCH API request to another Wakapi instance", + "operationId": "relay-patch", + "parameters": [ + { + "type": "string", + "description": "Original URL to perform the request to", + "name": "X-Target-URL", + "in": "header", + "required": true + } + ], + "responses": { + "403": { + "description": "Returned if request path is not whitelisted", + "schema": { + "type": "string" + } + }, + "502": { + "description": "Returned if upstream host is down", + "schema": { + "type": "string" + } + } + } + } } }, "definitions": { @@ -775,6 +962,9 @@ }, "type": { "type": "string" + }, + "user_agent": { + "type": "string" } } }, @@ -998,6 +1188,17 @@ } } }, + "v1.StatusBarViewModel": { + "type": "object", + "properties": { + "cached_at": { + "type": "string" + }, + "data": { + "$ref": "#/definitions/v1.SummariesData" + } + } + }, "v1.SummariesData": { "type": "object", "properties": { diff --git a/static/docs/swagger.yaml b/static/docs/swagger.yaml index db04e0c..0fe6280 100644 --- a/static/docs/swagger.yaml +++ b/static/docs/swagger.yaml @@ -49,6 +49,8 @@ definitions: type: number type: type: string + user_agent: + type: string type: object models.Summary: properties: @@ -198,6 +200,13 @@ definitions: data: $ref: '#/definitions/v1.StatsData' type: object + v1.StatusBarViewModel: + properties: + cached_at: + type: string + data: + $ref: '#/definitions/v1.SummariesData' + type: object v1.SummariesData: properties: categories: @@ -342,7 +351,7 @@ info: title: Wakapi API version: "1.0" paths: - /compat/shields/v1/{user}/{interval}/{filter}: + /api/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). @@ -387,7 +396,7 @@ paths: summary: Get badge data tags: - badges - /compat/wakatime/v1/users/{user}: + /api/compat/wakatime/v1/users/{user}: get: description: Mimics https://wakatime.com/developers#users operationId: get-wakatime-user @@ -409,7 +418,7 @@ paths: summary: Retrieve the given user tags: - wakatime - /compat/wakatime/v1/users/{user}/all_time_since_today: + /api/compat/wakatime/v1/users/{user}/all_time_since_today: get: description: Mimics https://wakatime.com/developers#all_time_since_today operationId: get-all-time @@ -431,7 +440,7 @@ paths: summary: Retrieve summary for all time tags: - wakatime - /compat/wakatime/v1/users/{user}/heartbeats: + /api/compat/wakatime/v1/users/{user}/heartbeats: post: consumes: - application/json @@ -451,7 +460,7 @@ paths: summary: Push a new heartbeat tags: - heartbeat - /compat/wakatime/v1/users/{user}/heartbeats.bulk: + /api/compat/wakatime/v1/users/{user}/heartbeats.bulk: post: consumes: - application/json @@ -473,7 +482,7 @@ paths: summary: Push new heartbeats tags: - heartbeat - /compat/wakatime/v1/users/{user}/projects: + /api/compat/wakatime/v1/users/{user}/projects: get: description: Mimics https://wakatime.com/developers#projects operationId: get-wakatime-projects @@ -500,7 +509,7 @@ paths: summary: Retrieve and fitler the user's projects tags: - wakatime - /compat/wakatime/v1/users/{user}/stats/{range}: + /api/compat/wakatime/v1/users/{user}/stats/{range}: get: description: Mimics https://wakatime.com/developers#stats operationId: get-wakatimes-tats @@ -539,7 +548,7 @@ paths: summary: Retrieve statistics for a given user tags: - wakatime - /compat/wakatime/v1/users/{user}/summaries: + /api/compat/wakatime/v1/users/{user}/summaries: get: description: Mimics https://wakatime.com/developers#summaries. operationId: get-wakatime-summaries @@ -586,7 +595,7 @@ paths: summary: Retrieve WakaTime-compatible summaries tags: - wakatime - /health: + /api/health: get: operationId: get-health produces: @@ -599,7 +608,7 @@ paths: summary: Check the application's health status tags: - misc - /heartbeat: + /api/heartbeat: post: consumes: - application/json @@ -619,7 +628,7 @@ paths: summary: Push a new heartbeat tags: - heartbeat - /heartbeats: + /api/heartbeats: post: consumes: - application/json @@ -641,7 +650,7 @@ paths: summary: Push new heartbeats tags: - heartbeat - /plugins/errors: + /api/plugins/errors: post: consumes: - application/json @@ -661,7 +670,7 @@ paths: summary: Push a new diagnostics object tags: - diagnostics - /summary: + /api/summary: get: operationId: get-summary parameters: @@ -706,7 +715,7 @@ paths: summary: Retrieve a summary tags: - summary - /users/{user}/heartbeats: + /api/users/{user}/heartbeats: post: consumes: - application/json @@ -726,7 +735,7 @@ paths: summary: Push a new heartbeat tags: - heartbeat - /users/{user}/heartbeats.bulk: + /api/users/{user}/heartbeats.bulk: post: consumes: - application/json @@ -748,7 +757,30 @@ paths: summary: Push new heartbeats tags: - heartbeat - /v1/users/{user}/heartbeats: + /api/users/{user}/statusbar/today: + get: + description: Mimics https://wakatime.com/api/v1/users/current/statusbar/today. + Have no official documentation + operationId: statusbar + 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.StatusBarViewModel' + security: + - ApiKeyAuth: [] + summary: Retrieve summary for statusbar + tags: + - wakatime + /api/v1/users/{user}/heartbeats: post: consumes: - application/json @@ -768,7 +800,7 @@ paths: summary: Push a new heartbeat tags: - heartbeat - /v1/users/{user}/heartbeats.bulk: + /api/v1/users/{user}/heartbeats.bulk: post: consumes: - application/json @@ -790,6 +822,107 @@ paths: summary: Push new heartbeats tags: - heartbeat + /relay: + delete: + operationId: relay-delete + parameters: + - description: Original URL to perform the request to + in: header + name: X-Target-URL + required: true + type: string + responses: + "403": + description: Returned if request path is not whitelisted + schema: + type: string + "502": + description: Returned if upstream host is down + schema: + type: string + summary: Proxy an DELETE API request to another Wakapi instance + tags: + - relay + get: + operationId: relay-get + parameters: + - description: Original URL to perform the request to + in: header + name: X-Target-URL + required: true + type: string + responses: + "403": + description: Returned if request path is not whitelisted + schema: + type: string + "502": + description: Returned if upstream host is down + schema: + type: string + summary: Proxy an GET API request to another Wakapi instance + tags: + - relay + patch: + operationId: relay-patch + parameters: + - description: Original URL to perform the request to + in: header + name: X-Target-URL + required: true + type: string + responses: + "403": + description: Returned if request path is not whitelisted + schema: + type: string + "502": + description: Returned if upstream host is down + schema: + type: string + summary: Proxy an PATCH API request to another Wakapi instance + tags: + - relay + post: + operationId: relay-post + parameters: + - description: Original URL to perform the request to + in: header + name: X-Target-URL + required: true + type: string + responses: + "403": + description: Returned if request path is not whitelisted + schema: + type: string + "502": + description: Returned if upstream host is down + schema: + type: string + summary: Proxy an POST API request to another Wakapi instance + tags: + - relay + put: + operationId: relay-put + parameters: + - description: Original URL to perform the request to + in: header + name: X-Target-URL + required: true + type: string + responses: + "403": + description: Returned if request path is not whitelisted + schema: + type: string + "502": + description: Returned if upstream host is down + schema: + type: string + summary: Proxy an PUT API request to another Wakapi instance + tags: + - relay securityDefinitions: ApiKeyAuth: in: header