move swagger-ui to webpack/npm (#9714)
Created a second webpack output file for swagger-ui which is loaded on the /api/swagger route. One notable difference is the absence of the swagger favicon that was previously used which is now the gitea icon. I see no easy way to restore that favicon, so I decided to not keep it.
This commit is contained in:
parent
44de66bf50
commit
f00961abe7
19 changed files with 875 additions and 462 deletions
8
Makefile
8
Makefile
|
@ -487,14 +487,6 @@ $(CSS_DEST): node_modules $(CSS_SOURCES)
|
|||
$(foreach file, $(filter-out web_src/less/themes/_base.less, $(wildcard web_src/less/themes/*)),npx lessc web_src/less/themes/$(notdir $(file)) > public/css/theme-$(notdir $(call strip-suffix,$(file))).css;)
|
||||
npx postcss --use autoprefixer --use cssnano --no-map --replace public/css/*
|
||||
|
||||
.PHONY: swagger-ui
|
||||
swagger-ui:
|
||||
rm -Rf public/vendor/assets/swagger-ui
|
||||
git clone --depth=10 -b v3.13.4 --single-branch https://github.com/swagger-api/swagger-ui.git $(TMPDIR)/swagger-ui
|
||||
mv $(TMPDIR)/swagger-ui/dist public/vendor/assets/swagger-ui
|
||||
rm -Rf $(TMPDIR)/swagger-ui
|
||||
$(SED_INPLACE) "s;http://petstore.swagger.io/v2/swagger.json;../../../swagger.v1.json;g" public/vendor/assets/swagger-ui/index.html
|
||||
|
||||
.PHONY: update-translations
|
||||
update-translations:
|
||||
mkdir -p ./translations
|
||||
|
|
902
package-lock.json
generated
902
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -4,6 +4,9 @@
|
|||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"dependencies": {
|
||||
"swagger-ui": "3.24.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.7.7",
|
||||
"@babel/plugin-transform-runtime": "7.7.6",
|
||||
|
|
BIN
public/vendor/assets/swagger-ui/favicon-16x16.png
vendored
BIN
public/vendor/assets/swagger-ui/favicon-16x16.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 665 B |
BIN
public/vendor/assets/swagger-ui/favicon-32x32.png
vendored
BIN
public/vendor/assets/swagger-ui/favicon-32x32.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 628 B |
60
public/vendor/assets/swagger-ui/index.html
vendored
60
public/vendor/assets/swagger-ui/index.html
vendored
|
@ -1,60 +0,0 @@
|
|||
<!-- 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"> </script>
|
||||
<script src="./swagger-ui-standalone-preset.js"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
// Begin Swagger UI call region
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "../../../swagger.v1.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>
|
|
@ -1,67 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en-US">
|
||||
<body onload="run()">
|
||||
</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.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();
|
||||
}
|
||||
</script>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"version":3,"sources":[],"names":[],"mappings":"","file":"swagger-ui.css","sourceRoot":""}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -6,6 +6,7 @@ var urlsToCache = [
|
|||
'{{StaticUrlPrefix}}/vendor/plugins/jquery-migrate/jquery-migrate.min.js?v=3.0.1',
|
||||
'{{StaticUrlPrefix}}/vendor/plugins/fomantic/semantic.min.js?v={{MD5 AppVer}}',
|
||||
'{{StaticUrlPrefix}}/js/index.js?v={{MD5 AppVer}}',
|
||||
'{{StaticUrlPrefix}}/js/swagger.js?v={{MD5 AppVer}}',
|
||||
'{{StaticUrlPrefix}}/js/gitgraph.js?v={{MD5 AppVer}}',
|
||||
'{{StaticUrlPrefix}}/vendor/plugins/clipboard/clipboard.min.js',
|
||||
'{{StaticUrlPrefix}}/vendor/plugins/vue/vue.min.js',
|
||||
|
|
|
@ -1,102 +1,24 @@
|
|||
<!-- 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="{{StaticUrlPrefix}}/vendor/assets/swagger-ui/swagger-ui.css" >
|
||||
<link rel="icon" type="image/png" href="{{StaticUrlPrefix}}/vendor/assets/swagger-ui/favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="{{StaticUrlPrefix}}/vendor/assets/swagger-ui/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>
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0">
|
||||
<defs>
|
||||
<symbol viewBox="0 0 20 20" id="unlocked">
|
||||
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="locked">
|
||||
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="close">
|
||||
<path d="M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="large-arrow">
|
||||
<path d="M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="large-arrow-down">
|
||||
<path d="M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z"/>
|
||||
</symbol>
|
||||
|
||||
|
||||
<symbol viewBox="0 0 24 24" id="jump-to">
|
||||
<path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 24 24" id="expand">
|
||||
<path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>
|
||||
</symbol>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="{{StaticUrlPrefix}}/vendor/assets/swagger-ui/swagger-ui-bundle.js"> </script>
|
||||
<script>
|
||||
|
||||
window.onload = function() {
|
||||
// Fetch the Swagger JSON specs
|
||||
var url = "{{AppUrl}}swagger.{{.APIJSONVersion}}.json"
|
||||
fetch(url)
|
||||
.then(function(response) {
|
||||
response.json()
|
||||
.then(function(spec) {
|
||||
// Make the page's protocol be at the top of the schemes list
|
||||
var protocol = window.location.protocol.slice(0, -1)
|
||||
spec.schemes.sort(function(x,y){ return x == protocol ? -1 : y == protocol ? 1 : 0 })
|
||||
// Begin Swagger UI call region
|
||||
const ui = SwaggerUIBundle({
|
||||
spec: spec,
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
]
|
||||
})
|
||||
// End Swagger UI call region
|
||||
|
||||
window.ui = ui
|
||||
})
|
||||
})
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Gitea API</title>
|
||||
<style>
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
*, *:before, *:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="swagger-ui" data-source="{{AppUrl}}swagger.{{.APIJSONVersion}}.json"></div>
|
||||
<script src="{{StaticUrlPrefix}}/js/swagger.js?v={{MD5 AppVer}}"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
30
web_src/js/swagger.js
Normal file
30
web_src/js/swagger.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
import SwaggerUI from 'swagger-ui';
|
||||
import 'swagger-ui/dist/swagger-ui.css';
|
||||
|
||||
window.addEventListener('load', async () => {
|
||||
const url = document.getElementById('swagger-ui').dataset.source;
|
||||
const res = await fetch(url);
|
||||
const spec = await res.json();
|
||||
|
||||
// Make the page's protocol be at the top of the schemes list
|
||||
const proto = window.location.protocol.slice(0, -1);
|
||||
spec.schemes.sort((a, b) => {
|
||||
if (a === proto) return -1;
|
||||
if (b === proto) return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
const ui = SwaggerUI({
|
||||
spec,
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUI.presets.apis
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUI.plugins.DownloadUrl
|
||||
]
|
||||
});
|
||||
|
||||
window.ui = ui;
|
||||
});
|
|
@ -1,15 +1,17 @@
|
|||
const path = require('path');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
const { SourceMapDevToolPlugin } = require('webpack');
|
||||
|
||||
module.exports = {
|
||||
mode: 'production',
|
||||
entry: {
|
||||
index: ['./web_src/js/index']
|
||||
index: ['./web_src/js/index'],
|
||||
swagger: ['./web_src/js/swagger'],
|
||||
},
|
||||
devtool: 'source-map',
|
||||
devtool: false,
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'public/js'),
|
||||
filename: 'index.js',
|
||||
filename: '[name].js',
|
||||
chunkFilename: '[name].js',
|
||||
},
|
||||
optimization: {
|
||||
|
@ -57,5 +59,18 @@ module.exports = {
|
|||
use: ['style-loader', 'css-loader'],
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
new SourceMapDevToolPlugin({
|
||||
filename: '[name].js.map',
|
||||
exclude: [
|
||||
'swagger.js',
|
||||
],
|
||||
}),
|
||||
],
|
||||
performance: {
|
||||
assetFilter: (filename) => {
|
||||
return !filename.endsWith('.map') && filename !== 'swagger.js';
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
Reference in a new issue