forked from NYANDEV/forgejo
[API] Forgejo API /api/forgejo/v1
(cherry picked from commit 20b56692693e054bb3c04b4ef12b29b0715b4530) (cherry picked from commit 1574643a6a9634e5b92c033a4bfb69062a86bd05) Update semantic version according to specification (cherry picked from commit 22510f41306f9c133a7e99b61f9c38dabfd4b810) Mise à jour de 'Makefile' (cherry picked from commit c3d85d8409f1bb18a45659a167cf1ffee057f3b6) (cherry picked from commit 5ea23098513c068444226af41faf9be9c4c998e6) (cherry picked from commit ec5217b9d1b94bb04e34ce8c27eecbdc6f3a247a) (cherry picked from commit 14f08e364b2ad7e3176b45d3ec8da5f5605b4315) (cherry picked from commit b4465c67b8737aed9fd79a43046aa3795a298e68) [API] [SEMVER] replace number with version (cherry picked from commit fba48e64977a75e77c9c6cf8e3f8a679a5e7b733) (cherry picked from commit 532ec5d8782703b62d7d02312764e50637cd016e) [API] [SEMVER] [v1.20] less is replaced by css (cherry picked from commit 01ca3a4f4291cf4c62df42cbd12a00638f3cdc70) (cherry picked from commit 1d928c3ab2e1fda6082e1400d89ea96d6605ebaa) (cherry picked from commit a39dc804cd1da86444ed709455857f069475e7db) Conflicts: webpack.config.js (cherry picked from commit adc68578b3eb41215338125edfca91804706f8a1) (cherry picked from commit 9b8d98475fd7efcc15bf0d91b0af6ef3aff64508) (cherry picked from commit 25161039745a63282257eded9616390241af8013) (cherry picked from commit 18e6287963a0e1863cd08fd514a4e732a1904a68) (cherry picked from commit e9694e67ab93ad74f7eae3152d88d95e8493e739) (cherry picked from commit a9763edaf002c8009a2cca4115cb8b926f8cdc85) (cherry picked from commit e2b550f4fba144f9637a212b56bfe30cac1adb3b) (cherry picked from commit2edac36701
) [API] Forgejo API /api/forgejo/v1 (squash) Update semver as v1.20 is entering release candidate mode (cherry picked from commit 4995098ec3c6eee19a7ad7bc956b71c6e937c04c) (cherry picked from commit 578ccfdd27d7a280050bdf61d497d07decf98f2f) (cherry picked from commit 1bf6ac09520490f0a56b9b55d7836c2d8ea5d22c) (cherry picked from commit 2fe16b2bfed62c0386d0bfe104f7dcc621d1c3be) (cherry picked from commit 7cd9d027eec5a2b328d06a47f34545943560fe1b) (cherry picked from commit eaed4be2ae88055a15dcc96564440c301a13ba8e) (cherry picked from commit cc94f3115f844a0f16064e49e5eb719d33bc4441) (cherry picked from commit d7a77e35ccfd2d0fc2ba98932296ab7354edd2db) (cherry picked from commit cd8eb68ab7b3e2eaacf78d370c762f43cc19fd6a) (cherry picked from commit 68487ac95f742837e7ff38df902834b6173cd9ab) (cherry picked from commit 616dceb565456d6fac6f58b1c4de43e9d3254090) (cherry picked from commit 545fe5975b47d2eab348a57b87c6fd4590f33442) (cherry picked from commit c042cf8eda2dea805138bd64daa7fbe07865ed5a) (cherry picked from commit ae5e5a7468aa66312055a26841f658574a9b0dd7) (cherry picked from commit 8034ef5fa2648a127f8c84c572bec02a1ff6bb9f) (cherry picked from commit aaf0293034468505449d33ab1483ae65b4175754) (cherry picked from commit daafa8ce58e5e6077da585b13e5190856228a4a3) (cherry picked from commit 7ca3681d3e2ed5ec1ae44364cba476d642e2b557) (cherry picked from commit 39f72cba71ff3f9d2cbb05c88031b34933573a8c) (cherry picked from commit 60a591713097384935ba0ac51a5cd4793f7544a8) (cherry picked from commit 4853bd9e16bc8986ba8159349e93bc3093dc8ab9) [API] Move forgejo api file (squash) - Move the file to accommodatefaa28b5a44
(cherry picked from commit bce89351d251bfa18c677b30bc7da80856d919fb) (cherry picked from commit 11ae7f6e85395b287c6f4108c531aa1a81fd964c) (cherry picked from commit 25e96cfcb28859406329090eb0c7990bea4e73eb) (cherry picked from commit6d8d19b391
)
This commit is contained in:
parent
20a468fc68
commit
5afc5c454b
14 changed files with 398 additions and 2 deletions
32
Makefile
32
Makefile
|
@ -92,7 +92,10 @@ else
|
||||||
endif
|
endif
|
||||||
VERSION = ${GITEA_VERSION}
|
VERSION = ${GITEA_VERSION}
|
||||||
|
|
||||||
LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)"
|
# SemVer
|
||||||
|
FORGEJO_VERSION := 5.0.0+0-gitea-1.20.0
|
||||||
|
|
||||||
|
LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)" -X "code.gitea.io/gitea/routers/api/forgejo/v1.ForgejoVersion=$(FORGEJO_VERSION)"
|
||||||
|
|
||||||
LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64
|
LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64
|
||||||
|
|
||||||
|
@ -144,6 +147,8 @@ ifdef DEPS_PLAYWRIGHT
|
||||||
PLAYWRIGHT_FLAGS += --with-deps
|
PLAYWRIGHT_FLAGS += --with-deps
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
FORGEJO_API_SPEC := public/assets/forgejo/api.v1.yml
|
||||||
|
|
||||||
SWAGGER_SPEC := templates/swagger/v1_json.tmpl
|
SWAGGER_SPEC := templates/swagger/v1_json.tmpl
|
||||||
SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|g
|
SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|g
|
||||||
SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|"basePath": "/api/v1"|g
|
SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|"basePath": "/api/v1"|g
|
||||||
|
@ -220,6 +225,8 @@ help:
|
||||||
@echo " - generate-license update license files"
|
@echo " - generate-license update license files"
|
||||||
@echo " - generate-gitignore update gitignore files"
|
@echo " - generate-gitignore update gitignore files"
|
||||||
@echo " - generate-manpage generate manpage"
|
@echo " - generate-manpage generate manpage"
|
||||||
|
@echo " - generate-forgejo-api generate the forgejo API from spec"
|
||||||
|
@echo " - forgejo-api-validate check if the forgejo API matches the specs"
|
||||||
@echo " - generate-swagger generate the swagger spec from code comments"
|
@echo " - generate-swagger generate the swagger spec from code comments"
|
||||||
@echo " - swagger-validate check if the swagger spec is valid"
|
@echo " - swagger-validate check if the swagger spec is valid"
|
||||||
@echo " - go-licenses regenerate go licenses"
|
@echo " - go-licenses regenerate go licenses"
|
||||||
|
@ -304,6 +311,27 @@ ifneq "$(TAGS)" "$(shell cat $(TAGS_EVIDENCE) 2>/dev/null)"
|
||||||
TAGS_PREREQ := $(TAGS_EVIDENCE)
|
TAGS_PREREQ := $(TAGS_EVIDENCE)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
OAPI_CODEGEN_PACKAGE ?= github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.12.4
|
||||||
|
KIN_OPENAPI_CODEGEN_PACKAGE ?= github.com/getkin/kin-openapi/cmd/validate@v0.114.0
|
||||||
|
FORGEJO_API_SERVER = routers/api/forgejo/v1/generated.go
|
||||||
|
|
||||||
|
.PHONY: generate-forgejo-api
|
||||||
|
generate-forgejo-api: $(FORGEJO_API_SPEC)
|
||||||
|
$(GO) run $(OAPI_CODEGEN_PACKAGE) -package v1 -generate chi-server,types $< > $(FORGEJO_API_SERVER)
|
||||||
|
|
||||||
|
.PHONY: forgejo-api-check
|
||||||
|
forgejo-api-check: generate-forgejo-api
|
||||||
|
@diff=$$(git diff $(FORGEJO_API_SERVER) ; \
|
||||||
|
if [ -n "$$diff" ]; then \
|
||||||
|
echo "Please run 'make generate-forgejo-api' and commit the result:"; \
|
||||||
|
echo "$${diff}"; \
|
||||||
|
exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
.PHONY: forgejo-api-validate
|
||||||
|
forgejo-api-validate:
|
||||||
|
$(GO) run $(KIN_OPENAPI_CODEGEN_PACKAGE) $(FORGEJO_API_SPEC)
|
||||||
|
|
||||||
.PHONY: generate-swagger
|
.PHONY: generate-swagger
|
||||||
generate-swagger: $(SWAGGER_SPEC)
|
generate-swagger: $(SWAGGER_SPEC)
|
||||||
|
|
||||||
|
@ -334,7 +362,7 @@ checks: checks-frontend checks-backend
|
||||||
checks-frontend: lockfile-check svg-check
|
checks-frontend: lockfile-check svg-check
|
||||||
|
|
||||||
.PHONY: checks-backend
|
.PHONY: checks-backend
|
||||||
checks-backend: tidy-check swagger-check fmt-check misspell-check swagger-validate security-check
|
checks-backend: tidy-check swagger-check fmt-check misspell-check forgejo-api-validate swagger-validate security-check
|
||||||
|
|
||||||
.PHONY: lint
|
.PHONY: lint
|
||||||
lint: lint-frontend lint-backend
|
lint: lint-frontend lint-backend
|
||||||
|
|
40
public/assets/forgejo/api.v1.yml
Normal file
40
public/assets/forgejo/api.v1.yml
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
openapi: 3.0.0
|
||||||
|
info:
|
||||||
|
title: Forgejo API
|
||||||
|
description: |-
|
||||||
|
Forgejo REST API
|
||||||
|
|
||||||
|
contact:
|
||||||
|
email: contact@forgejo.org
|
||||||
|
license:
|
||||||
|
name: MIT
|
||||||
|
url: https://codeberg.org/forgejo/forgejo/src/branch/forgejo/LICENSE
|
||||||
|
version: 1.0.0
|
||||||
|
externalDocs:
|
||||||
|
description: Find out more about Forgejo
|
||||||
|
url: http://forgejo.org
|
||||||
|
servers:
|
||||||
|
- url: /api/forgejo/v1
|
||||||
|
paths:
|
||||||
|
/version:
|
||||||
|
get:
|
||||||
|
summary: API version
|
||||||
|
description: Semantic version of the Forgejo API
|
||||||
|
operationId: getVersion
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Version'
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
Version:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
version:
|
||||||
|
type: string
|
||||||
|
|
16
routers/api/forgejo/v1/api.go
Normal file
16
routers/api/forgejo/v1/api.go
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright 2023 The Forgejo Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.gitea.io/gitea/modules/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Routes() *web.Route {
|
||||||
|
m := web.NewRoute()
|
||||||
|
forgejo := NewForgejo()
|
||||||
|
m.Get("", Root)
|
||||||
|
m.Get("/version", forgejo.GetVersion)
|
||||||
|
return m
|
||||||
|
}
|
24
routers/api/forgejo/v1/forgejo.go
Normal file
24
routers/api/forgejo/v1/forgejo.go
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Forgejo struct{}
|
||||||
|
|
||||||
|
var _ ServerInterface = &Forgejo{}
|
||||||
|
|
||||||
|
func NewForgejo() *Forgejo {
|
||||||
|
return &Forgejo{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var ForgejoVersion = "development"
|
||||||
|
|
||||||
|
func (f *Forgejo) GetVersion(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
_ = json.NewEncoder(w).Encode(Version{&ForgejoVersion})
|
||||||
|
}
|
167
routers/api/forgejo/v1/generated.go
Normal file
167
routers/api/forgejo/v1/generated.go
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
// Package v1 provides primitives to interact with the openapi HTTP API.
|
||||||
|
//
|
||||||
|
// Code generated by github.com/deepmap/oapi-codegen version v1.12.4 DO NOT EDIT.
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Version defines model for Version.
|
||||||
|
type Version struct {
|
||||||
|
Version *string `json:"version,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServerInterface represents all server handlers.
|
||||||
|
type ServerInterface interface {
|
||||||
|
// API version
|
||||||
|
// (GET /version)
|
||||||
|
GetVersion(w http.ResponseWriter, r *http.Request)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServerInterfaceWrapper converts contexts to parameters.
|
||||||
|
type ServerInterfaceWrapper struct {
|
||||||
|
Handler ServerInterface
|
||||||
|
HandlerMiddlewares []MiddlewareFunc
|
||||||
|
ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type MiddlewareFunc func(http.Handler) http.Handler
|
||||||
|
|
||||||
|
// GetVersion operation middleware
|
||||||
|
func (siw *ServerInterfaceWrapper) GetVersion(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
|
||||||
|
var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
siw.Handler.GetVersion(w, r)
|
||||||
|
})
|
||||||
|
|
||||||
|
for _, middleware := range siw.HandlerMiddlewares {
|
||||||
|
handler = middleware(handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.ServeHTTP(w, r.WithContext(ctx))
|
||||||
|
}
|
||||||
|
|
||||||
|
type UnescapedCookieParamError struct {
|
||||||
|
ParamName string
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *UnescapedCookieParamError) Error() string {
|
||||||
|
return fmt.Sprintf("error unescaping cookie parameter '%s'", e.ParamName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *UnescapedCookieParamError) Unwrap() error {
|
||||||
|
return e.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
type UnmarshallingParamError struct {
|
||||||
|
ParamName string
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *UnmarshallingParamError) Error() string {
|
||||||
|
return fmt.Sprintf("Error unmarshalling parameter %s as JSON: %s", e.ParamName, e.Err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *UnmarshallingParamError) Unwrap() error {
|
||||||
|
return e.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
type RequiredParamError struct {
|
||||||
|
ParamName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *RequiredParamError) Error() string {
|
||||||
|
return fmt.Sprintf("Query argument %s is required, but not found", e.ParamName)
|
||||||
|
}
|
||||||
|
|
||||||
|
type RequiredHeaderError struct {
|
||||||
|
ParamName string
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *RequiredHeaderError) Error() string {
|
||||||
|
return fmt.Sprintf("Header parameter %s is required, but not found", e.ParamName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *RequiredHeaderError) Unwrap() error {
|
||||||
|
return e.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
type InvalidParamFormatError struct {
|
||||||
|
ParamName string
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *InvalidParamFormatError) Error() string {
|
||||||
|
return fmt.Sprintf("Invalid format for parameter %s: %s", e.ParamName, e.Err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *InvalidParamFormatError) Unwrap() error {
|
||||||
|
return e.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
type TooManyValuesForParamError struct {
|
||||||
|
ParamName string
|
||||||
|
Count int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *TooManyValuesForParamError) Error() string {
|
||||||
|
return fmt.Sprintf("Expected one value for %s, got %d", e.ParamName, e.Count)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handler creates http.Handler with routing matching OpenAPI spec.
|
||||||
|
func Handler(si ServerInterface) http.Handler {
|
||||||
|
return HandlerWithOptions(si, ChiServerOptions{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChiServerOptions struct {
|
||||||
|
BaseURL string
|
||||||
|
BaseRouter chi.Router
|
||||||
|
Middlewares []MiddlewareFunc
|
||||||
|
ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandlerFromMux creates http.Handler with routing matching OpenAPI spec based on the provided mux.
|
||||||
|
func HandlerFromMux(si ServerInterface, r chi.Router) http.Handler {
|
||||||
|
return HandlerWithOptions(si, ChiServerOptions{
|
||||||
|
BaseRouter: r,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandlerFromMuxWithBaseURL(si ServerInterface, r chi.Router, baseURL string) http.Handler {
|
||||||
|
return HandlerWithOptions(si, ChiServerOptions{
|
||||||
|
BaseURL: baseURL,
|
||||||
|
BaseRouter: r,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandlerWithOptions creates http.Handler with additional options
|
||||||
|
func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handler {
|
||||||
|
r := options.BaseRouter
|
||||||
|
|
||||||
|
if r == nil {
|
||||||
|
r = chi.NewRouter()
|
||||||
|
}
|
||||||
|
if options.ErrorHandlerFunc == nil {
|
||||||
|
options.ErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wrapper := ServerInterfaceWrapper{
|
||||||
|
Handler: si,
|
||||||
|
HandlerMiddlewares: options.Middlewares,
|
||||||
|
ErrorHandlerFunc: options.ErrorHandlerFunc,
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Group(func(r chi.Router) {
|
||||||
|
r.Get(options.BaseURL+"/version", wrapper.GetVersion)
|
||||||
|
})
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
14
routers/api/forgejo/v1/root.go
Normal file
14
routers/api/forgejo/v1/root.go
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright The Forgejo Authors.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Root(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc8631
|
||||||
|
w.Header().Set("Link", "</assets/forgejo/api.v1.yml>; rel=\"service-desc\"")
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ import (
|
||||||
"code.gitea.io/gitea/modules/translation"
|
"code.gitea.io/gitea/modules/translation"
|
||||||
"code.gitea.io/gitea/modules/web"
|
"code.gitea.io/gitea/modules/web"
|
||||||
actions_router "code.gitea.io/gitea/routers/api/actions"
|
actions_router "code.gitea.io/gitea/routers/api/actions"
|
||||||
|
forgejo "code.gitea.io/gitea/routers/api/forgejo/v1"
|
||||||
packages_router "code.gitea.io/gitea/routers/api/packages"
|
packages_router "code.gitea.io/gitea/routers/api/packages"
|
||||||
apiv1 "code.gitea.io/gitea/routers/api/v1"
|
apiv1 "code.gitea.io/gitea/routers/api/v1"
|
||||||
"code.gitea.io/gitea/routers/common"
|
"code.gitea.io/gitea/routers/common"
|
||||||
|
@ -175,6 +176,7 @@ func NormalRoutes() *web.Route {
|
||||||
|
|
||||||
r.Mount("/", web_routers.Routes())
|
r.Mount("/", web_routers.Routes())
|
||||||
r.Mount("/api/v1", apiv1.Routes())
|
r.Mount("/api/v1", apiv1.Routes())
|
||||||
|
r.Mount("/api/forgejo/v1", forgejo.Routes())
|
||||||
r.Mount("/api/internal", private.Routes())
|
r.Mount("/api/internal", private.Routes())
|
||||||
|
|
||||||
r.Post("/-/fetch-redirect", common.FetchRedirectDelegate)
|
r.Post("/-/fetch-redirect", common.FetchRedirectDelegate)
|
||||||
|
|
19
routers/web/misc/swagger-forgejo.go
Normal file
19
routers/web/misc/swagger-forgejo.go
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package misc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/base"
|
||||||
|
"code.gitea.io/gitea/modules/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// tplSwagger swagger page template
|
||||||
|
const tplForgejoSwagger base.TplName = "swagger/forgejo-ui"
|
||||||
|
|
||||||
|
func SwaggerForgejo(ctx *context.Context) {
|
||||||
|
ctx.Data["APIVersion"] = "v1"
|
||||||
|
ctx.HTML(http.StatusOK, tplForgejoSwagger)
|
||||||
|
}
|
|
@ -262,6 +262,7 @@ func Routes() *web.Route {
|
||||||
if setting.API.EnableSwagger {
|
if setting.API.EnableSwagger {
|
||||||
// Note: The route is here but no in API routes because it renders a web page
|
// Note: The route is here but no in API routes because it renders a web page
|
||||||
routes.Get("/api/swagger", append(mid, misc.Swagger)...) // Render V1 by default
|
routes.Get("/api/swagger", append(mid, misc.Swagger)...) // Render V1 by default
|
||||||
|
routes.Get("/api/forgejo/swagger", append(mid, misc.SwaggerForgejo)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: These really seem like things that could be folded into Contexter or as helper functions
|
// TODO: These really seem like things that could be folded into Contexter or as helper functions
|
||||||
|
|
13
templates/swagger/forgejo-ui.tmpl
Normal file
13
templates/swagger/forgejo-ui.tmpl
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Forgejo API</title>
|
||||||
|
<link href="{{AssetUrlPrefix}}/css/swagger.css?v={{AssetVersion}}" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a class="swagger-back-link" href="{{AppUrl}}">{{svg "octicon-reply"}}{{.locale.Tr "return_to_gitea"}}</a>
|
||||||
|
<div id="swagger-ui" data-source="{{AssetUrlPrefix}}/forgejo/api.{{.APIVersion}}.yml"></div>
|
||||||
|
<script src="{{AssetUrlPrefix}}/js/forgejoswagger.js?v={{AssetVersion}}"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
21
tests/integration/api_forgejo_root_test.go
Normal file
21
tests/integration/api_forgejo_root_test.go
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright The Forgejo Authors.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/tests"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAPIForgejoRoot(t *testing.T) {
|
||||||
|
defer tests.PrepareTestEnv(t)()
|
||||||
|
|
||||||
|
req := NewRequest(t, "GET", "/api/forgejo/v1")
|
||||||
|
resp := MakeRequest(t, req, http.StatusNoContent)
|
||||||
|
assert.Contains(t, resp.Header().Get("Link"), "/assets/forgejo/api.v1.yml")
|
||||||
|
}
|
25
tests/integration/api_forgejo_version_test.go
Normal file
25
tests/integration/api_forgejo_version_test.go
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright The Forgejo Authors.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/routers/api/forgejo/v1"
|
||||||
|
"code.gitea.io/gitea/tests"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAPIForgejoVersion(t *testing.T) {
|
||||||
|
defer tests.PrepareTestEnv(t)()
|
||||||
|
|
||||||
|
req := NewRequest(t, "GET", "/api/forgejo/v1/version")
|
||||||
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
var version v1.Version
|
||||||
|
DecodeJSON(t, resp, &version)
|
||||||
|
assert.Equal(t, "development", *version.Version)
|
||||||
|
}
|
22
web_src/js/standalone/forgejo-swagger.js
Normal file
22
web_src/js/standalone/forgejo-swagger.js
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import SwaggerUI from 'swagger-ui-dist/swagger-ui-es-bundle.js';
|
||||||
|
import 'swagger-ui-dist/swagger-ui.css';
|
||||||
|
|
||||||
|
window.addEventListener('load', async () => {
|
||||||
|
const url = document.getElementById('swagger-ui').getAttribute('data-source');
|
||||||
|
|
||||||
|
const ui = SwaggerUI({
|
||||||
|
url: url,
|
||||||
|
dom_id: '#swagger-ui',
|
||||||
|
deepLinking: true,
|
||||||
|
docExpansion: 'none',
|
||||||
|
defaultModelRendering: 'model', // don't show examples by default, because they may be incomplete
|
||||||
|
presets: [
|
||||||
|
SwaggerUI.presets.apis
|
||||||
|
],
|
||||||
|
plugins: [
|
||||||
|
SwaggerUI.plugins.DownloadUrl
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
window.ui = ui;
|
||||||
|
});
|
|
@ -76,6 +76,10 @@ export default {
|
||||||
webcomponents: [
|
webcomponents: [
|
||||||
fileURLToPath(new URL('web_src/js/webcomponents/webcomponents.js', import.meta.url)),
|
fileURLToPath(new URL('web_src/js/webcomponents/webcomponents.js', import.meta.url)),
|
||||||
],
|
],
|
||||||
|
forgejoswagger: [ // Forgejo swagger is OpenAPI 3.0.0 and has specific parameters
|
||||||
|
fileURLToPath(new URL('web_src/js/standalone/forgejo-swagger.js', import.meta.url)),
|
||||||
|
fileURLToPath(new URL('web_src/css/standalone/swagger.css', import.meta.url)),
|
||||||
|
],
|
||||||
swagger: [
|
swagger: [
|
||||||
fileURLToPath(new URL('web_src/js/standalone/swagger.js', import.meta.url)),
|
fileURLToPath(new URL('web_src/js/standalone/swagger.js', import.meta.url)),
|
||||||
fileURLToPath(new URL('web_src/css/standalone/swagger.css', import.meta.url)),
|
fileURLToPath(new URL('web_src/css/standalone/swagger.css', import.meta.url)),
|
||||||
|
|
Loading…
Reference in a new issue