mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-12 19:05:55 +02:00
feat: added format code to config editor
This commit is contained in:
parent
5cc9068f5f
commit
594c61a0ff
13 changed files with 230 additions and 22 deletions
|
@ -7,6 +7,10 @@ const ngx = {
|
||||||
|
|
||||||
tokenize_config(content: string) {
|
tokenize_config(content: string) {
|
||||||
return http.post('/ngx/tokenize_config', {content})
|
return http.post('/ngx/tokenize_config', {content})
|
||||||
|
},
|
||||||
|
|
||||||
|
format_code(content: string) {
|
||||||
|
return http.post('/ngx/format_code', {content})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {computed, ref} from 'vue'
|
||||||
import config from '@/api/config'
|
import config from '@/api/config'
|
||||||
import {message} from 'ant-design-vue'
|
import {message} from 'ant-design-vue'
|
||||||
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
|
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
|
||||||
|
import ngx from '@/api/ngx'
|
||||||
|
|
||||||
const {$gettext, interpolate} = gettext
|
const {$gettext, interpolate} = gettext
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
@ -43,6 +44,14 @@ function save() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function format_code() {
|
||||||
|
ngx.format_code(configText.value).then(r => {
|
||||||
|
configText.value = r.content
|
||||||
|
message.success($gettext('Format successfully'))
|
||||||
|
}).catch(r => {
|
||||||
|
message.error(interpolate($gettext('Format error %{msg}'), {msg: r.message ?? ''}))
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,6 +63,9 @@ function save() {
|
||||||
<a-button @click="$router.go(-1)">
|
<a-button @click="$router.go(-1)">
|
||||||
<translate>Back</translate>
|
<translate>Back</translate>
|
||||||
</a-button>
|
</a-button>
|
||||||
|
<a-button @click="format_code">
|
||||||
|
<translate>Format Code</translate>
|
||||||
|
</a-button>
|
||||||
<a-button type="primary" @click="save">
|
<a-button type="primary" @click="save">
|
||||||
<translate>Save</translate>
|
<translate>Save</translate>
|
||||||
</a-button>
|
</a-button>
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -2,8 +2,6 @@ module github.com/0xJacky/Nginx-UI
|
||||||
|
|
||||||
go 1.19
|
go 1.19
|
||||||
|
|
||||||
replace github.com/tufanbarisyildirim/gonginx v0.0.0-20220829083426-44da4d61ef9a => github.com/0xJacky/gonginx v0.0.0-20230104051937-4c3a63627efb
|
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/creack/pty v1.1.18
|
github.com/creack/pty v1.1.18
|
||||||
github.com/dustin/go-humanize v1.0.0
|
github.com/dustin/go-humanize v1.0.0
|
||||||
|
@ -21,7 +19,7 @@ require (
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/shirou/gopsutil/v3 v3.21.7
|
github.com/shirou/gopsutil/v3 v3.21.7
|
||||||
github.com/spf13/cast v1.3.1
|
github.com/spf13/cast v1.3.1
|
||||||
github.com/tufanbarisyildirim/gonginx v0.0.0-20220829083426-44da4d61ef9a
|
github.com/tufanbarisyildirim/gonginx v0.0.0-20230104065106-9ae864d29eed
|
||||||
github.com/unknwon/com v1.0.1
|
github.com/unknwon/com v1.0.1
|
||||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
|
||||||
gopkg.in/ini.v1 v1.62.0
|
gopkg.in/ini.v1 v1.62.0
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -432,6 +432,8 @@ github.com/tklauser/numcpus v0.2.3 h1:nQ0QYpiritP6ViFhrKYsiv6VVxOpum2Gks5GhnJbS/
|
||||||
github.com/tklauser/numcpus v0.2.3/go.mod h1:vpEPS/JC+oZGGQ/My/vJnNsvMDQL6PwOqt8dsCw5j+E=
|
github.com/tklauser/numcpus v0.2.3/go.mod h1:vpEPS/JC+oZGGQ/My/vJnNsvMDQL6PwOqt8dsCw5j+E=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g=
|
github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g=
|
||||||
|
github.com/tufanbarisyildirim/gonginx v0.0.0-20230104065106-9ae864d29eed h1:EyT9V+boG4nI4pzIuN4AWHQNvyM1LxNS21MC1CDSfg4=
|
||||||
|
github.com/tufanbarisyildirim/gonginx v0.0.0-20230104065106-9ae864d29eed/go.mod h1:+uQMU+LMBHOQermcm/ICplG+r35Ypb6Up9iYKlvKuTE=
|
||||||
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
|
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
|
||||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||||
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
||||||
|
|
|
@ -31,3 +31,17 @@ func TokenizeNginxConfig(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, ngxConfig)
|
c.JSON(http.StatusOK, ngxConfig)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FormatNginxConfig(c *gin.Context) {
|
||||||
|
var json struct {
|
||||||
|
Content string `json:"content" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if !BindAndValid(c, &json) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"content": nginx.FmtCode(json.Content),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||||
|
"github.com/0xJacky/Nginx-UI/template"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -57,3 +62,81 @@ proxy_pass http://127.0.0.1:{{ HTTP01PORT }};
|
||||||
"tokenized": ngxConfig,
|
"tokenized": ngxConfig,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetTemplateConfList(c *gin.Context) {
|
||||||
|
configs, err := template.DistFS.ReadDir("conf")
|
||||||
|
if err != nil {
|
||||||
|
ErrHandler(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
type configItem struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description map[string]string `json:"description"`
|
||||||
|
Author string `json:"author"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var configList []configItem
|
||||||
|
for _, config := range configs {
|
||||||
|
func() {
|
||||||
|
configListItem := configItem{
|
||||||
|
Description: make(map[string]string),
|
||||||
|
}
|
||||||
|
|
||||||
|
file, _ := template.DistFS.Open(filepath.Join("conf", config.Name()))
|
||||||
|
defer file.Close()
|
||||||
|
r := bufio.NewReader(file)
|
||||||
|
bytes, _, err := r.ReadLine()
|
||||||
|
if err == io.EOF {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
line := strings.TrimSpace(string(bytes))
|
||||||
|
|
||||||
|
if line != "# Nginx UI Template Start" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var content string
|
||||||
|
for {
|
||||||
|
bytes, _, err = r.ReadLine()
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
line = strings.TrimSpace(string(bytes))
|
||||||
|
if line == "# Nginx UI Template End" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
content += line + "\n"
|
||||||
|
}
|
||||||
|
re := regexp.MustCompile(`# (\S+): (.*)`)
|
||||||
|
matches := re.FindAllStringSubmatch(content, -1)
|
||||||
|
for _, match := range matches {
|
||||||
|
if len(match) < 3 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
key := match[1]
|
||||||
|
switch {
|
||||||
|
case key == "Name":
|
||||||
|
configListItem.Name = match[2]
|
||||||
|
case key == "Author":
|
||||||
|
configListItem.Author = match[2]
|
||||||
|
case strings.Contains(key, "Description"):
|
||||||
|
re = regexp.MustCompile(`(\w+)\[(\w+)\]`)
|
||||||
|
matches = re.FindAllStringSubmatch(key, -1)
|
||||||
|
for _, m := range matches {
|
||||||
|
if len(m) < 3 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// lang => description
|
||||||
|
configListItem.Description[m[2]] = match[2]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configList = append(configList, configListItem)
|
||||||
|
}()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"data": configList,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -2,9 +2,17 @@ package nginx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/tufanbarisyildirim/gonginx"
|
"github.com/tufanbarisyildirim/gonginx"
|
||||||
|
"github.com/tufanbarisyildirim/gonginx/parser"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *NgxConfig) FmtCode() (fmtContent string) {
|
func (c *NgxConfig) FmtCode() (fmtContent string) {
|
||||||
fmtContent = gonginx.DumpConfig(c.c, gonginx.IndentedStyle)
|
fmtContent = gonginx.DumpConfig(c.c, gonginx.IndentedStyle)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FmtCode(content string) (fmtContent string) {
|
||||||
|
p := parser.NewStringParser(content)
|
||||||
|
c := p.Parse()
|
||||||
|
fmtContent = gonginx.DumpConfig(c, gonginx.IndentedStyle)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -60,6 +60,8 @@ func InitRouter() *gin.Engine {
|
||||||
g.POST("ngx/build_config", api.BuildNginxConfig)
|
g.POST("ngx/build_config", api.BuildNginxConfig)
|
||||||
// Tokenized nginx configuration to NgxConf
|
// Tokenized nginx configuration to NgxConf
|
||||||
g.POST("ngx/tokenize_config", api.TokenizeNginxConfig)
|
g.POST("ngx/tokenize_config", api.TokenizeNginxConfig)
|
||||||
|
// Format nginx configuration code
|
||||||
|
g.POST("ngx/format_code", api.FormatNginxConfig)
|
||||||
|
|
||||||
g.POST("domain/:name/enable", api.EnableDomain)
|
g.POST("domain/:name/enable", api.EnableDomain)
|
||||||
g.POST("domain/:name/disable", api.DisableDomain)
|
g.POST("domain/:name/disable", api.DisableDomain)
|
||||||
|
@ -74,6 +76,7 @@ func InitRouter() *gin.Engine {
|
||||||
//g.GET("backup/:id", api.GetFileBackup)
|
//g.GET("backup/:id", api.GetFileBackup)
|
||||||
|
|
||||||
g.GET("template", api.GetTemplate)
|
g.GET("template", api.GetTemplate)
|
||||||
|
g.GET("template/configs", api.GetTemplateConfList)
|
||||||
|
|
||||||
g.GET("cert/issue", api.IssueCert)
|
g.GET("cert/issue", api.IssueCert)
|
||||||
|
|
||||||
|
|
3
template/block/codeigniter.conf
Normal file
3
template/block/codeigniter.conf
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.php;
|
||||||
|
}
|
3
template/block/laravel.conf
Normal file
3
template/block/laravel.conf
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /server.php?$query_string;
|
||||||
|
}
|
33
template/conf/nginx-ui.conf
Normal file
33
template/conf/nginx-ui.conf
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# Nginx UI Template Start
|
||||||
|
# Name: Nginx UI
|
||||||
|
# Description[en]: Nginx UI Config Template
|
||||||
|
# Description[zh_CN]: Nginx UI 配置模板
|
||||||
|
# Author: @0xJacky
|
||||||
|
# Nginx UI Template End
|
||||||
|
map $http_upgrade $connection_upgrade {
|
||||||
|
default upgrade;
|
||||||
|
'' close;
|
||||||
|
}
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name ;
|
||||||
|
rewrite ^(.*)$ https://$host$1 permanent;
|
||||||
|
}
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
listen [::]:443 ssl http2;
|
||||||
|
server_name ;
|
||||||
|
ssl_certificate ;
|
||||||
|
ssl_certificate_key ;
|
||||||
|
location / {
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
proxy_pass http://127.0.0.1:9000/;
|
||||||
|
}
|
||||||
|
}
|
45
template/conf/wordpress.conf
Normal file
45
template/conf/wordpress.conf
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
# Nginx UI Template Start
|
||||||
|
# Name: WordPress-PHP8.1
|
||||||
|
# Description[en]: WordPress PHP 8.1 Config Template
|
||||||
|
# Description[zh_CN]: WordPress PHP 8.1 配置模板
|
||||||
|
# Author: @0xJacky
|
||||||
|
# Nginx UI Template End
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name ;
|
||||||
|
rewrite ^(.*)$ https://$host$1 permanent;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
listen [::]:443 ssl http2;
|
||||||
|
server_name ;
|
||||||
|
ssl_certificate ;
|
||||||
|
ssl_certificate_key ;
|
||||||
|
root ;
|
||||||
|
index index.php;
|
||||||
|
|
||||||
|
location ~ [^/]\.php(/|$) {
|
||||||
|
try_files $uri =404;
|
||||||
|
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
|
||||||
|
fastcgi_index index.php;
|
||||||
|
include fastcgi.conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.php?$args;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add trailing slash to */wp-admin requests.
|
||||||
|
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
|
||||||
|
|
||||||
|
location /.well-known {
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real_IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
|
||||||
|
proxy_pass http://127.0.0.1:{{ HTTP01PORT }};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,5 +2,5 @@ package template
|
||||||
|
|
||||||
import "embed"
|
import "embed"
|
||||||
|
|
||||||
//go:embed *
|
//go:embed conf/* block/*
|
||||||
var DistFS embed.FS
|
var DistFS embed.FS
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue