diff --git a/README.md b/README.md index dbf5aca..a7d2889 100644 --- a/README.md +++ b/README.md @@ -84,3 +84,36 @@ r.Use(fiberredoc.New(doc)) ``` See [examples](/_examples) + + +## Configuration Options + + +```go +r := redoc.Redoc{ + SpecFile: "testdata/spec.json", + SpecFS: &spec, + SpecPath: "/openapi.json", // "/openapi.yaml" Title: "Test API", + Description: "Meta Description" + Options: map[string]any{ + "disableSearch": true, + "theme": map[string]any{ + "colors": map[string]any{"primary": map[string]any{"main": "#297b21"}}, + "typography": map[string]any{"headings": map[string]any{"fontWeight": "600"}} + "sidebar": map[string]any{"backgroundColor": "#cae6c6"}, + }, + }, +} +``` + +`Title` : The head title of your html page - Shown on search engine. + +`Description` : The head meta description of your html page - Shown on search engine. + +`Options`: redoc option see [Redoc Configuration Documentation](https://github.com/Redocly/redoc/blob/main/docs/config.md) + +`SpecFile`: file path to your openapi/swagger file from your project. + +`SpecPath`: url path to call your openapi/swagger file from redoc documentation. Must be aligned with your web server configuration. + +`DocsPath` : url path to call your generated API documentation. Must be aligned with your web server configuration. \ No newline at end of file diff --git a/assets/index.html b/assets/index.html index 09a1ef5..53cc3e1 100644 --- a/assets/index.html +++ b/assets/index.html @@ -15,6 +15,6 @@
- + diff --git a/go.mod b/go.mod index e42f333..c140b3f 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/mvrilo/go-redoc -go 1.17 +go 1.18 require github.com/stretchr/testify v1.8.4 diff --git a/redoc.go b/redoc.go index 9f624a4..f9ff5b2 100644 --- a/redoc.go +++ b/redoc.go @@ -3,7 +3,9 @@ package redoc import ( "bytes" "embed" + "encoding/json" "errors" + "log" "net/http" "os" "strings" @@ -21,6 +23,7 @@ type Redoc struct { SpecFS *embed.FS Title string Description string + Options map[string]any } // HTML represents the redoc index.html page @@ -41,11 +44,21 @@ func (r Redoc) Body() ([]byte, error) { return nil, err } + var optionsString = "{}" + + var optionsByte, errM = json.Marshal(r.Options) + if errM == nil { + optionsString = string(optionsByte) + } else { + log.Printf("Invalid json options provided, using default options instead.") + } + if err = tpl.Execute(buf, map[string]string{ "body": JavaScript, "title": r.Title, "url": r.SpecPath, "description": r.Description, + "options": optionsString, }); err != nil { return nil, err } diff --git a/redoc_test.go b/redoc_test.go index 7904472..8b84af1 100644 --- a/redoc_test.go +++ b/redoc_test.go @@ -60,3 +60,59 @@ func TestRedoc(t *testing.T) { }) }) } + +func TestRedocWithOptions(t *testing.T) { + r := redoc.Redoc{ + SpecFile: "testdata/spec.json", + SpecFS: &spec, + SpecPath: "/openapi.json", // "/openapi.yaml" + Title: "Test API", + Options: map[string]any{ + "disableSearch": true, + "theme": map[string]any{ + "colors": map[string]any{"primary": map[string]any{"main": "#297b21"}}, + "typography": map[string]any{"headings": map[string]any{"fontWeight": "600"}}, + "sidebar": map[string]any{"backgroundColor": "#cae6c6"}, + }, + }, + } + + t.Run("Body", func(t *testing.T) { + body, err := r.Body() + assert.NoError(t, err) + assert.Contains(t, string(body), r.Title) + }) + + t.Run("Handler", func(t *testing.T) { + handler := r.Handler() + + t.Run("Spec", func(t *testing.T) { + req := httptest.NewRequest(http.MethodGet, "/openapi.json", nil) + w := httptest.NewRecorder() + handler(w, req) + + resp := w.Result() + assert.Equal(t, http.StatusOK, resp.StatusCode) + assert.Equal(t, "application/json", resp.Header.Get("Content-Type")) + + body, err := ioutil.ReadAll(resp.Body) + assert.NoError(t, err) + assert.Contains(t, string(body), `"swagger":"2.0"`) + }) + + t.Run("Docs", func(t *testing.T) { + req := httptest.NewRequest(http.MethodGet, "/", nil) + w := httptest.NewRecorder() + handler(w, req) + + resp := w.Result() + assert.Equal(t, http.StatusOK, resp.StatusCode) + assert.Equal(t, "text/html", resp.Header.Get("Content-Type")) + + body, err := ioutil.ReadAll(resp.Body) + assert.NoError(t, err) + assert.Contains(t, string(body), r.Title) + assert.Contains(t, string(body), `{"disableSearch`) + }) + }) +}