Skip to content

Commit

Permalink
Merge pull request #1 from a-kataev/initial
Browse files Browse the repository at this point in the history
initial version
  • Loading branch information
a-kataev authored Oct 28, 2022
2 parents 383681c + 3e3714c commit dd4b48b
Show file tree
Hide file tree
Showing 24 changed files with 489 additions and 0 deletions.
13 changes: 13 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
target-branch: "main"
schedule:
interval: "daily"
time: "03:00"
reviewers:
- "a-kataev"
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# 🗂 swagfs - Swagger-UI FileSystem
77 changes: 77 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package swagfs

import (
"encoding/json"
"fmt"
"io"

"github.com/a-kataev/swagfs/files"
"github.com/a-kataev/swagfs/tmpl"
)

type URL struct {
URL string `json:"url"`
Name string `json:"name,omitempty"`
}

type Config struct {
Urls []URL `json:"urls"`
Layout string `json:"layout"`
}

var _ tmpl.File = (*Config)(nil)

func defaultConfig() *Config {
return &Config{
Urls: []URL{
{
URL: "/api/v1/swagger.yaml",
Name: "v1",
},
},
Layout: "BaseLayout",
}
}

func NewConfig() *Config {
return defaultConfig()
}

func (c *Config) Filename() string {
return files.ConfigName
}

func (c *Config) Template() string {
return string(files.ConfigData())
}

func (c *Config) TagFunc(w io.Writer, tag string) (int, error) {
switch tag {
case "layout":
return w.Write([]byte(c.Layout))
case "urls":
b, err := json.Marshal(c.Urls)
if err != nil {
return 0, fmt.Errorf("urls: %v", err)
}

return w.Write(b)
}

return 0, nil
}

func (c *Config) AddURL(url, name string) *Config {
c.Urls = append(c.Urls, URL{
URL: url,
Name: name,
})

return c
}

func (c *Config) SetLayout(layout string) *Config {
c.Layout = layout

return c
}
16 changes: 16 additions & 0 deletions files/config/swagger-initializer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
window.onload = function() {
window.ui = SwaggerUIBundle({
urls: {{urls}},
dom_id: "#swagger-ui",
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "{{layout}}",
validatorUrl: null
});
};
Binary file added files/dist/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added files/dist/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions files/dist/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
html {
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}

*,
*:before,
*:after {
box-sizing: inherit;
}

body {
margin: 0;
background: #fafafa;
}
19 changes: 19 additions & 0 deletions files/dist/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!-- 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="stylesheet" type="text/css" href="index.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" />
</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 src="./swagger-initializer.js" charset="UTF-8"> </script>
</body>
</html>
79 changes: 79 additions & 0 deletions files/dist/oauth2-redirect.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<!doctype html>
<html lang="en-US">
<head>
<title>Swagger UI: OAuth2 Redirect</title>
</head>
<body>
<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).replace('?', '&');
} 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. The 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();
}

if (document.readyState !== 'loading') {
run();
} else {
document.addEventListener('DOMContentLoaded', function () {
run();
});
}
</script>
</body>
</html>
16 changes: 16 additions & 0 deletions files/dist/swagger-initializer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
window.onload = function() {
window.ui = SwaggerUIBundle({
url: "/api/v1/swagger.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "BaseLayout",
validatorUrl: null
});
};
3 changes: 3 additions & 0 deletions files/dist/swagger-ui-bundle.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions files/dist/swagger-ui-bundle.js.map

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions files/dist/swagger-ui-standalone-preset.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions files/dist/swagger-ui-standalone-preset.js.map

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions files/dist/swagger-ui.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions files/dist/swagger-ui.css.map

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions files/dist/swagger-ui.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions files/dist/swagger-ui.js.map

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions files/files.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package files

import (
"embed"
"io/fs"
)

//go:embed dist/*.js dist/*.js.map dist/*.css dist/*.css.map dist/*.html dist/*.png
var distFS embed.FS

func DistFS() fs.FS {
f, _ := fs.Sub(distFS, "dist")

return f
}

//go:embed config/swagger-initializer.js
var configFile []byte

const ConfigName = "swagger-initializer.js"

func ConfigData() []byte {
return configFile
}
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module github.com/a-kataev/swagfs

go 1.19

require github.com/valyala/fasttemplate v1.2.2

require github.com/valyala/bytebufferpool v1.0.0 // indirect
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
110 changes: 110 additions & 0 deletions static/static.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package static

import (
"bytes"
"io"
"io/fs"
"time"
)

type info struct {
name string
size int64
}

var _ fs.FileInfo = (*info)(nil)

func (*info) IsDir() bool {
return false
}

func (*info) ModTime() time.Time {
return time.Time{}
}

func (*info) Mode() fs.FileMode {
return fs.ModePerm
}

func (i *info) Name() string {
return i.name
}

func (i *info) Size() int64 {
return i.size
}

func (*info) Sys() any {
return nil
}

type file struct {
info *info
reader *bytes.Reader
}

var (
_ fs.File = (*file)(nil)
_ io.ReadCloser = (*file)(nil)
)

func (f *file) Close() error {
return nil
}

func (f *file) Read(b []byte) (int, error) {
return f.reader.Read(b)
}

func (f *file) Seek(o int64, w int) (int64, error) {
return f.reader.Seek(o, w)
}

func (f *file) Stat() (fs.FileInfo, error) {
return f.info, nil
}

type AddFunc = func(*Static)

func File(name string, data []byte) AddFunc {
return func(f *Static) {
if data == nil {
data = []byte{}
}

f.files[name] = data
}
}

type Static struct {
files map[string][]byte
}

var _ fs.FS = (*Static)(nil)

func FS(files ...AddFunc) *Static {
mfs := &Static{
files: make(map[string][]byte, len(files)),
}

for _, fn := range files {
fn(mfs)
}

return mfs
}

func (f *Static) Open(name string) (fs.File, error) {
data, ok := f.files[name]
if !ok {
return nil, fs.ErrNotExist
}

return &file{
info: &info{
name: name,
size: int64(len(data)),
},
reader: bytes.NewReader(data),
}, nil
}
Loading

0 comments on commit dd4b48b

Please sign in to comment.