mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-11 10:25:52 +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) {
|
||||
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 {message} from 'ant-design-vue'
|
||||
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
|
||||
import ngx from '@/api/ngx'
|
||||
|
||||
const {$gettext, interpolate} = gettext
|
||||
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>
|
||||
|
||||
|
||||
|
@ -54,6 +63,9 @@ function save() {
|
|||
<a-button @click="$router.go(-1)">
|
||||
<translate>Back</translate>
|
||||
</a-button>
|
||||
<a-button @click="format_code">
|
||||
<translate>Format Code</translate>
|
||||
</a-button>
|
||||
<a-button type="primary" @click="save">
|
||||
<translate>Save</translate>
|
||||
</a-button>
|
||||
|
|
4
go.mod
4
go.mod
|
@ -2,8 +2,6 @@ module github.com/0xJacky/Nginx-UI
|
|||
|
||||
go 1.19
|
||||
|
||||
replace github.com/tufanbarisyildirim/gonginx v0.0.0-20220829083426-44da4d61ef9a => github.com/0xJacky/gonginx v0.0.0-20230104051937-4c3a63627efb
|
||||
|
||||
require (
|
||||
github.com/creack/pty v1.1.18
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
|
@ -21,7 +19,7 @@ require (
|
|||
github.com/pkg/errors v0.9.1
|
||||
github.com/shirou/gopsutil/v3 v3.21.7
|
||||
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
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
|
||||
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/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/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/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
||||
|
|
|
@ -1,33 +1,47 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func BuildNginxConfig(c *gin.Context) {
|
||||
var ngxConf nginx.NgxConfig
|
||||
if !BindAndValid(c, &ngxConf) {
|
||||
return
|
||||
}
|
||||
var ngxConf nginx.NgxConfig
|
||||
if !BindAndValid(c, &ngxConf) {
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"content": ngxConf.BuildConfig(),
|
||||
})
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"content": ngxConf.BuildConfig(),
|
||||
})
|
||||
}
|
||||
|
||||
func TokenizeNginxConfig(c *gin.Context) {
|
||||
var json struct {
|
||||
Content string `json:"content" binding:"required"`
|
||||
}
|
||||
var json struct {
|
||||
Content string `json:"content" binding:"required"`
|
||||
}
|
||||
|
||||
if !BindAndValid(c, &json) {
|
||||
return
|
||||
}
|
||||
if !BindAndValid(c, &json) {
|
||||
return
|
||||
}
|
||||
|
||||
ngxConfig := nginx.ParseNgxConfigByContent(json.Content)
|
||||
ngxConfig := nginx.ParseNgxConfigByContent(json.Content)
|
||||
|
||||
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
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||
"github.com/0xJacky/Nginx-UI/template"
|
||||
"github.com/gin-gonic/gin"
|
||||
"io"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -57,3 +62,81 @@ proxy_pass http://127.0.0.1:{{ HTTP01PORT }};
|
|||
"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 (
|
||||
"github.com/tufanbarisyildirim/gonginx"
|
||||
"github.com/tufanbarisyildirim/gonginx/parser"
|
||||
)
|
||||
|
||||
func (c *NgxConfig) FmtCode() (fmtContent string) {
|
||||
fmtContent = gonginx.DumpConfig(c.c, gonginx.IndentedStyle)
|
||||
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)
|
||||
// Tokenized nginx configuration to NgxConf
|
||||
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/disable", api.DisableDomain)
|
||||
|
@ -74,6 +76,7 @@ func InitRouter() *gin.Engine {
|
|||
//g.GET("backup/:id", api.GetFileBackup)
|
||||
|
||||
g.GET("template", api.GetTemplate)
|
||||
g.GET("template/configs", api.GetTemplateConfList)
|
||||
|
||||
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"
|
||||
|
||||
//go:embed *
|
||||
//go:embed conf/* block/*
|
||||
var DistFS embed.FS
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue