From 287ef7527dad19b68267f57b653f8db80ff35a5e Mon Sep 17 00:00:00 2001 From: 0xJacky Date: Wed, 29 Nov 2023 00:08:44 +0800 Subject: [PATCH] refactor: refactor app and api --- .air.toml | 9 +- api/certificate/router.go | 4 +- api/config/add.go | 56 + api/config/config.go | 206 -- api/config/get.go | 51 + api/config/list.go | 69 + api/config/modify.go | 51 + api/cosy/cosy.go | 134 + api/cosy/create.go | 72 + api/cosy/custom.go | 39 + api/cosy/delete.go | 91 + api/cosy/error.go | 23 + api/cosy/list.go | 158 ++ api/cosy/map2struct/hook.go | 56 + api/cosy/map2struct/map2struct.go | 24 + api/cosy/order.go | 42 + api/cosy/update.go | 90 + api/nginx/nginx.go | 11 +- api/openai/openai.go | 45 +- api/openai/store.go | 44 + api/sites/advance.go | 42 + api/sites/auto_cert.go | 64 + api/sites/domain.go | 276 +-- api/sites/duplicate.go | 44 + api/sites/sites.go | 26 + api/template/template.go | 2 +- app/.eslintrc.js | 258 ++ app/components.d.ts | 24 +- app/gettext.config.js | 1 + app/package.json | 12 + app/pnpm-lock.yaml | 2185 ++++++++++++++++- app/src/App.vue | 19 +- app/src/api/analytic.ts | 2 +- app/src/api/auth.ts | 25 +- app/src/api/auto_cert.ts | 27 +- app/src/api/cert.ts | 24 +- app/src/api/config.ts | 11 +- app/src/api/curd.ts | 40 +- app/src/api/dns_credential.ts | 10 +- app/src/api/domain.ts | 47 +- app/src/api/install.ts | 11 +- app/src/api/nginx_log.ts | 5 +- app/src/api/ngx.ts | 41 +- app/src/api/openai.ts | 10 +- app/src/api/settings.ts | 3 +- app/src/api/template.ts | 32 +- app/src/api/upgrade.ts | 6 +- app/src/components/Breadcrumb/Breadcrumb.vue | 32 +- app/src/components/Chart/AreaChart.vue | 103 +- app/src/components/Chart/RadialBarChart.vue | 72 +- .../components/Chart/UsageProgressLine.vue | 27 +- app/src/components/Chart/types.d.ts | 4 + app/src/components/ChatGPT/ChatGPT.vue | 251 +- app/src/components/CodeEditor/CodeEditor.vue | 24 +- app/src/components/CodeEditor/index.ts | 2 +- .../components/EnvIndicator/EnvIndicator.vue | 44 +- .../FooterToolbar/FooterToolBar.vue | 12 +- app/src/components/Logo/Logo.vue | 9 +- .../components/NginxControl/NginxControl.vue | 94 +- .../components/NodeSelector/NodeSelector.vue | 74 +- app/src/components/PageHeader/PageHeader.vue | 22 +- .../components/SetLanguage/SetLanguage.vue | 32 +- .../components/StdDataEntry/StdDataEntry.tsx | 37 - .../StdDataEntry/components/StdSelect.vue | 45 - app/src/components/StdDataEntry/index.tsx | 133 - .../StdDataDisplay/StdBatchEdit.vue | 35 +- .../StdDataDisplay/StdCurd.vue | 95 +- .../StdDataDisplay/StdPagination.vue | 26 +- .../StdDataDisplay/StdTable.vue | 335 +-- .../StdDataDisplay/StdTableTransformer.tsx | 14 +- .../{ => StdDesign}/StdDataDisplay/index.ts | 0 .../StdDesign/StdDataEntry/StdDataEntry.tsx | 54 + .../StdDataEntry/StdFormItem.vue | 34 +- .../StdDataEntry/components/StdPassword.vue | 46 +- .../StdDataEntry/components/StdSelect.vue | 53 + .../StdDataEntry/components/StdSelector.vue | 92 +- .../StdDesign/StdDataEntry/index.tsx | 101 + .../{ => StdDesign}/StdDataEntry/style.less | 0 app/src/components/StdDesign/types.d.ts | 49 + .../SwitchAppearance/SwitchAppearance.vue | 25 +- .../SwitchAppearance/icons/VPIconMoon.vue | 10 +- .../SwitchAppearance/icons/VPIconSun.vue | 30 +- app/src/components/VPSwitch/VPSwitch.vue | 13 +- app/src/gettext.ts | 4 +- app/src/language/constants.ts | 4 +- app/src/layouts/BaseLayout.vue | 93 +- app/src/layouts/BaseRouterView.vue | 10 +- app/src/layouts/FooterLayout.vue | 15 +- app/src/layouts/HeaderLayout.vue | 32 +- app/src/layouts/Loading.vue | 41 +- app/src/layouts/SideBar.vue | 98 +- app/src/lib/helper/index.ts | 48 +- app/src/lib/http/index.ts | 41 +- app/src/lib/websocket/index.ts | 16 +- app/src/main.ts | 12 +- app/src/pinia/index.ts | 6 +- app/src/pinia/moudule/settings.ts | 14 +- app/src/pinia/moudule/user.ts | 10 +- app/src/routes/index.ts | 136 +- app/src/version.json | 2 +- app/src/views/cert/Cert.vue | 140 +- app/src/views/cert/DNSChallenge.vue | 73 +- app/src/views/cert/DNSCredential.vue | 55 +- app/src/views/config/Config.vue | 59 +- app/src/views/config/ConfigEdit.vue | 129 +- app/src/views/config/InspectConfig.vue | 33 +- app/src/views/config/config.ts | 27 +- app/src/views/config/constants.ts | 24 +- app/src/views/dashboard/DashBoard.vue | 4 +- app/src/views/dashboard/Environments.vue | 83 +- app/src/views/dashboard/ServerAnalytic.vue | 348 ++- .../dashboard/components/NodeAnalyticItem.vue | 32 +- app/src/views/domain/DomainAdd.vue | 142 +- app/src/views/domain/DomainEdit.vue | 196 +- app/src/views/domain/DomainList.vue | 135 +- app/src/views/domain/cert/Cert.vue | 38 +- app/src/views/domain/cert/CertInfo.vue | 58 +- app/src/views/domain/cert/ChangeCert.vue | 83 +- app/src/views/domain/cert/IssueCert.vue | 37 +- .../cert/components/AutoCertStepOne.vue | 60 +- .../domain/cert/components/DNSChallenge.vue | 69 +- .../domain/cert/components/ObtainCert.vue | 266 +- app/src/views/domain/components/Deploy.vue | 71 +- .../views/domain/components/RightSettings.vue | 89 +- .../views/domain/components/SiteDuplicate.vue | 100 +- .../views/domain/ngx_conf/LocationEditor.vue | 150 +- app/src/views/domain/ngx_conf/LogEntry.vue | 66 +- .../views/domain/ngx_conf/NgxConfigEditor.vue | 272 +- .../config_template/ConfigTemplate.vue | 99 +- .../ngx_conf/config_template/TemplateForm.vue | 33 +- .../config_template/TemplateFormItem.vue | 46 +- .../ngx_conf/directive/DirectiveAdd.vue | 114 +- .../ngx_conf/directive/DirectiveEditor.vue | 53 +- .../directive/DirectiveEditorItem.vue | 123 +- app/src/views/environment/Environment.vue | 98 +- app/src/views/nginx_log/NginxLog.vue | 106 +- app/src/views/other/Error.vue | 17 +- app/src/views/other/Install.vue | 109 +- app/src/views/other/Login.vue | 98 +- app/src/views/preference/BasicSettings.vue | 59 +- app/src/views/preference/NginxSettings.vue | 24 +- app/src/views/preference/OpenAISettings.vue | 61 +- app/src/views/preference/Preference.vue | 75 +- app/src/views/preference/typedef.ts | 10 +- app/src/views/pty/Terminal.vue | 51 +- app/src/views/system/About.vue | 44 +- app/src/views/system/Upgrade.vue | 174 +- app/src/views/user/User.vue | 28 +- app/src/vite-env.d.ts | 3 +- app/tailwind.config.js | 7 +- app/version.json | 2 +- app/vite.config.ts | 49 +- internal/config/config.go | 17 + internal/config/config_list.go | 59 + internal/config_list/config_list.go | 62 - internal/template/template.go | 34 +- model/model.go | 4 + 157 files changed, 8080 insertions(+), 3551 deletions(-) create mode 100644 api/config/add.go delete mode 100644 api/config/config.go create mode 100644 api/config/get.go create mode 100644 api/config/list.go create mode 100644 api/config/modify.go create mode 100644 api/cosy/cosy.go create mode 100644 api/cosy/create.go create mode 100644 api/cosy/custom.go create mode 100644 api/cosy/delete.go create mode 100644 api/cosy/error.go create mode 100644 api/cosy/list.go create mode 100644 api/cosy/map2struct/hook.go create mode 100644 api/cosy/map2struct/map2struct.go create mode 100644 api/cosy/order.go create mode 100644 api/cosy/update.go create mode 100644 api/openai/store.go create mode 100644 api/sites/advance.go create mode 100644 api/sites/auto_cert.go create mode 100644 api/sites/duplicate.go create mode 100644 api/sites/sites.go create mode 100644 app/.eslintrc.js create mode 100644 app/src/components/Chart/types.d.ts delete mode 100644 app/src/components/StdDataEntry/StdDataEntry.tsx delete mode 100644 app/src/components/StdDataEntry/components/StdSelect.vue delete mode 100644 app/src/components/StdDataEntry/index.tsx rename app/src/components/{ => StdDesign}/StdDataDisplay/StdBatchEdit.vue (69%) rename app/src/components/{ => StdDesign}/StdDataDisplay/StdCurd.vue (71%) rename app/src/components/{ => StdDesign}/StdDataDisplay/StdPagination.vue (65%) rename app/src/components/{ => StdDesign}/StdDataDisplay/StdTable.vue (68%) rename app/src/components/{ => StdDesign}/StdDataDisplay/StdTableTransformer.tsx (54%) rename app/src/components/{ => StdDesign}/StdDataDisplay/index.ts (100%) create mode 100644 app/src/components/StdDesign/StdDataEntry/StdDataEntry.tsx rename app/src/components/{ => StdDesign}/StdDataEntry/StdFormItem.vue (58%) rename app/src/components/{ => StdDesign}/StdDataEntry/components/StdPassword.vue (53%) create mode 100644 app/src/components/StdDesign/StdDataEntry/components/StdSelect.vue rename app/src/components/{ => StdDesign}/StdDataEntry/components/StdSelector.vue (58%) create mode 100644 app/src/components/StdDesign/StdDataEntry/index.tsx rename app/src/components/{ => StdDesign}/StdDataEntry/style.less (100%) create mode 100644 app/src/components/StdDesign/types.d.ts create mode 100644 internal/config/config.go create mode 100644 internal/config/config_list.go delete mode 100644 internal/config_list/config_list.go diff --git a/.air.toml b/.air.toml index 96b8b457..0759b9e4 100644 --- a/.air.toml +++ b/.air.toml @@ -13,11 +13,11 @@ bin = "tmp/main" # Customize binary. full_bin = "APP_ENV=dev APP_USER=air ./tmp/main" # Watch these filename extensions. -include_ext = ["go", "tpl", "tmpl", "html", "toml"] +include_ext = ["go", "tpl", "tmpl", "html", "toml", "po"] # Ignore these filename extensions or directories. -exclude_dir = ["assets", "tmp", "vendor", "app/node_modules", "upload", "docs", "resources", .ts", ".vue", ".tsx", ".idea"] +exclude_dir = ["assets", "tmp", "vendor", "app/node_modules", "upload", "docs", "resources", ".idea"] # Watch these directories if you specified. -include_dir = ["app/src/language"] +include_dir = [] # Exclude files. exclude_file = [] # Exclude specific regular expressions. @@ -51,3 +51,6 @@ runner = "green" [misc] # Delete tmp directory on exit clean_on_exit = true + +[screen] +keep_scroll = true diff --git a/api/certificate/router.go b/api/certificate/router.go index d37e8ce5..157ce10e 100644 --- a/api/certificate/router.go +++ b/api/certificate/router.go @@ -17,6 +17,6 @@ func InitCertificateRouter(r *gin.RouterGroup) { r.POST("cert", AddCert) r.POST("cert/:id", ModifyCert) r.DELETE("cert/:id", RemoveCert) - r.GET("auto_cert/dns/providers", GetDNSProvidersList) - r.GET("auto_cert/dns/provider/:code", GetDNSProvider) + r.GET("certificate/dns_providers", GetDNSProvidersList) + r.GET("certificate/dns_provider/:code", GetDNSProvider) } diff --git a/api/config/add.go b/api/config/add.go new file mode 100644 index 00000000..f2acd817 --- /dev/null +++ b/api/config/add.go @@ -0,0 +1,56 @@ +package config + +import ( + "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/internal/config" + "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/gin-gonic/gin" + "net/http" + "os" +) + +func AddConfig(c *gin.Context) { + var request struct { + Name string `json:"name" binding:"required"` + Content string `json:"content" binding:"required"` + } + + err := c.BindJSON(&request) + if err != nil { + api.ErrHandler(c, err) + return + } + + name := request.Name + content := request.Content + + path := nginx.GetConfPath("/", name) + + if _, err = os.Stat(path); err == nil { + c.JSON(http.StatusNotAcceptable, gin.H{ + "message": "config exist", + }) + return + } + + if content != "" { + err = os.WriteFile(path, []byte(content), 0644) + if err != nil { + api.ErrHandler(c, err) + return + } + } + + output := nginx.Reload() + if nginx.GetLogLevel(output) >= nginx.Warn { + c.JSON(http.StatusInternalServerError, gin.H{ + "message": output, + }) + return + } + + c.JSON(http.StatusOK, config.Config{ + Name: name, + Content: content, + }) +} diff --git a/api/config/config.go b/api/config/config.go deleted file mode 100644 index 08903ac1..00000000 --- a/api/config/config.go +++ /dev/null @@ -1,206 +0,0 @@ -package config - -import ( - "github.com/0xJacky/Nginx-UI/api" - "github.com/0xJacky/Nginx-UI/internal/config_list" - "github.com/0xJacky/Nginx-UI/internal/logger" - nginx2 "github.com/0xJacky/Nginx-UI/internal/nginx" - "github.com/0xJacky/Nginx-UI/query" - "github.com/gin-gonic/gin" - "github.com/sashabaranov/go-openai" - "net/http" - "os" -) - -func GetConfigs(c *gin.Context) { - orderBy := c.Query("order_by") - sort := c.DefaultQuery("sort", "desc") - dir := c.DefaultQuery("dir", "/") - - mySort := map[string]string{ - "name": "string", - "modify": "time", - "is_dir": "bool", - } - - configFiles, err := os.ReadDir(nginx2.GetConfPath(dir)) - - if err != nil { - api.ErrHandler(c, err) - return - } - - var configs []gin.H - - for i := range configFiles { - file := configFiles[i] - fileInfo, _ := file.Info() - - switch mode := fileInfo.Mode(); { - case mode.IsRegular(): // regular file, not a hidden file - if "." == file.Name()[0:1] { - continue - } - case mode&os.ModeSymlink != 0: // is a symbol - var targetPath string - targetPath, err = os.Readlink(nginx2.GetConfPath(file.Name())) - if err != nil { - logger.Error("Read Symlink Error", targetPath, err) - continue - } - - var targetInfo os.FileInfo - targetInfo, err = os.Stat(targetPath) - if err != nil { - logger.Error("Stat Error", targetPath, err) - continue - } - // but target file is not a dir - if targetInfo.IsDir() { - continue - } - } - - configs = append(configs, gin.H{ - "name": file.Name(), - "size": fileInfo.Size(), - "modify": fileInfo.ModTime(), - "is_dir": file.IsDir(), - }) - } - - configs = config_list.Sort(orderBy, sort, mySort[orderBy], configs) - - c.JSON(http.StatusOK, gin.H{ - "data": configs, - }) -} - -func GetConfig(c *gin.Context) { - name := c.Param("name") - path := nginx2.GetConfPath("/", name) - - stat, err := os.Stat(path) - - if err != nil { - api.ErrHandler(c, err) - return - } - - content, err := os.ReadFile(path) - - if err != nil { - api.ErrHandler(c, err) - return - } - - g := query.ChatGPTLog - chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate() - - if err != nil { - api.ErrHandler(c, err) - return - } - - if chatgpt.Content == nil { - chatgpt.Content = make([]openai.ChatCompletionMessage, 0) - } - - c.JSON(http.StatusOK, gin.H{ - "config": string(content), - "chatgpt_messages": chatgpt.Content, - "file_path": path, - "modified_at": stat.ModTime(), - }) - -} - -type AddConfigJson struct { - Name string `json:"name" binding:"required"` - Content string `json:"content" binding:"required"` -} - -func AddConfig(c *gin.Context) { - var request AddConfigJson - err := c.BindJSON(&request) - if err != nil { - api.ErrHandler(c, err) - return - } - - name := request.Name - content := request.Content - - path := nginx2.GetConfPath("/", name) - - if _, err = os.Stat(path); err == nil { - c.JSON(http.StatusNotAcceptable, gin.H{ - "message": "config exist", - }) - return - } - - if content != "" { - err = os.WriteFile(path, []byte(content), 0644) - if err != nil { - api.ErrHandler(c, err) - return - } - } - - output := nginx2.Reload() - if nginx2.GetLogLevel(output) >= nginx2.Warn { - c.JSON(http.StatusInternalServerError, gin.H{ - "message": output, - }) - return - } - - c.JSON(http.StatusOK, gin.H{ - "name": name, - "content": content, - }) - -} - -type EditConfigJson struct { - Content string `json:"content" binding:"required"` -} - -func EditConfig(c *gin.Context) { - name := c.Param("name") - var request EditConfigJson - err := c.BindJSON(&request) - if err != nil { - api.ErrHandler(c, err) - return - } - path := nginx2.GetConfPath("/", name) - content := request.Content - - origContent, err := os.ReadFile(path) - if err != nil { - api.ErrHandler(c, err) - return - } - - if content != "" && content != string(origContent) { - // model.CreateBackup(path) - err = os.WriteFile(path, []byte(content), 0644) - if err != nil { - api.ErrHandler(c, err) - return - } - } - - output := nginx2.Reload() - - if nginx2.GetLogLevel(output) >= nginx2.Warn { - c.JSON(http.StatusInternalServerError, gin.H{ - "message": output, - }) - return - } - - GetConfig(c) -} diff --git a/api/config/get.go b/api/config/get.go new file mode 100644 index 00000000..6d359578 --- /dev/null +++ b/api/config/get.go @@ -0,0 +1,51 @@ +package config + +import ( + "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/internal/config" + "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/0xJacky/Nginx-UI/query" + "github.com/gin-gonic/gin" + "github.com/sashabaranov/go-openai" + "net/http" + "os" +) + +func GetConfig(c *gin.Context) { + name := c.Param("name") + path := nginx.GetConfPath("/", name) + + stat, err := os.Stat(path) + + if err != nil { + api.ErrHandler(c, err) + return + } + + content, err := os.ReadFile(path) + + if err != nil { + api.ErrHandler(c, err) + return + } + + g := query.ChatGPTLog + chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate() + + if err != nil { + api.ErrHandler(c, err) + return + } + + if chatgpt.Content == nil { + chatgpt.Content = make([]openai.ChatCompletionMessage, 0) + } + + c.JSON(http.StatusOK, config.Config{ + Name: name, + Content: string(content), + ChatGPTMessages: chatgpt.Content, + FilePath: path, + ModifiedAt: stat.ModTime(), + }) +} diff --git a/api/config/list.go b/api/config/list.go new file mode 100644 index 00000000..56e767ed --- /dev/null +++ b/api/config/list.go @@ -0,0 +1,69 @@ +package config + +import ( + "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/internal/config" + "github.com/0xJacky/Nginx-UI/internal/logger" + "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/gin-gonic/gin" + "net/http" + "os" +) + +func GetConfigs(c *gin.Context) { + orderBy := c.Query("order_by") + sort := c.DefaultQuery("sort", "desc") + dir := c.DefaultQuery("dir", "/") + + configFiles, err := os.ReadDir(nginx.GetConfPath(dir)) + + if err != nil { + api.ErrHandler(c, err) + return + } + + var configs []config.Config + + for i := range configFiles { + file := configFiles[i] + fileInfo, _ := file.Info() + + switch mode := fileInfo.Mode(); { + case mode.IsRegular(): // regular file, not a hidden file + if "." == file.Name()[0:1] { + continue + } + case mode&os.ModeSymlink != 0: // is a symbol + var targetPath string + targetPath, err = os.Readlink(nginx.GetConfPath(file.Name())) + if err != nil { + logger.Error("Read Symlink Error", targetPath, err) + continue + } + + var targetInfo os.FileInfo + targetInfo, err = os.Stat(targetPath) + if err != nil { + logger.Error("Stat Error", targetPath, err) + continue + } + // but target file is not a dir + if targetInfo.IsDir() { + continue + } + } + + configs = append(configs, config.Config{ + Name: file.Name(), + ModifiedAt: fileInfo.ModTime(), + Size: fileInfo.Size(), + IsDir: fileInfo.IsDir(), + }) + } + + configs = config.Sort(orderBy, sort, configs) + + c.JSON(http.StatusOK, gin.H{ + "data": configs, + }) +} diff --git a/api/config/modify.go b/api/config/modify.go new file mode 100644 index 00000000..70b5a611 --- /dev/null +++ b/api/config/modify.go @@ -0,0 +1,51 @@ +package config + +import ( + "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/gin-gonic/gin" + "net/http" + "os" +) + +type EditConfigJson struct { + Content string `json:"content" binding:"required"` +} + +func EditConfig(c *gin.Context) { + name := c.Param("name") + var request EditConfigJson + err := c.BindJSON(&request) + if err != nil { + api.ErrHandler(c, err) + return + } + path := nginx.GetConfPath("/", name) + content := request.Content + + origContent, err := os.ReadFile(path) + if err != nil { + api.ErrHandler(c, err) + return + } + + if content != "" && content != string(origContent) { + // model.CreateBackup(path) + err = os.WriteFile(path, []byte(content), 0644) + if err != nil { + api.ErrHandler(c, err) + return + } + } + + output := nginx.Reload() + + if nginx.GetLogLevel(output) >= nginx.Warn { + c.JSON(http.StatusInternalServerError, gin.H{ + "message": output, + }) + return + } + + GetConfig(c) +} diff --git a/api/cosy/cosy.go b/api/cosy/cosy.go new file mode 100644 index 00000000..0bbe5cf2 --- /dev/null +++ b/api/cosy/cosy.go @@ -0,0 +1,134 @@ +package cosy + +import ( + "github.com/0xJacky/Nginx-UI/internal/logger" + "github.com/gin-gonic/gin" + "github.com/go-playground/validator/v10" + "gorm.io/gorm" +) + +var validate *validator.Validate + +func init() { + validate = validator.New() +} + +type Ctx[T any] struct { + ctx *gin.Context + rules gin.H + Payload map[string]interface{} + Model T + abort bool + nextHandler *gin.HandlerFunc + beforeDecodeHookFunc []func(ctx *Ctx[T]) + beforeExecuteHookFunc []func(ctx *Ctx[T]) + executedHookFunc []func(ctx *Ctx[T]) + gormScopes []func(tx *gorm.DB) *gorm.DB + preloads []string + scan func(tx *gorm.DB) any + transformer func(*T) any + SelectedFields []string +} + +func Core[T any](c *gin.Context) *Ctx[T] { + return &Ctx[T]{ + ctx: c, + gormScopes: make([]func(tx *gorm.DB) *gorm.DB, 0), + beforeExecuteHookFunc: make([]func(ctx *Ctx[T]), 0), + beforeDecodeHookFunc: make([]func(ctx *Ctx[T]), 0), + } +} + +func (c *Ctx[T]) SetValidRules(rules gin.H) *Ctx[T] { + c.rules = rules + + return c +} + +func (c *Ctx[T]) BeforeDecodeHook(hook ...func(ctx *Ctx[T])) *Ctx[T] { + c.beforeDecodeHookFunc = append(c.beforeDecodeHookFunc, hook...) + return c +} + +func (c *Ctx[T]) BeforeExecuteHook(hook ...func(ctx *Ctx[T])) *Ctx[T] { + c.beforeExecuteHookFunc = append(c.beforeExecuteHookFunc, hook...) + return c +} + +func (c *Ctx[T]) ExecutedHook(hook ...func(ctx *Ctx[T])) *Ctx[T] { + c.executedHookFunc = append(c.executedHookFunc, hook...) + return c +} + +func (c *Ctx[T]) SetPreloads(args ...string) *Ctx[T] { + c.preloads = append(c.preloads, args...) + return c +} + +func (c *Ctx[T]) beforeExecuteHook() { + if len(c.beforeExecuteHookFunc) > 0 { + for _, v := range c.beforeExecuteHookFunc { + v(c) + } + } +} + +func (c *Ctx[T]) beforeDecodeHook() { + if len(c.beforeDecodeHookFunc) > 0 { + for _, v := range c.beforeDecodeHookFunc { + v(c) + } + } +} + +func (c *Ctx[T]) validate() (errs gin.H) { + c.Payload = make(gin.H) + + _ = c.ctx.ShouldBindJSON(&c.Payload) + + errs = validate.ValidateMap(c.Payload, c.rules) + + if len(errs) > 0 { + logger.Debug(errs) + for k := range errs { + errs[k] = c.rules[k] + } + return + } + // Make sure that the key in c.Payload is also the key of rules + validated := make(map[string]interface{}) + + for k, v := range c.Payload { + if _, ok := c.rules[k]; ok { + validated[k] = v + } + } + + c.Payload = validated + + return +} + +func (c *Ctx[T]) SetScan(scan func(tx *gorm.DB) any) *Ctx[T] { + c.scan = scan + return c +} + +func (c *Ctx[T]) SetTransformer(t func(m *T) any) *Ctx[T] { + c.transformer = t + return c +} + +func (c *Ctx[T]) AbortWithError(err error) { + c.abort = true + errHandler(c.ctx, err) +} + +func (c *Ctx[T]) Abort() { + c.abort = true +} + +func (c *Ctx[T]) GormScope(hook func(tx *gorm.DB) *gorm.DB) *Ctx[T] { + c.gormScopes = append(c.gormScopes, hook) + return c +} diff --git a/api/cosy/create.go b/api/cosy/create.go new file mode 100644 index 00000000..65920c15 --- /dev/null +++ b/api/cosy/create.go @@ -0,0 +1,72 @@ +package cosy + +import ( + "github.com/0xJacky/Nginx-UI/api/cosy/map2struct" + "github.com/0xJacky/Nginx-UI/model" + "github.com/gin-gonic/gin" + "gorm.io/gorm/clause" + "net/http" +) + +func (c *Ctx[T]) Create() { + + errs := c.validate() + + if len(errs) > 0 { + c.ctx.JSON(http.StatusNotAcceptable, gin.H{ + "message": "Requested with wrong parameters", + "errors": errs, + }) + return + } + + db := model.UseDB() + + c.beforeDecodeHook() + + if c.abort { + return + } + + err := map2struct.WeakDecode(c.Payload, &c.Model) + + if err != nil { + errHandler(c.ctx, err) + return + } + + c.beforeExecuteHook() + + if c.abort { + return + } + + // skip all associations + err = db.Omit(clause.Associations).Create(&c.Model).Error + + if err != nil { + errHandler(c.ctx, err) + return + } + + tx := db.Preload(clause.Associations) + for _, v := range c.preloads { + tx = tx.Preload(v) + } + tx.First(&c.Model) + + if len(c.executedHookFunc) > 0 { + for _, v := range c.executedHookFunc { + v(c) + + if c.abort { + return + } + } + } + if c.nextHandler != nil { + (*c.nextHandler)(c.ctx) + } else { + c.ctx.JSON(http.StatusOK, c.Model) + } +} diff --git a/api/cosy/custom.go b/api/cosy/custom.go new file mode 100644 index 00000000..66ce714e --- /dev/null +++ b/api/cosy/custom.go @@ -0,0 +1,39 @@ +package cosy + +import ( + "github.com/0xJacky/Nginx-UI/api/cosy/map2struct" + "github.com/gin-gonic/gin" + "net/http" +) + +func (c *Ctx[T]) Custom(fx func(ctx *Ctx[T])) { + if c.abort { + return + } + errs := c.validate() + + if len(errs) > 0 { + c.ctx.JSON(http.StatusNotAcceptable, gin.H{ + "message": "Requested with wrong parameters", + "errors": errs, + }) + return + } + + c.beforeDecodeHook() + + for k := range c.Payload { + c.SelectedFields = append(c.SelectedFields, k) + } + + err := map2struct.WeakDecode(c.Payload, &c.Model) + + if err != nil { + errHandler(c.ctx, err) + return + } + + c.beforeExecuteHook() + + fx(c) +} diff --git a/api/cosy/delete.go b/api/cosy/delete.go new file mode 100644 index 00000000..c2a2cae0 --- /dev/null +++ b/api/cosy/delete.go @@ -0,0 +1,91 @@ +package cosy + +import ( + "github.com/0xJacky/Nginx-UI/model" + "gorm.io/gorm" + "net/http" +) + +func (c *Ctx[T]) Destroy() { + if c.abort { + return + } + id := c.ctx.Param("id") + + c.beforeExecuteHook() + + db := model.UseDB() + var dbModel T + + result := db + if len(c.gormScopes) > 0 { + result = result.Scopes(c.gormScopes...) + } + + err := result.Session(&gorm.Session{}).First(&dbModel, id).Error + + if err != nil { + errHandler(c.ctx, err) + return + } + + err = result.Delete(&dbModel).Error + if err != nil { + errHandler(c.ctx, err) + return + } + + if len(c.executedHookFunc) > 0 { + for _, v := range c.executedHookFunc { + v(c) + + if c.abort { + return + } + } + } + + c.ctx.JSON(http.StatusNoContent, nil) +} + +func (c *Ctx[T]) Recover() { + if c.abort { + return + } + id := c.ctx.Param("id") + + c.beforeExecuteHook() + + db := model.UseDB() + var dbModel T + + result := db.Unscoped() + if len(c.gormScopes) > 0 { + result = result.Scopes(c.gormScopes...) + } + + err := result.Session(&gorm.Session{}).First(&dbModel, id).Error + + if err != nil { + errHandler(c.ctx, err) + return + } + + err = result.Model(&dbModel).Update("deleted_at", nil).Error + if err != nil { + errHandler(c.ctx, err) + return + } + + if len(c.executedHookFunc) > 0 { + for _, v := range c.executedHookFunc { + v(c) + + if c.abort { + return + } + } + } + + c.ctx.JSON(http.StatusNoContent, nil) +} diff --git a/api/cosy/error.go b/api/cosy/error.go new file mode 100644 index 00000000..caa5a5ba --- /dev/null +++ b/api/cosy/error.go @@ -0,0 +1,23 @@ +package cosy + +import ( + "errors" + "github.com/0xJacky/Nginx-UI/internal/logger" + "github.com/gin-gonic/gin" + "go.uber.org/zap" + "gorm.io/gorm" + "net/http" +) + +func errHandler(c *gin.Context, err error) { + logger.GetLogger().WithOptions(zap.AddCallerSkip(1)).Errorln(err) + if errors.Is(err, gorm.ErrRecordNotFound) { + c.JSON(http.StatusNotFound, gin.H{ + "message": err.Error(), + }) + return + } + c.JSON(http.StatusInternalServerError, gin.H{ + "message": err.Error(), + }) +} diff --git a/api/cosy/list.go b/api/cosy/list.go new file mode 100644 index 00000000..12663c85 --- /dev/null +++ b/api/cosy/list.go @@ -0,0 +1,158 @@ +package cosy + +import ( + "github.com/0xJacky/Nginx-UI/internal/logger" + "github.com/0xJacky/Nginx-UI/model" + "github.com/0xJacky/Nginx-UI/settings" + "github.com/spf13/cast" + "gorm.io/gorm" + "net/http" +) + +func (c *Ctx[T]) SetFussy(keys ...string) *Ctx[T] { + c.gormScopes = append(c.gormScopes, func(tx *gorm.DB) *gorm.DB { + return model.QueryToFussySearch(c.ctx, tx, keys...) + }) + return c +} + +func (c *Ctx[T]) SetFussyKeys(value string, keys ...string) *Ctx[T] { + c.gormScopes = append(c.gormScopes, func(tx *gorm.DB) *gorm.DB { + return model.QueryToFussyKeysSearch(c.ctx, tx, value, keys...) + }) + return c +} + +func (c *Ctx[T]) SetEqual(keys ...string) *Ctx[T] { + c.gormScopes = append(c.gormScopes, func(tx *gorm.DB) *gorm.DB { + return model.QueryToEqualSearch(c.ctx, tx, keys...) + }) + return c +} + +func (c *Ctx[T]) SetIn(keys ...string) *Ctx[T] { + c.gormScopes = append(c.gormScopes, func(tx *gorm.DB) *gorm.DB { + return model.QueryToInSearch(c.ctx, tx, keys...) + }) + return c +} + +func (c *Ctx[T]) SetOrFussy(keys ...string) *Ctx[T] { + c.gormScopes = append(c.gormScopes, func(tx *gorm.DB) *gorm.DB { + return model.QueryToOrFussySearch(c.ctx, tx, keys...) + }) + return c +} + +func (c *Ctx[T]) SetOrEqual(keys ...string) *Ctx[T] { + c.gormScopes = append(c.gormScopes, func(tx *gorm.DB) *gorm.DB { + return model.QueryToOrEqualSearch(c.ctx, tx, keys...) + }) + return c +} + +func (c *Ctx[T]) SetOrIn(keys ...string) *Ctx[T] { + c.gormScopes = append(c.gormScopes, func(tx *gorm.DB) *gorm.DB { + return model.QueryToOrInSearch(c.ctx, tx, keys...) + }) + return c +} + +func (c *Ctx[T]) result() (*gorm.DB, bool) { + for _, v := range c.preloads { + t := v + c.GormScope(func(tx *gorm.DB) *gorm.DB { + tx = tx.Preload(t) + return tx + }) + } + + c.beforeExecuteHook() + + var dbModel T + result := model.UseDB() + + if c.ctx.Query("trash") == "true" { + stmt := &gorm.Statement{DB: model.UseDB()} + err := stmt.Parse(&dbModel) + if err != nil { + logger.Error(err) + return nil, false + } + result = result.Unscoped().Where(stmt.Schema.Table + ".deleted_at IS NOT NULL") + } + + result = result.Model(&dbModel) + + if len(c.gormScopes) > 0 { + result = result.Scopes(c.gormScopes...) + } + + return result, true +} + +func (c *Ctx[T]) ListAllData() ([]*T, bool) { + result, ok := c.result() + if !ok { + return nil, false + } + + result = result.Scopes(model.SortOrder(c.ctx)) + models := make([]*T, 0) + result.Find(&models) + return models, true +} + +func (c *Ctx[T]) PagingListData() (*model.DataList, bool) { + result, ok := c.result() + if !ok { + return nil, false + } + + result = result.Scopes(model.OrderAndPaginate(c.ctx)) + data := &model.DataList{} + if c.scan == nil { + models := make([]*T, 0) + result.Find(&models) + + if c.transformer != nil { + transformed := make([]any, 0) + for k := range models { + transformed = append(transformed, c.transformer(models[k])) + } + data.Data = transformed + } else { + data.Data = models + } + } else { + data.Data = c.scan(result) + } + + page := cast.ToInt(c.ctx.Query("page")) + if page == 0 { + page = 1 + } + + pageSize := settings.AppSettings.PageSize + if reqPageSize := c.ctx.Query("page_size"); reqPageSize != "" { + pageSize = cast.ToInt(reqPageSize) + } + + var totalRecords int64 + result.Session(&gorm.Session{}).Count(&totalRecords) + + data.Pagination = model.Pagination{ + Total: totalRecords, + PerPage: pageSize, + CurrentPage: page, + TotalPages: model.TotalPage(totalRecords, pageSize), + } + return data, true +} + +func (c *Ctx[T]) PagingList() { + data, ok := c.PagingListData() + if ok { + c.ctx.JSON(http.StatusOK, data) + } +} diff --git a/api/cosy/map2struct/hook.go b/api/cosy/map2struct/hook.go new file mode 100644 index 00000000..67010b09 --- /dev/null +++ b/api/cosy/map2struct/hook.go @@ -0,0 +1,56 @@ +package map2struct + +import ( + "github.com/mitchellh/mapstructure" + "github.com/shopspring/decimal" + "github.com/spf13/cast" + "reflect" + "time" +) + +var timeLocation *time.Location + +func init() { + timeLocation = time.Local +} + +func ToTimeHookFunc() mapstructure.DecodeHookFunc { + return func( + f reflect.Type, + t reflect.Type, + data interface{}) (interface{}, error) { + if t != reflect.TypeOf(time.Time{}) { + return data, nil + } + + switch f.Kind() { + case reflect.String: + return cast.ToTimeInDefaultLocationE(data, timeLocation) + case reflect.Float64: + return time.Unix(0, int64(data.(float64))*int64(time.Millisecond)), nil + case reflect.Int64: + return time.Unix(0, data.(int64)*int64(time.Millisecond)), nil + default: + return data, nil + } + // Convert it by parsing + } +} + +func ToDecimalHookFunc() mapstructure.DecodeHookFunc { + return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { + + if t == reflect.TypeOf(decimal.Decimal{}) { + if f.Kind() == reflect.Float64 { + return decimal.NewFromFloat(data.(float64)), nil + } + + if input := data.(string); input != "" { + return decimal.NewFromString(data.(string)) + } + return decimal.Decimal{}, nil + } + + return data, nil + } +} diff --git a/api/cosy/map2struct/map2struct.go b/api/cosy/map2struct/map2struct.go new file mode 100644 index 00000000..34373644 --- /dev/null +++ b/api/cosy/map2struct/map2struct.go @@ -0,0 +1,24 @@ +package map2struct + +import ( + "github.com/mitchellh/mapstructure" +) + +func WeakDecode(input, output interface{}) error { + config := &mapstructure.DecoderConfig{ + Metadata: nil, + Result: output, + WeaklyTypedInput: true, + DecodeHook: mapstructure.ComposeDecodeHookFunc( + ToDecimalHookFunc(), ToTimeHookFunc(), + ), + TagName: "json", + } + + decoder, err := mapstructure.NewDecoder(config) + if err != nil { + return err + } + + return decoder.Decode(input) +} diff --git a/api/cosy/order.go b/api/cosy/order.go new file mode 100644 index 00000000..174325f2 --- /dev/null +++ b/api/cosy/order.go @@ -0,0 +1,42 @@ +package cosy + +import ( + "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/model" + "gorm.io/gorm" + "net/http" +) + +func (c *Ctx[T]) UpdateOrder() { + var json struct { + TargetID int `json:"target_id"` + Direction int `json:"direction" binding:"oneof=-1 1"` + AffectedIDs []int `json:"affected_ids"` + } + + if !api.BindAndValid(c.ctx, &json) { + return + } + + affectedLen := len(json.AffectedIDs) + + db := model.UseDB() + + // update target + err := db.Model(&c.Model).Where("id = ?", json.TargetID).Update("order_id", gorm.Expr("order_id + ?", affectedLen*(-json.Direction))).Error + + if err != nil { + api.ErrHandler(c.ctx, err) + return + } + + // update affected + err = db.Model(&c.Model).Where("id in ?", json.AffectedIDs).Update("order_id", gorm.Expr("order_id + ?", json.Direction)).Error + + if err != nil { + api.ErrHandler(c.ctx, err) + return + } + + c.ctx.JSON(http.StatusOK, json) +} diff --git a/api/cosy/update.go b/api/cosy/update.go new file mode 100644 index 00000000..7126ef1b --- /dev/null +++ b/api/cosy/update.go @@ -0,0 +1,90 @@ +package cosy + +import ( + "github.com/0xJacky/Nginx-UI/api/cosy/map2struct" + "github.com/0xJacky/Nginx-UI/model" + "github.com/gin-gonic/gin" + "gorm.io/gorm" + "net/http" +) + +func (c *Ctx[T]) SetNextHandler(handler gin.HandlerFunc) *Ctx[T] { + c.nextHandler = &handler + return c +} + +func (c *Ctx[T]) Modify() { + if c.abort { + return + } + id := c.ctx.Param("id") + errs := c.validate() + + if len(errs) > 0 { + c.ctx.JSON(http.StatusNotAcceptable, gin.H{ + "message": "Requested with wrong parameters", + "errors": errs, + }) + return + } + + db := model.UseDB() + + result := db + if len(c.gormScopes) > 0 { + result = result.Scopes(c.gormScopes...) + } + + err := result.Session(&gorm.Session{}).First(&c.Model, id).Error + + if err != nil { + c.AbortWithError(err) + return + } + + c.beforeDecodeHook() + if c.abort { + return + } + + var selectedFields []string + + for k := range c.Payload { + selectedFields = append(selectedFields, k) + } + + err = map2struct.WeakDecode(c.Payload, &c.Model) + + if err != nil { + errHandler(c.ctx, err) + return + } + + c.beforeExecuteHook() + if c.abort { + return + } + + err = db.Model(&c.Model).Select(selectedFields).Updates(&c.Model).Error + + if err != nil { + c.AbortWithError(err) + return + } + + if len(c.executedHookFunc) > 0 { + for _, v := range c.executedHookFunc { + v(c) + + if c.abort { + return + } + } + } + + if c.nextHandler != nil { + (*c.nextHandler)(c.ctx) + } else { + c.ctx.JSON(http.StatusOK, c.Model) + } +} diff --git a/api/nginx/nginx.go b/api/nginx/nginx.go index 76a84c67..1a492056 100644 --- a/api/nginx/nginx.go +++ b/api/nginx/nginx.go @@ -2,14 +2,14 @@ package nginx import ( "github.com/0xJacky/Nginx-UI/api" - nginx2 "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/gin-gonic/gin" "net/http" "os" ) func BuildNginxConfig(c *gin.Context) { - var ngxConf nginx2.NgxConfig + var ngxConf nginx.NgxConfig if !api.BindAndValid(c, &ngxConf) { return } @@ -29,7 +29,7 @@ func TokenizeNginxConfig(c *gin.Context) { } c.Set("maybe_error", "nginx_config_syntax_error") - ngxConfig := nginx2.ParseNgxConfigByContent(json.Content) + ngxConfig := nginx.ParseNgxConfigByContent(json.Content) c.JSON(http.StatusOK, ngxConfig) @@ -46,12 +46,12 @@ func FormatNginxConfig(c *gin.Context) { c.Set("maybe_error", "nginx_config_syntax_error") c.JSON(http.StatusOK, gin.H{ - "content": nginx2.FmtCode(json.Content), + "content": nginx.FmtCode(json.Content), }) } func Status(c *gin.Context) { - pidPath := nginx2.GetNginxPIDPath() + pidPath := nginx.GetNginxPIDPath() running := true if fileInfo, err := os.Stat(pidPath); err != nil || fileInfo.Size() == 0 { // fileInfo.Size() == 0 no process id @@ -62,4 +62,3 @@ func Status(c *gin.Context) { "running": running, }) } - diff --git a/api/openai/openai.go b/api/openai/openai.go index 3a042988..6e15bca6 100644 --- a/api/openai/openai.go +++ b/api/openai/openai.go @@ -2,10 +2,9 @@ package openai import ( "context" + "crypto/tls" "fmt" "github.com/0xJacky/Nginx-UI/api" - "github.com/0xJacky/Nginx-UI/model" - "github.com/0xJacky/Nginx-UI/query" "github.com/0xJacky/Nginx-UI/settings" "github.com/gin-gonic/gin" "github.com/pkg/errors" @@ -35,7 +34,7 @@ func MakeChatCompletionRequest(c *gin.Context) { } messages = append(messages, json.Messages...) // sse server - c.Writer.Header().Set("Content-Type", "text/event-stream") + c.Writer.Header().Set("Content-Type", "text/event-stream; charset=utf-8") c.Writer.Header().Set("Cache-Control", "no-cache") c.Writer.Header().Set("Connection", "keep-alive") c.Writer.Header().Set("Access-Control-Allow-Origin", "*") @@ -66,7 +65,8 @@ func MakeChatCompletionRequest(c *gin.Context) { return } transport := &http.Transport{ - Proxy: http.ProxyURL(proxyUrl), + Proxy: http.ProxyURL(proxyUrl), + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } config.HTTPClient = &http.Client{ Transport: transport, @@ -100,17 +100,16 @@ func MakeChatCompletionRequest(c *gin.Context) { defer stream.Close() msgChan := make(chan string) go func() { + defer close(msgChan) for { response, err := stream.Recv() if errors.Is(err, io.EOF) { - close(msgChan) fmt.Println() return } if err != nil { fmt.Printf("Stream error: %v\n", err) - close(msgChan) return } @@ -133,37 +132,3 @@ func MakeChatCompletionRequest(c *gin.Context) { return false }) } - -func StoreChatGPTRecord(c *gin.Context) { - var json struct { - FileName string `json:"file_name"` - Messages []openai.ChatCompletionMessage `json:"messages"` - } - - if !api.BindAndValid(c, &json) { - return - } - - name := json.FileName - g := query.ChatGPTLog - _, err := g.Where(g.Name.Eq(name)).FirstOrCreate() - - if err != nil { - api.ErrHandler(c, err) - return - } - - _, err = g.Where(g.Name.Eq(name)).Updates(&model.ChatGPTLog{ - Name: name, - Content: json.Messages, - }) - - if err != nil { - api.ErrHandler(c, err) - return - } - - c.JSON(http.StatusOK, gin.H{ - "message": "ok", - }) -} diff --git a/api/openai/store.go b/api/openai/store.go new file mode 100644 index 00000000..75e2b3ed --- /dev/null +++ b/api/openai/store.go @@ -0,0 +1,44 @@ +package openai + +import ( + "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/model" + "github.com/0xJacky/Nginx-UI/query" + "github.com/gin-gonic/gin" + "github.com/sashabaranov/go-openai" + "net/http" +) + +func StoreChatGPTRecord(c *gin.Context) { + var json struct { + FileName string `json:"file_name"` + Messages []openai.ChatCompletionMessage `json:"messages"` + } + + if !api.BindAndValid(c, &json) { + return + } + + name := json.FileName + g := query.ChatGPTLog + _, err := g.Where(g.Name.Eq(name)).FirstOrCreate() + + if err != nil { + api.ErrHandler(c, err) + return + } + + _, err = g.Where(g.Name.Eq(name)).Updates(&model.ChatGPTLog{ + Name: name, + Content: json.Messages, + }) + + if err != nil { + api.ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + }) +} diff --git a/api/sites/advance.go b/api/sites/advance.go new file mode 100644 index 00000000..e3d5807b --- /dev/null +++ b/api/sites/advance.go @@ -0,0 +1,42 @@ +package sites + +import ( + "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/0xJacky/Nginx-UI/query" + "github.com/gin-gonic/gin" + "net/http" +) + +func DomainEditByAdvancedMode(c *gin.Context) { + var json struct { + Advanced bool `json:"advanced"` + } + + if !api.BindAndValid(c, &json) { + return + } + + name := c.Param("name") + path := nginx.GetConfPath("sites-available", name) + + s := query.Site + + _, err := s.Where(s.Path.Eq(path)).FirstOrCreate() + if err != nil { + api.ErrHandler(c, err) + return + } + + _, err = s.Where(s.Path.Eq(path)).Update(s.Advanced, json.Advanced) + + if err != nil { + api.ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + }) + +} diff --git a/api/sites/auto_cert.go b/api/sites/auto_cert.go new file mode 100644 index 00000000..2319ff82 --- /dev/null +++ b/api/sites/auto_cert.go @@ -0,0 +1,64 @@ +package sites + +import ( + "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/model" + "github.com/gin-gonic/gin" + "net/http" +) + +func AddDomainToAutoCert(c *gin.Context) { + name := c.Param("name") + + var json struct { + DnsCredentialID int `json:"dns_credential_id"` + ChallengeMethod string `json:"challenge_method"` + Domains []string `json:"domains"` + } + + if !api.BindAndValid(c, &json) { + return + } + + certModel, err := model.FirstOrCreateCert(name) + + if err != nil { + api.ErrHandler(c, err) + return + } + + err = certModel.Updates(&model.Cert{ + Name: name, + Domains: json.Domains, + AutoCert: model.AutoCertEnabled, + DnsCredentialID: json.DnsCredentialID, + ChallengeMethod: json.ChallengeMethod, + }) + + if err != nil { + api.ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, certModel) +} + +func RemoveDomainFromAutoCert(c *gin.Context) { + name := c.Param("name") + certModel, err := model.FirstCert(name) + + if err != nil { + api.ErrHandler(c, err) + return + } + + err = certModel.Updates(&model.Cert{ + AutoCert: model.AutoCertDisabled, + }) + + if err != nil { + api.ErrHandler(c, err) + return + } + c.JSON(http.StatusOK, nil) +} diff --git a/api/sites/domain.go b/api/sites/domain.go index ac007635..bcca006a 100644 --- a/api/sites/domain.go +++ b/api/sites/domain.go @@ -1,20 +1,19 @@ package sites import ( - "github.com/0xJacky/Nginx-UI/api" - "github.com/0xJacky/Nginx-UI/internal/cert" - "github.com/0xJacky/Nginx-UI/internal/config_list" - helper2 "github.com/0xJacky/Nginx-UI/internal/helper" - "github.com/0xJacky/Nginx-UI/internal/logger" - nginx2 "github.com/0xJacky/Nginx-UI/internal/nginx" - "github.com/0xJacky/Nginx-UI/model" - "github.com/0xJacky/Nginx-UI/query" - "github.com/gin-gonic/gin" - "github.com/sashabaranov/go-openai" - "net/http" - "os" - "strings" - "time" + "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/internal/cert" + "github.com/0xJacky/Nginx-UI/internal/config" + "github.com/0xJacky/Nginx-UI/internal/helper" + "github.com/0xJacky/Nginx-UI/internal/logger" + "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/0xJacky/Nginx-UI/model" + "github.com/0xJacky/Nginx-UI/query" + "github.com/gin-gonic/gin" + "github.com/sashabaranov/go-openai" + "net/http" + "os" + "strings" ) func GetDomains(c *gin.Context) { @@ -22,20 +21,14 @@ func GetDomains(c *gin.Context) { orderBy := c.Query("order_by") sort := c.DefaultQuery("sort", "desc") - mySort := map[string]string{ - "enabled": "bool", - "name": "string", - "modify": "time", - } - - configFiles, err := os.ReadDir(nginx2.GetConfPath("sites-available")) + configFiles, err := os.ReadDir(nginx.GetConfPath("sites-available")) if err != nil { api.ErrHandler(c, err) return } - enabledConfig, err := os.ReadDir(nginx2.GetConfPath("sites-enabled")) + enabledConfig, err := os.ReadDir(nginx.GetConfPath("sites-enabled")) if err != nil { api.ErrHandler(c, err) @@ -47,7 +40,7 @@ func GetDomains(c *gin.Context) { enabledConfigMap[enabledConfig[i].Name()] = true } - var configs []gin.H + var configs []config.Config for i := range configFiles { file := configFiles[i] @@ -56,29 +49,23 @@ func GetDomains(c *gin.Context) { if name != "" && !strings.Contains(file.Name(), name) { continue } - configs = append(configs, gin.H{ - "name": file.Name(), - "size": fileInfo.Size(), - "modify": fileInfo.ModTime(), - "enabled": enabledConfigMap[file.Name()], + configs = append(configs, config.Config{ + Name: file.Name(), + ModifiedAt: fileInfo.ModTime(), + Size: fileInfo.Size(), + IsDir: fileInfo.IsDir(), + Enabled: enabledConfigMap[file.Name()], }) } } - configs = config_list.Sort(orderBy, sort, mySort[orderBy], configs) + configs = config.Sort(orderBy, sort, configs) c.JSON(http.StatusOK, gin.H{ "data": configs, }) } -type CertificateInfo struct { - SubjectName string `json:"subject_name"` - IssuerName string `json:"issuer_name"` - NotAfter time.Time `json:"not_after"` - NotBefore time.Time `json:"not_before"` -} - func GetDomain(c *gin.Context) { rewriteName, ok := c.Get("rewriteConfigFileName") @@ -89,7 +76,7 @@ func GetDomain(c *gin.Context) { name = rewriteName.(string) } - path := nginx2.GetConfPath("sites-available", name) + path := nginx.GetConfPath("sites-available", name) file, err := os.Stat(path) if os.IsNotExist(err) { c.JSON(http.StatusNotFound, gin.H{ @@ -100,7 +87,7 @@ func GetDomain(c *gin.Context) { enabled := true - if _, err := os.Stat(nginx2.GetConfPath("sites-enabled", name)); os.IsNotExist(err) { + if _, err := os.Stat(nginx.GetConfPath("sites-enabled", name)); os.IsNotExist(err) { enabled = false } @@ -127,7 +114,7 @@ func GetDomain(c *gin.Context) { certModel, err := model.FirstCert(name) if err != nil { - logger.Warn("cert", err) + logger.Warn(err) } if site.Advanced { @@ -137,20 +124,20 @@ func GetDomain(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{ - "modified_at": file.ModTime(), - "advanced": site.Advanced, - "enabled": enabled, - "name": name, - "config": string(origContent), - "auto_cert": certModel.AutoCert == model.AutoCertEnabled, - "chatgpt_messages": chatgpt.Content, + c.JSON(http.StatusOK, Site{ + ModifiedAt: file.ModTime(), + Advanced: site.Advanced, + Enabled: enabled, + Name: name, + Config: string(origContent), + AutoCert: certModel.AutoCert == model.AutoCertEnabled, + ChatGPTMessages: chatgpt.Content, }) return } c.Set("maybe_error", "nginx_config_syntax_error") - config, err := nginx2.ParseNgxConfig(path) + nginxConfig, err := nginx.ParseNgxConfig(path) if err != nil { api.ErrHandler(c, err) @@ -160,7 +147,7 @@ func GetDomain(c *gin.Context) { c.Set("maybe_error", "") certInfoMap := make(map[int]CertificateInfo) - for serverIdx, server := range config.Servers { + for serverIdx, server := range nginxConfig.Servers { for _, directive := range server.Directives { if directive.Directive == "ssl_certificate" { @@ -185,18 +172,17 @@ func GetDomain(c *gin.Context) { c.Set("maybe_error", "nginx_config_syntax_error") - c.JSON(http.StatusOK, gin.H{ - "modified_at": file.ModTime(), - "advanced": site.Advanced, - "enabled": enabled, - "name": name, - "config": config.FmtCode(), - "tokenized": config, - "auto_cert": certModel.AutoCert == model.AutoCertEnabled, - "cert_info": certInfoMap, - "chatgpt_messages": chatgpt.Content, + c.JSON(http.StatusOK, Site{ + ModifiedAt: file.ModTime(), + Advanced: site.Advanced, + Enabled: enabled, + Name: name, + Config: nginxConfig.FmtCode(), + Tokenized: nginxConfig, + AutoCert: certModel.AutoCert == model.AutoCertEnabled, + CertInfo: certInfoMap, + ChatGPTMessages: chatgpt.Content, }) - } func SaveDomain(c *gin.Context) { @@ -219,9 +205,9 @@ func SaveDomain(c *gin.Context) { return } - path := nginx2.GetConfPath("sites-available", name) + path := nginx.GetConfPath("sites-available", name) - if !json.Overwrite && helper2.FileExists(path) { + if !json.Overwrite && helper.FileExists(path) { c.JSON(http.StatusNotAcceptable, gin.H{ "message": "File exists", }) @@ -233,24 +219,24 @@ func SaveDomain(c *gin.Context) { api.ErrHandler(c, err) return } - enabledConfigFilePath := nginx2.GetConfPath("sites-enabled", name) + enabledConfigFilePath := nginx.GetConfPath("sites-enabled", name) // rename the config file if needed if name != json.Name { - newPath := nginx2.GetConfPath("sites-available", json.Name) + newPath := nginx.GetConfPath("sites-available", json.Name) s := query.Site _, err = s.Where(s.Path.Eq(path)).Update(s.Path, newPath) // check if dst file exists, do not rename - if helper2.FileExists(newPath) { + if helper.FileExists(newPath) { c.JSON(http.StatusNotAcceptable, gin.H{ "message": "File exists", }) return } // recreate soft link - if helper2.FileExists(enabledConfigFilePath) { + if helper.FileExists(enabledConfigFilePath) { _ = os.Remove(enabledConfigFilePath) - enabledConfigFilePath = nginx2.GetConfPath("sites-enabled", json.Name) + enabledConfigFilePath = nginx.GetConfPath("sites-enabled", json.Name) err = os.Symlink(newPath, enabledConfigFilePath) if err != nil { @@ -269,12 +255,12 @@ func SaveDomain(c *gin.Context) { c.Set("rewriteConfigFileName", name) } - enabledConfigFilePath = nginx2.GetConfPath("sites-enabled", name) - if helper2.FileExists(enabledConfigFilePath) { + enabledConfigFilePath = nginx.GetConfPath("sites-enabled", name) + if helper.FileExists(enabledConfigFilePath) { // Test nginx configuration - output := nginx2.TestConf() + output := nginx.TestConf() - if nginx2.GetLogLevel(output) > nginx2.Warn { + if nginx.GetLogLevel(output) > nginx.Warn { c.JSON(http.StatusInternalServerError, gin.H{ "message": output, "error": "nginx_config_syntax_error", @@ -282,9 +268,9 @@ func SaveDomain(c *gin.Context) { return } - output = nginx2.Reload() + output = nginx.Reload() - if nginx2.GetLogLevel(output) > nginx2.Warn { + if nginx.GetLogLevel(output) > nginx.Warn { c.JSON(http.StatusInternalServerError, gin.H{ "message": output, }) @@ -296,8 +282,8 @@ func SaveDomain(c *gin.Context) { } func EnableDomain(c *gin.Context) { - configFilePath := nginx2.GetConfPath("sites-available", c.Param("name")) - enabledConfigFilePath := nginx2.GetConfPath("sites-enabled", c.Param("name")) + configFilePath := nginx.GetConfPath("sites-available", c.Param("name")) + enabledConfigFilePath := nginx.GetConfPath("sites-enabled", c.Param("name")) _, err := os.Stat(configFilePath) @@ -316,9 +302,9 @@ func EnableDomain(c *gin.Context) { } // Test nginx config, if not pass then disable the site. - output := nginx2.TestConf() + output := nginx.TestConf() - if nginx2.GetLogLevel(output) > nginx2.Warn { + if nginx.GetLogLevel(output) > nginx.Warn { _ = os.Remove(enabledConfigFilePath) c.JSON(http.StatusInternalServerError, gin.H{ "message": output, @@ -326,9 +312,9 @@ func EnableDomain(c *gin.Context) { return } - output = nginx2.Reload() + output = nginx.Reload() - if nginx2.GetLogLevel(output) > nginx2.Warn { + if nginx.GetLogLevel(output) > nginx.Warn { c.JSON(http.StatusInternalServerError, gin.H{ "message": output, }) @@ -341,7 +327,7 @@ func EnableDomain(c *gin.Context) { } func DisableDomain(c *gin.Context) { - enabledConfigFilePath := nginx2.GetConfPath("sites-enabled", c.Param("name")) + enabledConfigFilePath := nginx.GetConfPath("sites-enabled", c.Param("name")) _, err := os.Stat(enabledConfigFilePath) @@ -365,9 +351,9 @@ func DisableDomain(c *gin.Context) { return } - output := nginx2.Reload() + output := nginx.Reload() - if nginx2.GetLogLevel(output) > nginx2.Warn { + if nginx.GetLogLevel(output) > nginx.Warn { c.JSON(http.StatusInternalServerError, gin.H{ "message": output, }) @@ -382,8 +368,8 @@ func DisableDomain(c *gin.Context) { func DeleteDomain(c *gin.Context) { var err error name := c.Param("name") - availablePath := nginx2.GetConfPath("sites-available", name) - enabledPath := nginx2.GetConfPath("sites-enabled", name) + availablePath := nginx.GetConfPath("sites-available", name) + enabledPath := nginx.GetConfPath("sites-enabled", name) if _, err = os.Stat(availablePath); os.IsNotExist(err) { c.JSON(http.StatusNotFound, gin.H{ @@ -412,126 +398,4 @@ func DeleteDomain(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "message": "ok", }) - -} - -func AddDomainToAutoCert(c *gin.Context) { - name := c.Param("name") - - var json struct { - model.Cert - Domains []string `json:"domains"` - } - - if !api.BindAndValid(c, &json) { - return - } - - certModel, err := model.FirstOrCreateCert(name) - - if err != nil { - api.ErrHandler(c, err) - return - } - - err = certModel.Updates(&model.Cert{ - Name: name, - Domains: json.Domains, - AutoCert: model.AutoCertEnabled, - DnsCredentialID: json.DnsCredentialID, - ChallengeMethod: json.ChallengeMethod, - }) - - if err != nil { - api.ErrHandler(c, err) - return - } - - c.JSON(http.StatusOK, certModel) -} - -func RemoveDomainFromAutoCert(c *gin.Context) { - name := c.Param("name") - certModel, err := model.FirstCert(name) - - if err != nil { - api.ErrHandler(c, err) - return - } - - err = certModel.Updates(&model.Cert{ - AutoCert: model.AutoCertDisabled, - }) - - if err != nil { - api.ErrHandler(c, err) - return - } - c.JSON(http.StatusOK, nil) -} - -func DuplicateSite(c *gin.Context) { - name := c.Param("name") - - var json struct { - Name string `json:"name" binding:"required"` - } - - if !api.BindAndValid(c, &json) { - return - } - - src := nginx2.GetConfPath("sites-available", name) - dst := nginx2.GetConfPath("sites-available", json.Name) - - if helper2.FileExists(dst) { - c.JSON(http.StatusNotAcceptable, gin.H{ - "message": "File exists", - }) - return - } - - _, err := helper2.CopyFile(src, dst) - - if err != nil { - api.ErrHandler(c, err) - return - } - - c.JSON(http.StatusOK, gin.H{ - "dst": dst, - }) -} - -func DomainEditByAdvancedMode(c *gin.Context) { - var json struct { - Advanced bool `json:"advanced"` - } - - if !api.BindAndValid(c, &json) { - return - } - - name := c.Param("name") - path := nginx2.GetConfPath("sites-available", name) - - s := query.Site - - _, err := s.Where(s.Path.Eq(path)).FirstOrCreate() - if err != nil { - api.ErrHandler(c, err) - return - } - - _, err = s.Where(s.Path.Eq(path)).Update(s.Advanced, json.Advanced) - - if err != nil { - api.ErrHandler(c, err) - return - } - - c.JSON(http.StatusOK, gin.H{ - "message": "ok", - }) - } diff --git a/api/sites/duplicate.go b/api/sites/duplicate.go new file mode 100644 index 00000000..577a288b --- /dev/null +++ b/api/sites/duplicate.go @@ -0,0 +1,44 @@ +package sites + +import ( + "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/internal/helper" + "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/gin-gonic/gin" + "net/http" +) + +func DuplicateSite(c *gin.Context) { + // Source name + name := c.Param("name") + + // Destination name + var json struct { + Name string `json:"name" binding:"required"` + } + + if !api.BindAndValid(c, &json) { + return + } + + src := nginx.GetConfPath("sites-available", name) + dst := nginx.GetConfPath("sites-available", json.Name) + + if helper.FileExists(dst) { + c.JSON(http.StatusNotAcceptable, gin.H{ + "message": "File exists", + }) + return + } + + _, err := helper.CopyFile(src, dst) + + if err != nil { + api.ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, gin.H{ + "dst": dst, + }) +} diff --git a/api/sites/sites.go b/api/sites/sites.go new file mode 100644 index 00000000..823f9946 --- /dev/null +++ b/api/sites/sites.go @@ -0,0 +1,26 @@ +package sites + +import ( + "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/sashabaranov/go-openai" + "time" +) + +type CertificateInfo struct { + SubjectName string `json:"subject_name"` + IssuerName string `json:"issuer_name"` + NotAfter time.Time `json:"not_after"` + NotBefore time.Time `json:"not_before"` +} + +type Site struct { + ModifiedAt time.Time `json:"modified_at"` + Advanced bool `json:"advanced"` + Enabled bool `json:"enabled"` + Name string `json:"name"` + Config string `json:"config"` + AutoCert bool `json:"auto_cert"` + ChatGPTMessages []openai.ChatCompletionMessage `json:"chatgpt_messages,omitempty"` + Tokenized *nginx.NgxConfig `json:"tokenized,omitempty"` + CertInfo map[int]CertificateInfo `json:"cert_info,omitempty"` +} diff --git a/api/template/template.go b/api/template/template.go index d635e40e..eb984980 100644 --- a/api/template/template.go +++ b/api/template/template.go @@ -76,7 +76,7 @@ func GetTemplateBlock(c *gin.Context) { template.ConfigInfoItem template.ConfigDetail } - var bindData map[string]template.TVariable + var bindData map[string]template.Variable _ = c.ShouldBindJSON(&bindData) info := template.GetTemplateInfo("block", c.Param("name")) diff --git a/app/.eslintrc.js b/app/.eslintrc.js new file mode 100644 index 00000000..7bad4118 --- /dev/null +++ b/app/.eslintrc.js @@ -0,0 +1,258 @@ +module.exports = { + env: { + browser: true, + es2021: true, + }, + extends: [ + '@antfu/eslint-config-vue', + 'plugin:vue/vue3-recommended', + 'plugin:import/recommended', + 'plugin:import/typescript', + 'plugin:promise/recommended', + 'plugin:sonarjs/recommended', + 'plugin:@typescript-eslint/recommended', + + // 'plugin:unicorn/recommended', + ], + parser: 'vue-eslint-parser', + parserOptions: { + ecmaVersion: 13, + parser: '@typescript-eslint/parser', + sourceType: 'module', + }, + plugins: [ + 'vue', + '@typescript-eslint', + 'regex', + ], + ignorePatterns: ['src/@iconify/*.js', 'node_modules', 'dist', '*.d.ts'], + rules: { + 'vue/no-v-html': 'off', + + 'vue/block-tag-newline': 'off', + // eslint-disable-next-line n/prefer-global/process + 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + // eslint-disable-next-line n/prefer-global/process + 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + + // indentation (Already present in TypeScript) + 'comma-spacing': ['error', { + before: false, + after: true, + }], + 'key-spacing': ['error', { afterColon: true }], + + 'vue/first-attribute-linebreak': ['error', { + singleline: 'beside', + multiline: 'below', + }], + + 'antfu/top-level-function': 'off', + + // Enforce trailing comma (Already present in TypeScript) + 'comma-dangle': ['error', 'always-multiline'], + + // Disable max-len + 'max-len': 'off', + + // we don't want it + 'semi': ['error', 'never'], + + // add parens ony when required in arrow function + 'arrow-parens': ['error', 'as-needed'], + + // add new line above comment + 'newline-before-return': 'error', + + // add new line above comment + 'lines-around-comment': [ + 'error', + { + beforeBlockComment: true, + beforeLineComment: true, + allowBlockStart: true, + allowClassStart: true, + allowObjectStart: true, + allowArrayStart: true, + }, + ], + + // Ignore _ as unused variable + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_+$' }], + + 'array-element-newline': ['error', 'consistent'], + 'array-bracket-newline': ['error', 'consistent'], + + 'vue/multi-word-component-names': 'off', + + 'padding-line-between-statements': [ + 'error', + { + blankLine: 'always', + prev: 'expression', + next: 'const', + }, + { + blankLine: 'always', + prev: 'const', + next: 'expression', + }, + { + blankLine: 'always', + prev: 'multiline-const', + next: '*', + }, + { + blankLine: 'always', + prev: '*', + next: 'multiline-const', + }, + ], + + // Plugin: eslint-plugin-import + 'import/prefer-default-export': 'off', + 'import/newline-after-import': ['error', { count: 1 }], + 'no-restricted-imports': ['error', 'vuetify/components'], + + // For omitting extension for ts files + 'import/extensions': [ + 'error', + 'ignorePackages', + { + mjs: 'never', + js: 'never', + jsx: 'never', + ts: 'never', + tsx: 'never', + }, + ], + + // ignore virtual files + 'import/no-unresolved': [2, { + ignore: [ + '~pages$', + 'virtual:generated-layouts', + + // Ignore vite's ?raw imports + '.*\?raw', + ], + }], + + // Thanks: https://stackoverflow.com/a/63961972/10796681 + 'no-shadow': 'off', + '@typescript-eslint/no-shadow': ['error'], + + '@typescript-eslint/consistent-type-imports': 'error', + + // Plugin: eslint-plugin-promise + 'promise/always-return': 'off', + 'promise/catch-or-return': 'off', + + // ESLint plugin vue + 'vue/component-api-style': 'error', + 'vue/component-name-in-template-casing': ['error', 'PascalCase', { registeredComponentsOnly: false }], + 'vue/custom-event-name-casing': ['error', 'camelCase', { + ignores: [ + '/^(click):[a-z]+((\d)|([A-Z0-9][a-z0-9]+))*([A-Z])?/', + ], + }], + 'vue/define-macros-order': 'error', + 'vue/html-comment-content-newline': 'error', + 'vue/html-comment-content-spacing': 'error', + 'vue/html-comment-indent': 'error', + 'vue/match-component-file-name': 'error', + 'vue/no-child-content': 'error', + 'vue/require-default-prop': 'off', + + // NOTE this rule only supported in SFC, Users of the unplugin-vue-define-options should disable that rule: https://github.com/vuejs/eslint-plugin-vue/issues/1886 + // 'vue/no-duplicate-attr-inheritance': 'error', + 'vue/no-multiple-objects-in-class': 'error', + 'vue/no-reserved-component-names': 'error', + 'vue/no-template-target-blank': 'error', + 'vue/no-useless-mustaches': 'error', + 'vue/no-useless-v-bind': 'error', + 'vue/padding-line-between-blocks': 'error', + 'vue/prefer-separate-static-class': 'error', + 'vue/prefer-true-attribute-shorthand': 'error', + 'vue/v-on-function-call': 'error', + 'vue/valid-v-slot': ['error', { + allowModifiers: true, + }], + + // -- Extension Rules + 'vue/no-irregular-whitespace': 'error', + + // -- Sonarlint + 'sonarjs/no-duplicate-string': 'off', + 'sonarjs/no-nested-template-literals': 'off', + + // -- Unicorn + // 'unicorn/filename-case': 'off', + // 'unicorn/prevent-abbreviations': ['error', { + // replacements: { + // props: false, + // }, + // }], + // https://github.com/gmullerb/eslint-plugin-regex + 'regex/invalid': [ + 'error', + [ + { + regex: '@/assets/images', + replacement: '@images', + message: 'Use \'@images\' path alias for image imports', + }, + { + regex: '@/styles', + replacement: '@styles', + message: 'Use \'@styles\' path alias for importing styles from \'src/styles\'', + }, + + // { + // id: 'Disallow icon of icon library', + // regex: 'tabler-\\w', + // message: 'Only \'mdi\' icons are allowed', + // }, + + { + regex: '@core/\\w', + message: 'You can\'t use @core when you are in @layouts module', + files: { + inspect: '@layouts/.*', + }, + }, + { + regex: 'useLayouts\\(', + message: '`useLayouts` composable is only allowed in @layouts & @core directory. Please use `useThemeConfig` composable instead.', + files: { + inspect: '^(?!.*(@core|@layouts)).*', + }, + }, + ], + + // Ignore files + '\.eslintrc\.js', + ], + }, + settings: { + 'import/resolver': { + node: { + extensions: ['.ts', '.js', '.tsx', '.jsx', '.mjs', '.png', '.jpg'], + }, + typescript: {}, + alias: { + map: [ + ['@', './src'], + ], + }, + }, + }, + overrides: [ + { + files: ['*.json'], + rules: { + 'no-invalid-meta': 'off', + }, + }, + ], +} diff --git a/app/components.d.ts b/app/components.d.ts index 1cbf169d..dcbecddc 100644 --- a/app/components.d.ts +++ b/app/components.d.ts @@ -77,14 +77,22 @@ declare module 'vue' { RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] SetLanguageSetLanguage: typeof import('./src/components/SetLanguage/SetLanguage.vue')['default'] - StdDataDisplayStdBatchEdit: typeof import('./src/components/StdDataDisplay/StdBatchEdit.vue')['default'] - StdDataDisplayStdCurd: typeof import('./src/components/StdDataDisplay/StdCurd.vue')['default'] - StdDataDisplayStdPagination: typeof import('./src/components/StdDataDisplay/StdPagination.vue')['default'] - StdDataDisplayStdTable: typeof import('./src/components/StdDataDisplay/StdTable.vue')['default'] - StdDataEntryComponentsStdPassword: typeof import('./src/components/StdDataEntry/components/StdPassword.vue')['default'] - StdDataEntryComponentsStdSelect: typeof import('./src/components/StdDataEntry/components/StdSelect.vue')['default'] - StdDataEntryComponentsStdSelector: typeof import('./src/components/StdDataEntry/components/StdSelector.vue')['default'] - StdDataEntryStdFormItem: typeof import('./src/components/StdDataEntry/StdFormItem.vue')['default'] + StdDataDisplayStdBatchEdit: typeof import('./src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue')['default'] + StdDataDisplayStdCurd: typeof import('./src/components/StdDesign/StdDataDisplay/StdCurd.vue')['default'] + StdDataDisplayStdPagination: typeof import('./src/components/StdDesign/StdDataDisplay/StdPagination.vue')['default'] + StdDataDisplayStdTable: typeof import('./src/components/StdDesign/StdDataDisplay/StdTable.vue')['default'] + StdDataEntryComponentsStdPassword: typeof import('./src/components/StdDesign/StdDataEntry/components/StdPassword.vue')['default'] + StdDataEntryComponentsStdSelect: typeof import('./src/components/StdDesign/StdDataEntry/components/StdSelect.vue')['default'] + StdDataEntryComponentsStdSelector: typeof import('./src/components/StdDesign/StdDataEntry/components/StdSelector.vue')['default'] + StdDataEntryStdFormItem: typeof import('./src/components/StdDesign/StdDataEntry/StdFormItem.vue')['default'] + StdDesignStdDataDisplayStdBatchEdit: typeof import('./src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue')['default'] + StdDesignStdDataDisplayStdCurd: typeof import('./src/components/StdDesign/StdDataDisplay/StdCurd.vue')['default'] + StdDesignStdDataDisplayStdPagination: typeof import('./src/components/StdDesign/StdDataDisplay/StdPagination.vue')['default'] + StdDesignStdDataDisplayStdTable: typeof import('./src/components/StdDesign/StdDataDisplay/StdTable.vue')['default'] + StdDesignStdDataEntryComponentsStdPassword: typeof import('./src/components/StdDesign/StdDataEntry/components/StdPassword.vue')['default'] + StdDesignStdDataEntryComponentsStdSelect: typeof import('./src/components/StdDesign/StdDataEntry/components/StdSelect.vue')['default'] + StdDesignStdDataEntryComponentsStdSelector: typeof import('./src/components/StdDesign/StdDataEntry/components/StdSelector.vue')['default'] + StdDesignStdDataEntryStdFormItem: typeof import('./src/components/StdDesign/StdDataEntry/StdFormItem.vue')['default'] SwitchAppearanceIconsVPIconMoon: typeof import('./src/components/SwitchAppearance/icons/VPIconMoon.vue')['default'] SwitchAppearanceIconsVPIconSun: typeof import('./src/components/SwitchAppearance/icons/VPIconSun.vue')['default'] SwitchAppearanceSwitchAppearance: typeof import('./src/components/SwitchAppearance/SwitchAppearance.vue')['default'] diff --git a/app/gettext.config.js b/app/gettext.config.js index 48bb7d5f..be0cd003 100644 --- a/app/gettext.config.js +++ b/app/gettext.config.js @@ -1,3 +1,4 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires const i18n = require('./i18n.json') module.exports = { diff --git a/app/package.json b/app/package.json index b13447e1..75217f7e 100644 --- a/app/package.json +++ b/app/package.json @@ -5,6 +5,7 @@ "type": "commonjs", "scripts": { "dev": "vite", + "lint": "eslint . -c .eslintrc.js --fix --ext .ts,.vue,.tsx", "build": "vite build", "preview": "vite preview", "gettext:extract": "vue-gettext-extract", @@ -18,6 +19,7 @@ "@types/sortablejs": "^1.15.0", "@vue/reactivity": "^3.3.9", "@vue/shared": "^3.3.9", + "@vueuse/core": "^10.6.1", "ant-design-vue": "4.0.7", "apexcharts": "^3.36.3", "axios": "^1.6.2", @@ -43,11 +45,21 @@ "xterm-addon-fit": "^0.8.0" }, "devDependencies": { + "@antfu/eslint-config-vue": "^0.43.1", + "@typescript-eslint/eslint-plugin": "^6.13.0", + "@typescript-eslint/parser": "^6.13.0", "@vitejs/plugin-vue": "^4.5.0", "@vitejs/plugin-vue-jsx": "^3.1.0", "@vue/compiler-sfc": "^3.3.9", "ace-builds": "^1.31.2", "autoprefixer": "^10.4.16", + "eslint": "^8.54.0", + "eslint-import-resolver-alias": "^1.1.2", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-regex": "^1.10.0", + "eslint-plugin-sonarjs": "^0.23.0", + "eslint-plugin-vue": "^9.18.1", "less": "^4.2.0", "postcss": "^8.4.31", "tailwindcss": "^3.3.5", diff --git a/app/pnpm-lock.yaml b/app/pnpm-lock.yaml index 6c98a106..0122dc51 100644 --- a/app/pnpm-lock.yaml +++ b/app/pnpm-lock.yaml @@ -26,6 +26,9 @@ dependencies: '@vue/shared': specifier: ^3.3.9 version: 3.3.9 + '@vueuse/core': + specifier: ^10.6.1 + version: 10.6.1(vue@3.3.9) ant-design-vue: specifier: 4.0.7 version: 4.0.7(vue@3.3.9) @@ -97,6 +100,15 @@ dependencies: version: 0.8.0(xterm@5.3.0) devDependencies: + '@antfu/eslint-config-vue': + specifier: ^0.43.1 + version: 0.43.1(@typescript-eslint/eslint-plugin@6.13.0)(@typescript-eslint/parser@6.13.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/eslint-plugin': + specifier: ^6.13.0 + version: 6.13.0(@typescript-eslint/parser@6.13.0)(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/parser': + specifier: ^6.13.0 + version: 6.13.0(eslint@8.54.0)(typescript@5.3.2) '@vitejs/plugin-vue': specifier: ^4.5.0 version: 4.5.0(vite@5.0.2)(vue@3.3.9) @@ -112,6 +124,27 @@ devDependencies: autoprefixer: specifier: ^10.4.16 version: 10.4.16(postcss@8.4.31) + eslint: + specifier: ^8.54.0 + version: 8.54.0 + eslint-import-resolver-alias: + specifier: ^1.1.2 + version: 1.1.2(eslint-plugin-import@2.29.0) + eslint-import-resolver-typescript: + specifier: ^3.6.1 + version: 3.6.1(@typescript-eslint/parser@6.13.0)(eslint-plugin-import@2.29.0)(eslint@8.54.0) + eslint-plugin-import: + specifier: ^2.29.0 + version: 2.29.0(@typescript-eslint/parser@6.13.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0) + eslint-plugin-regex: + specifier: ^1.10.0 + version: 1.10.0(eslint@8.54.0) + eslint-plugin-sonarjs: + specifier: ^0.23.0 + version: 0.23.0(eslint@8.54.0) + eslint-plugin-vue: + specifier: ^9.18.1 + version: 9.18.1(eslint@8.54.0) less: specifier: ^4.2.0 version: 4.2.0 @@ -126,7 +159,7 @@ devDependencies: version: 5.3.2 unplugin-auto-import: specifier: ^0.17.1 - version: 0.17.1 + version: 0.17.1(@vueuse/core@10.6.1) unplugin-vue-components: specifier: ^0.25.2 version: 0.25.2(vue@3.3.9) @@ -148,6 +181,11 @@ devDependencies: packages: + /@aashutoshrathi/word-wrap@1.2.6: + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + dev: true + /@alloc/quick-lru@5.2.0: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} @@ -181,6 +219,77 @@ packages: vue: 3.3.9(typescript@5.3.2) dev: false + /@antfu/eslint-config-basic@0.43.1(@typescript-eslint/eslint-plugin@6.13.0)(@typescript-eslint/parser@6.13.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-SW6hmGmqI985fsCJ+oivo4MbiMmRMgCJ0Ne8j/hwCB6O6Mc0m5bDqYeKn5HqFhvZhG84GEg5jPDKNiHrBYnQjw==} + peerDependencies: + eslint: '>=7.4.0' + dependencies: + '@stylistic/eslint-plugin-js': 0.0.4 + eslint: 8.54.0 + eslint-plugin-antfu: 0.43.1(eslint@8.54.0)(typescript@5.3.2) + eslint-plugin-eslint-comments: 3.2.0(eslint@8.54.0) + eslint-plugin-html: 7.1.0 + eslint-plugin-import: /eslint-plugin-i@2.28.1(@typescript-eslint/parser@6.13.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0) + eslint-plugin-jsdoc: 46.9.0(eslint@8.54.0) + eslint-plugin-jsonc: 2.10.0(eslint@8.54.0) + eslint-plugin-markdown: 3.0.1(eslint@8.54.0) + eslint-plugin-n: 16.3.1(eslint@8.54.0) + eslint-plugin-no-only-tests: 3.1.0 + eslint-plugin-promise: 6.1.1(eslint@8.54.0) + eslint-plugin-unicorn: 48.0.1(eslint@8.54.0) + eslint-plugin-unused-imports: 3.0.0(@typescript-eslint/eslint-plugin@6.13.0)(eslint@8.54.0) + eslint-plugin-yml: 1.10.0(eslint@8.54.0) + jsonc-eslint-parser: 2.4.0 + yaml-eslint-parser: 1.2.2 + transitivePeerDependencies: + - '@typescript-eslint/eslint-plugin' + - '@typescript-eslint/parser' + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + - typescript + dev: true + + /@antfu/eslint-config-ts@0.43.1(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-s3zItBSopYbM/3eii/JKas1PmWR+wCPRNS89qUi4zxPvpuIgN5mahkBvbsCiWacrNFtLxe1zGgo5qijBhVfuvA==} + peerDependencies: + eslint: '>=7.4.0' + typescript: '>=3.9' + dependencies: + '@antfu/eslint-config-basic': 0.43.1(@typescript-eslint/eslint-plugin@6.13.0)(@typescript-eslint/parser@6.13.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0)(typescript@5.3.2) + '@stylistic/eslint-plugin-ts': 0.0.4(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/eslint-plugin': 6.13.0(@typescript-eslint/parser@6.13.0)(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/parser': 6.13.0(eslint@8.54.0)(typescript@5.3.2) + eslint: 8.54.0 + eslint-plugin-jest: 27.6.0(@typescript-eslint/eslint-plugin@6.13.0)(eslint@8.54.0)(typescript@5.3.2) + typescript: 5.3.2 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - jest + - supports-color + dev: true + + /@antfu/eslint-config-vue@0.43.1(@typescript-eslint/eslint-plugin@6.13.0)(@typescript-eslint/parser@6.13.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-HxOfe8Vl+DPrzssbs5LHRDCnBtCy1LSA1DIeV71IC+iTpzoASFahSsVX5qckYu1InFgUm93XOhHCWm34LzPsvg==} + peerDependencies: + eslint: '>=7.4.0' + dependencies: + '@antfu/eslint-config-basic': 0.43.1(@typescript-eslint/eslint-plugin@6.13.0)(@typescript-eslint/parser@6.13.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0)(typescript@5.3.2) + '@antfu/eslint-config-ts': 0.43.1(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0)(typescript@5.3.2) + eslint: 8.54.0 + eslint-plugin-vue: 9.18.1(eslint@8.54.0) + local-pkg: 0.4.3 + transitivePeerDependencies: + - '@typescript-eslint/eslint-plugin' + - '@typescript-eslint/parser' + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - jest + - supports-color + - typescript + dev: true + /@antfu/utils@0.7.6: resolution: {integrity: sha512-pvFiLP2BeOKA/ZOS6jxx4XhKzdVLHDhGlFEaZ2flWWYf2xOqVniqpk38I04DFRyz+L0ASggl7SkItTc+ZLju4w==} dev: true @@ -486,6 +595,15 @@ packages: resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==} dev: false + /@es-joy/jsdoccomment@0.41.0: + resolution: {integrity: sha512-aKUhyn1QI5Ksbqcr3fFJj16p99QdjUxXAEuFst1Z47DRyoiMwivIH9MV/ARcJOCXVjPfjITciej8ZD2O/6qUmw==} + engines: {node: '>=16'} + dependencies: + comment-parser: 1.4.1 + esquery: 1.5.0 + jsdoc-type-pratt-parser: 4.0.0 + dev: true + /@esbuild/android-arm64@0.18.20: resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} engines: {node: '>=12'} @@ -882,10 +1000,67 @@ packages: dev: true optional: true + /@eslint-community/eslint-utils@4.4.0(eslint@8.54.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.54.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.10.0: + resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.1.3: + resolution: {integrity: sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 9.6.1 + globals: 13.23.0 + ignore: 5.3.0 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@8.54.0: + resolution: {integrity: sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + /@formkit/auto-animate@0.8.1: resolution: {integrity: sha512-0/Z2cuNXWVVIG/l0SpcHAWFhGdvLJ8DRvEfRWvmojtmRWfEy+LWNwgDazbZqY0qQYtkHcoEK3jBLkhiZaB/4Ig==} dev: false + /@humanwhocodes/config-array@0.11.13: + resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 2.0.1 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema@2.0.1: + resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} + dev: true + /@jridgewell/gen-mapping@0.3.3: resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} engines: {node: '>=6.0.0'} @@ -1068,6 +1243,34 @@ packages: nanopop: 2.3.0 dev: false + /@stylistic/eslint-plugin-js@0.0.4: + resolution: {integrity: sha512-W1rq2xxlFNhgZZJO+L59wtvlDI0xARYxx0WD8EeWNBO7NDybUSYSozCIcY9XvxQbTAsEXBjwqokeYm0crt7RxQ==} + dependencies: + acorn: 8.11.2 + escape-string-regexp: 4.0.0 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esutils: 2.0.3 + graphemer: 1.4.0 + dev: true + + /@stylistic/eslint-plugin-ts@0.0.4(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-sWL4Km5j8S+TLyzya/3adxMWGkCm3lVasJIVQqhxVfwnlGkpMI0GgYVIu/ubdKPS+dSvqjUHpsXgqWfMRF2+cQ==} + peerDependencies: + eslint: '*' + typescript: '*' + dependencies: + '@stylistic/eslint-plugin-js': 0.0.4 + '@typescript-eslint/scope-manager': 6.13.0 + '@typescript-eslint/type-utils': 6.13.0(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/utils': 6.13.0(eslint@8.54.0)(typescript@5.3.2) + eslint: 8.54.0 + graphemer: 1.4.0 + typescript: 5.3.2 + transitivePeerDependencies: + - supports-color + dev: true + /@trysound/sax@0.2.0: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} @@ -1084,10 +1287,24 @@ packages: '@types/node': 20.10.0 dev: false + /@types/json-schema@7.0.15: + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + dev: true + + /@types/json5@0.0.29: + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: true + /@types/lodash@4.14.202: resolution: {integrity: sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==} dev: false + /@types/mdast@3.0.15: + resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} + dependencies: + '@types/unist': 2.0.10 + dev: true + /@types/minimatch@5.1.2: resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} dev: false @@ -1104,6 +1321,10 @@ packages: undici-types: 5.26.5 dev: false + /@types/normalize-package-data@2.4.4: + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + dev: true + /@types/nprogress@0.2.3: resolution: {integrity: sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==} dev: false @@ -1116,10 +1337,218 @@ packages: resolution: {integrity: sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==} dev: false + /@types/semver@7.5.6: + resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==} + dev: true + /@types/sortablejs@1.15.7: resolution: {integrity: sha512-PvgWCx1Lbgm88FdQ6S7OGvLIjWS66mudKPlfdrWil0TjsO5zmoZmzoKiiwRShs1dwPgrlkr0N4ewuy0/+QUXYQ==} dev: false + /@types/unist@2.0.10: + resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==} + dev: true + + /@types/web-bluetooth@0.0.20: + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + + /@typescript-eslint/eslint-plugin@6.13.0(@typescript-eslint/parser@6.13.0)(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-HTvbSd0JceI2GW5DHS3R9zbarOqjkM9XDR7zL8eCsBUO/eSiHcoNE7kSL5sjGXmVa9fjH5LCfHDXNnH4QLp7tQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@eslint-community/regexpp': 4.10.0 + '@typescript-eslint/parser': 6.13.0(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/scope-manager': 6.13.0 + '@typescript-eslint/type-utils': 6.13.0(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/utils': 6.13.0(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/visitor-keys': 6.13.0 + debug: 4.3.4 + eslint: 8.54.0 + graphemer: 1.4.0 + ignore: 5.3.0 + natural-compare: 1.4.0 + semver: 7.5.4 + ts-api-utils: 1.0.3(typescript@5.3.2) + typescript: 5.3.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/parser@6.13.0(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-VpG+M7GNhHLI/aTDctqAV0XbzB16vf+qDX9DXuMZSe/0bahzDA9AKZB15NDbd+D9M4cDsJvfkbGOA7qiZ/bWJw==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 6.13.0 + '@typescript-eslint/types': 6.13.0 + '@typescript-eslint/typescript-estree': 6.13.0(typescript@5.3.2) + '@typescript-eslint/visitor-keys': 6.13.0 + debug: 4.3.4 + eslint: 8.54.0 + typescript: 5.3.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager@5.62.0: + resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + dev: true + + /@typescript-eslint/scope-manager@6.13.0: + resolution: {integrity: sha512-2x0K2/CujsokIv+LN2T0l5FVDMtsCjkUyYtlcY4xxnxLAW+x41LXr16duoicHpGtLhmtN7kqvuFJ3zbz00Ikhw==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.13.0 + '@typescript-eslint/visitor-keys': 6.13.0 + dev: true + + /@typescript-eslint/type-utils@6.13.0(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-YHufAmZd/yP2XdoD3YeFEjq+/Tl+myhzv+GJHSOz+ro/NFGS84mIIuLU3pVwUcauSmwlCrVXbBclkn1HfjY0qQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 6.13.0(typescript@5.3.2) + '@typescript-eslint/utils': 6.13.0(eslint@8.54.0)(typescript@5.3.2) + debug: 4.3.4 + eslint: 8.54.0 + ts-api-utils: 1.0.3(typescript@5.3.2) + typescript: 5.3.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types@5.62.0: + resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@typescript-eslint/types@6.13.0: + resolution: {integrity: sha512-oXg7DFxx/GmTrKXKKLSoR2rwiutOC7jCQ5nDH5p5VS6cmHE1TcPTaYQ0VPSSUvj7BnNqCgQ/NXcTBxn59pfPTQ==} + engines: {node: ^16.0.0 || >=18.0.0} + dev: true + + /@typescript-eslint/typescript-estree@5.62.0(typescript@5.3.2): + resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.5.4 + tsutils: 3.21.0(typescript@5.3.2) + typescript: 5.3.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/typescript-estree@6.13.0(typescript@5.3.2): + resolution: {integrity: sha512-IT4O/YKJDoiy/mPEDsfOfp+473A9GVqXlBKckfrAOuVbTqM8xbc0LuqyFCcgeFWpqu3WjQexolgqN2CuWBYbog==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 6.13.0 + '@typescript-eslint/visitor-keys': 6.13.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.5.4 + ts-api-utils: 1.0.3(typescript@5.3.2) + typescript: 5.3.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils@5.62.0(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.6 + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.3.2) + eslint: 8.54.0 + eslint-scope: 5.1.1 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/utils@6.13.0(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-V+txaxARI8yznDkcQ6FNRXxG+T37qT3+2NsDTZ/nKLxv6VfGrRhTnuvxPUxpVuWWr+eVeIxU53PioOXbz8ratQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.6 + '@typescript-eslint/scope-manager': 6.13.0 + '@typescript-eslint/types': 6.13.0 + '@typescript-eslint/typescript-estree': 6.13.0(typescript@5.3.2) + eslint: 8.54.0 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/visitor-keys@5.62.0: + resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.62.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@typescript-eslint/visitor-keys@6.13.0: + resolution: {integrity: sha512-UQklteCEMCRoq/1UhKFZsHv5E4dN1wQSzJoxTfABasWk1HgJRdg1xNUve/Kv/Sdymt4x+iEzpESOqRFlQr/9Aw==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.13.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@ungap/structured-clone@1.2.0: + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + dev: true + /@vitejs/plugin-vue-jsx@3.1.0(vite@5.0.2)(vue@3.3.9): resolution: {integrity: sha512-w9M6F3LSEU5kszVb9An2/MmXNxocAnUb3WhRr8bHlimhDrXNt6n6D2nJQR3UXpGlZHh/EsgouOHCsM8V3Ln+WA==} engines: {node: ^14.18.0 || >=16.0.0} @@ -1305,6 +1734,28 @@ packages: /@vue/shared@3.3.9: resolution: {integrity: sha512-ZE0VTIR0LmYgeyhurPTpy4KzKsuDyQbMSdM49eKkMnT5X4VfFBLysMzjIZhLEFQYjjOVVfbvUDHckwjDFiO2eA==} + /@vueuse/core@10.6.1(vue@3.3.9): + resolution: {integrity: sha512-Pc26IJbqgC9VG1u6VY/xrXXfxD33hnvxBnKrLlA2LJlyHII+BSrRoTPJgGYq7qZOu61itITFUnm6QbacwZ4H8Q==} + dependencies: + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 10.6.1 + '@vueuse/shared': 10.6.1(vue@3.3.9) + vue-demi: 0.14.6(vue@3.3.9) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + /@vueuse/metadata@10.6.1: + resolution: {integrity: sha512-qhdwPI65Bgcj23e5lpGfQsxcy0bMjCAsUGoXkJ7DsoeDUdasbZ2DBa4dinFCOER3lF4gwUv+UD2AlA11zdzMFw==} + + /@vueuse/shared@10.6.1(vue@3.3.9): + resolution: {integrity: sha512-TECVDTIedFlL0NUfHWncf3zF9Gc4VfdxfQc8JFwoVZQmxpONhLxFrlm0eHQeidHj4rdTPL3KXJa0TZCk1wnc5Q==} + dependencies: + vue-demi: 0.14.6(vue@3.3.9) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + /@yr/monotone-cubic-spline@1.0.3: resolution: {integrity: sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==} dev: false @@ -1312,12 +1763,34 @@ packages: /ace-builds@1.31.2: resolution: {integrity: sha512-IeZI9ytPA6mB+goPxPkUPW4vXBoLuaBl5czu2tjtKrMi7mdRgyIUA/8e5JlrI1mqKoMeWHoUujzMTWkyutTdBw==} + /acorn-jsx@5.3.2(acorn@8.11.2): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.11.2 + dev: true + /acorn@8.11.2: resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} engines: {node: '>=0.4.0'} hasBin: true dev: true + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + /ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -1385,19 +1858,95 @@ packages: svg.select.js: 3.0.1 dev: false + /are-docs-informative@0.0.2: + resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} + engines: {node: '>=14'} + dev: true + /arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} dev: true + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + /array-back@3.1.0: resolution: {integrity: sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==} engines: {node: '>=6'} dev: false + /array-buffer-byte-length@1.0.0: + resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} + dependencies: + call-bind: 1.0.5 + is-array-buffer: 3.0.2 + dev: true + + /array-includes@3.1.7: + resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 + is-string: 1.0.7 + dev: true + /array-tree-filter@2.1.0: resolution: {integrity: sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==} dev: false + /array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + + /array.prototype.findlastindex@1.2.3: + resolution: {integrity: sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + es-shim-unscopables: 1.0.2 + get-intrinsic: 1.2.2 + dev: true + + /array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + es-shim-unscopables: 1.0.2 + dev: true + + /arraybuffer.prototype.slice@1.0.2: + resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 + is-array-buffer: 3.0.2 + is-shared-array-buffer: 1.0.2 + dev: true + /ast-kit@0.11.2: resolution: {integrity: sha512-Q0DjXK4ApbVoIf9GLyCo252tUH44iTnD/hiJ2TQaJeydYWSpKk0sI34+WMel8S9Wt5pbLgG02oJ+gkgX5DV3sQ==} engines: {node: '>=16.14.0'} @@ -1458,6 +2007,11 @@ packages: postcss-value-parser: 4.2.0 dev: true + /available-typed-arrays@1.0.5: + resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + engines: {node: '>= 0.4'} + dev: true + /axios@1.6.2: resolution: {integrity: sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==} dependencies: @@ -1514,10 +2068,28 @@ packages: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} dev: true + /builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + dev: true + + /builtins@5.0.1: + resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} + dependencies: + semver: 7.5.4 + dev: true + + /call-bind@1.0.5: + resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} + dependencies: + function-bind: 1.1.2 + get-intrinsic: 1.2.2 + set-function-length: 1.1.1 + dev: true + /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - dev: false /camel-case@4.1.2: resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} @@ -1555,6 +2127,18 @@ packages: ansi-styles: 4.3.0 supports-color: 7.2.0 + /character-entities-legacy@1.1.4: + resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} + dev: true + + /character-entities@1.2.4: + resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} + dev: true + + /character-reference-invalid@1.1.4: + resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} + dev: true + /chokidar@3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -1570,6 +2154,11 @@ packages: fsevents: 2.3.3 dev: true + /ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + dev: true + /clean-css@5.3.2: resolution: {integrity: sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==} engines: {node: '>= 10.0'} @@ -1577,6 +2166,13 @@ packages: source-map: 0.6.1 dev: true + /clean-regexp@1.0.0: + resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} + engines: {node: '>=4'} + dependencies: + escape-string-regexp: 1.0.5 + dev: true + /color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: @@ -1634,7 +2230,12 @@ packages: engines: {node: '>= 12'} dev: true - /compute-scroll-into-view@1.0.20: + /comment-parser@1.4.1: + resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} + engines: {node: '>= 12.0.0'} + dev: true + + /compute-scroll-into-view@1.0.20: resolution: {integrity: sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==} dev: false @@ -1679,6 +2280,15 @@ packages: yaml: 1.10.2 dev: false + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + /css-select@4.3.0: resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} dependencies: @@ -1758,7 +2368,6 @@ packages: optional: true dependencies: ms: 2.1.3 - optional: true /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} @@ -1772,6 +2381,28 @@ packages: ms: 2.1.2 dev: true + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /define-data-property@1.1.1: + resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + dev: true + + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + has-property-descriptors: 1.0.1 + object-keys: 1.1.1 + dev: true + /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -1781,10 +2412,31 @@ packages: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} dev: true + /dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + /dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} dev: true + /doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + /dom-align@1.12.4: resolution: {integrity: sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==} dev: false @@ -1872,6 +2524,14 @@ packages: resolution: {integrity: sha512-xT1HVAu5xFn7bDfkjGQi9dNpMqGchUkebwf1GL7cZN32NSwwlHRPMSDJ1KN6HkS0bWUtndbSQZqvpQftKG2uFQ==} dev: true + /enhanced-resolve@5.15.0: + resolution: {integrity: sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==} + engines: {node: '>=10.13.0'} + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + dev: true + /entities@2.2.0: resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} dev: true @@ -1893,7 +2553,75 @@ packages: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} dependencies: is-arrayish: 0.2.1 - dev: false + + /es-abstract@1.22.3: + resolution: {integrity: sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + arraybuffer.prototype.slice: 1.0.2 + available-typed-arrays: 1.0.5 + call-bind: 1.0.5 + es-set-tostringtag: 2.0.2 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.2 + get-symbol-description: 1.0.0 + globalthis: 1.0.3 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + has-proto: 1.0.1 + has-symbols: 1.0.3 + hasown: 2.0.0 + internal-slot: 1.0.6 + is-array-buffer: 3.0.2 + is-callable: 1.2.7 + is-negative-zero: 2.0.2 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + is-string: 1.0.7 + is-typed-array: 1.1.12 + is-weakref: 1.0.2 + object-inspect: 1.13.1 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.5.1 + safe-array-concat: 1.0.1 + safe-regex-test: 1.0.0 + string.prototype.trim: 1.2.8 + string.prototype.trimend: 1.0.7 + string.prototype.trimstart: 1.0.7 + typed-array-buffer: 1.0.0 + typed-array-byte-length: 1.0.0 + typed-array-byte-offset: 1.0.0 + typed-array-length: 1.0.4 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.13 + dev: true + + /es-set-tostringtag@2.0.2: + resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.2 + has-tostringtag: 1.0.0 + hasown: 2.0.0 + dev: true + + /es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + dependencies: + hasown: 2.0.0 + dev: true + + /es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true /esbuild@0.18.20: resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} @@ -1964,14 +2692,502 @@ packages: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + /escape-string-regexp@5.0.0: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} dev: true + /eslint-compat-utils@0.1.2(eslint@8.54.0): + resolution: {integrity: sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==} + engines: {node: '>=12'} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + eslint: 8.54.0 + dev: true + + /eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.29.0): + resolution: {integrity: sha512-WdviM1Eu834zsfjHtcGHtGfcu+F30Od3V7I9Fi57uhBEwPkjDcii7/yW8jAT+gOhn4P/vOxxNAXbFAKsrrc15w==} + engines: {node: '>= 4'} + peerDependencies: + eslint-plugin-import: '>=1.4.0' + dependencies: + eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.13.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0) + dev: true + + /eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + dependencies: + debug: 3.2.7 + is-core-module: 2.13.1 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.13.0)(eslint-plugin-import@2.29.0)(eslint@8.54.0): + resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + dependencies: + debug: 4.3.4 + enhanced-resolve: 5.15.0 + eslint: 8.54.0 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.13.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0) + eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.13.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0) + fast-glob: 3.3.2 + get-tsconfig: 4.7.2 + is-core-module: 2.13.1 + is-glob: 4.0.3 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-node + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.13.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0): + resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 6.13.0(eslint@8.54.0)(typescript@5.3.2) + debug: 3.2.7 + eslint: 8.54.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.13.0)(eslint-plugin-import@2.29.0)(eslint@8.54.0) + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-antfu@0.43.1(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-Nak+Qpy5qEK10dCXtVaabPTUmLBPLhsVKAFXAtxYGYRlY/SuuZUBhW2YIsLsixNROiICGuov8sN+eNOCC7Wb5g==} + dependencies: + '@typescript-eslint/utils': 6.13.0(eslint@8.54.0)(typescript@5.3.2) + transitivePeerDependencies: + - eslint + - supports-color + - typescript + dev: true + + /eslint-plugin-es-x@7.4.0(eslint@8.54.0): + resolution: {integrity: sha512-WJa3RhYzBtl8I37ebY9p76s61UhZyi4KaFOnX2A5r32RPazkXj5yoT6PGnD02dhwzEUj0KwsUdqfKDd/OuvGsw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '>=8' + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) + '@eslint-community/regexpp': 4.10.0 + eslint: 8.54.0 + eslint-compat-utils: 0.1.2(eslint@8.54.0) + dev: true + + /eslint-plugin-eslint-comments@3.2.0(eslint@8.54.0): + resolution: {integrity: sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==} + engines: {node: '>=6.5.0'} + peerDependencies: + eslint: '>=4.19.1' + dependencies: + escape-string-regexp: 1.0.5 + eslint: 8.54.0 + ignore: 5.3.0 + dev: true + + /eslint-plugin-html@7.1.0: + resolution: {integrity: sha512-fNLRraV/e6j8e3XYOC9xgND4j+U7b1Rq+OygMlLcMg+wI/IpVbF+ubQa3R78EjKB9njT6TQOlcK5rFKBVVtdfg==} + dependencies: + htmlparser2: 8.0.2 + dev: true + + /eslint-plugin-i@2.28.1(@typescript-eslint/parser@6.13.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0): + resolution: {integrity: sha512-a4oVt0j3ixNhGhvV4XF6NS7OWRFK2rrJ0Q5C4S2dSRb8FxZi31J0uUd5WJLL58wnVJ/OiQ1BxiXnFA4dWQO1Cg==} + engines: {node: '>=12'} + peerDependencies: + eslint: ^7.2.0 || ^8 + dependencies: + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.54.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.13.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0) + get-tsconfig: 4.7.2 + is-glob: 4.0.3 + minimatch: 3.1.2 + resolve: 1.22.8 + semver: 7.5.4 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-plugin-import@2.29.0(@typescript-eslint/parser@6.13.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0): + resolution: {integrity: sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 6.13.0(eslint@8.54.0)(typescript@5.3.2) + array-includes: 3.1.7 + array.prototype.findlastindex: 1.2.3 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.54.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.13.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0) + hasown: 2.0.0 + is-core-module: 2.13.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.7 + object.groupby: 1.0.1 + object.values: 1.1.7 + semver: 6.3.1 + tsconfig-paths: 3.14.2 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-plugin-jest@27.6.0(@typescript-eslint/eslint-plugin@6.13.0)(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-MTlusnnDMChbElsszJvrwD1dN3x6nZl//s4JD23BxB6MgR66TZlL064su24xEIS3VACfAoHV1vgyMgPw8nkdng==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^5.0.0 || ^6.0.0 + eslint: ^7.0.0 || ^8.0.0 + jest: '*' + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + jest: + optional: true + dependencies: + '@typescript-eslint/eslint-plugin': 6.13.0(@typescript-eslint/parser@6.13.0)(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/utils': 5.62.0(eslint@8.54.0)(typescript@5.3.2) + eslint: 8.54.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /eslint-plugin-jsdoc@46.9.0(eslint@8.54.0): + resolution: {integrity: sha512-UQuEtbqLNkPf5Nr/6PPRCtr9xypXY+g8y/Q7gPa0YK7eDhh0y2lWprXRnaYbW7ACgIUvpDKy9X2bZqxtGzBG9Q==} + engines: {node: '>=16'} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + '@es-joy/jsdoccomment': 0.41.0 + are-docs-informative: 0.0.2 + comment-parser: 1.4.1 + debug: 4.3.4 + escape-string-regexp: 4.0.0 + eslint: 8.54.0 + esquery: 1.5.0 + is-builtin-module: 3.2.1 + semver: 7.5.4 + spdx-expression-parse: 3.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-jsonc@2.10.0(eslint@8.54.0): + resolution: {integrity: sha512-9d//o6Jyh4s1RxC9fNSt1+MMaFN2ruFdXPG9XZcb/mR2KkfjADYiNL/hbU6W0Cyxfg3tS/XSFuhl5LgtMD8hmw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) + eslint: 8.54.0 + eslint-compat-utils: 0.1.2(eslint@8.54.0) + jsonc-eslint-parser: 2.4.0 + natural-compare: 1.4.0 + dev: true + + /eslint-plugin-markdown@3.0.1(eslint@8.54.0): + resolution: {integrity: sha512-8rqoc148DWdGdmYF6WSQFT3uQ6PO7zXYgeBpHAOAakX/zpq+NvFYbDA/H7PYzHajwtmaOzAwfxyl++x0g1/N9A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + eslint: 8.54.0 + mdast-util-from-markdown: 0.8.5 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-n@16.3.1(eslint@8.54.0): + resolution: {integrity: sha512-w46eDIkxQ2FaTHcey7G40eD+FhTXOdKudDXPUO2n9WNcslze/i/HT2qJ3GXjHngYSGDISIgPNhwGtgoix4zeOw==} + engines: {node: '>=16.0.0'} + peerDependencies: + eslint: '>=7.0.0' + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) + builtins: 5.0.1 + eslint: 8.54.0 + eslint-plugin-es-x: 7.4.0(eslint@8.54.0) + get-tsconfig: 4.7.2 + ignore: 5.3.0 + is-builtin-module: 3.2.1 + is-core-module: 2.13.1 + minimatch: 3.1.2 + resolve: 1.22.8 + semver: 7.5.4 + dev: true + + /eslint-plugin-no-only-tests@3.1.0: + resolution: {integrity: sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw==} + engines: {node: '>=5.0.0'} + dev: true + + /eslint-plugin-promise@6.1.1(eslint@8.54.0): + resolution: {integrity: sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + eslint: 8.54.0 + dev: true + + /eslint-plugin-regex@1.10.0(eslint@8.54.0): + resolution: {integrity: sha512-C8/qYKkkbIb0epxKzaz4aw7oVAOmm19fJpR/moUrUToq/vc4xW4sEKMlTQqH6EtNGpvLjYsbbZRlWNWwQGeTSA==} + engines: {node: '>=6.0.0'} + peerDependencies: + eslint: '>=4.0.0' + dependencies: + eslint: 8.54.0 + dev: true + + /eslint-plugin-sonarjs@0.23.0(eslint@8.54.0): + resolution: {integrity: sha512-z44T3PBf9W7qQ/aR+NmofOTyg6HLhSEZOPD4zhStqBpLoMp8GYhFksuUBnCxbnf1nfISpKBVkQhiBLFI/F4Wlg==} + engines: {node: '>=14'} + peerDependencies: + eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + eslint: 8.54.0 + dev: true + + /eslint-plugin-unicorn@48.0.1(eslint@8.54.0): + resolution: {integrity: sha512-FW+4r20myG/DqFcCSzoumaddKBicIPeFnTrifon2mWIzlfyvzwyqZjqVP7m4Cqr/ZYisS2aiLghkUWaPg6vtCw==} + engines: {node: '>=16'} + peerDependencies: + eslint: '>=8.44.0' + dependencies: + '@babel/helper-validator-identifier': 7.22.20 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) + ci-info: 3.9.0 + clean-regexp: 1.0.0 + eslint: 8.54.0 + esquery: 1.5.0 + indent-string: 4.0.0 + is-builtin-module: 3.2.1 + jsesc: 3.0.2 + lodash: 4.17.21 + pluralize: 8.0.0 + read-pkg-up: 7.0.1 + regexp-tree: 0.1.27 + regjsparser: 0.10.0 + semver: 7.5.4 + strip-indent: 3.0.0 + dev: true + + /eslint-plugin-unused-imports@3.0.0(@typescript-eslint/eslint-plugin@6.13.0)(eslint@8.54.0): + resolution: {integrity: sha512-sduiswLJfZHeeBJ+MQaG+xYzSWdRXoSw61DpU13mzWumCkR0ufD0HmO4kdNokjrkluMHpj/7PJeN35pgbhW3kw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^6.0.0 + eslint: ^8.0.0 + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + dependencies: + '@typescript-eslint/eslint-plugin': 6.13.0(@typescript-eslint/parser@6.13.0)(eslint@8.54.0)(typescript@5.3.2) + eslint: 8.54.0 + eslint-rule-composer: 0.3.0 + dev: true + + /eslint-plugin-vue@9.18.1(eslint@8.54.0): + resolution: {integrity: sha512-7hZFlrEgg9NIzuVik2I9xSnJA5RsmOfueYgsUGUokEDLJ1LHtxO0Pl4duje1BriZ/jDWb+44tcIlC3yi0tdlZg==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) + eslint: 8.54.0 + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.0.13 + semver: 7.5.4 + vue-eslint-parser: 9.3.2(eslint@8.54.0) + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-yml@1.10.0(eslint@8.54.0): + resolution: {integrity: sha512-53SUwuNDna97lVk38hL/5++WXDuugPM9SUQ1T645R0EHMRCdBIIxGye/oOX2qO3FQ7aImxaUZJU/ju+NMUBrLQ==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + debug: 4.3.4 + eslint: 8.54.0 + eslint-compat-utils: 0.1.2(eslint@8.54.0) + lodash: 4.17.21 + natural-compare: 1.4.0 + yaml-eslint-parser: 1.2.2 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-rule-composer@0.3.0: + resolution: {integrity: sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==} + engines: {node: '>=4.0.0'} + dev: true + + /eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + dev: true + + /eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint@8.54.0: + resolution: {integrity: sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) + '@eslint-community/regexpp': 4.10.0 + '@eslint/eslintrc': 2.1.3 + '@eslint/js': 8.54.0 + '@humanwhocodes/config-array': 0.11.13 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.23.0 + graphemer: 1.4.0 + ignore: 5.3.0 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.3 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.11.2 + acorn-jsx: 5.3.2(acorn@8.11.2) + eslint-visitor-keys: 3.4.3 + dev: true + + /esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + /estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + /fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} @@ -1983,12 +3199,27 @@ packages: micromatch: 4.0.5 dev: true + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + /fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} dependencies: reusify: 1.0.4 dev: true + /file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.2.0 + dev: true + /filelist@1.0.4: resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} dependencies: @@ -2009,6 +3240,35 @@ packages: array-back: 3.1.0 dev: false + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flatted: 3.2.9 + keyv: 4.5.4 + rimraf: 3.0.2 + dev: true + + /flatted@3.2.9: + resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} + dev: true + /follow-redirects@1.15.3: resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==} engines: {node: '>=4.0'} @@ -2019,6 +3279,12 @@ packages: optional: true dev: false + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + /form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} @@ -2055,11 +3321,48 @@ packages: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} dev: true + /function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + functions-have-names: 1.2.3 + dev: true + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + /gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} dev: true + /get-intrinsic@1.2.2: + resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} + dependencies: + function-bind: 1.1.2 + has-proto: 1.0.1 + has-symbols: 1.0.3 + hasown: 2.0.0 + dev: true + + /get-symbol-description@1.0.0: + resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + dev: true + + /get-tsconfig@4.7.2: + resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==} + dependencies: + resolve-pkg-maps: 1.0.0 + dev: true + /gettext-extractor@3.8.0: resolution: {integrity: sha512-i/3mDQufQoJd2/EKm/B+VlaYrt3yGjVfLZu8DQpESKH29klNiW6z2S89FVCIEB85bDNgtGCeM/3A/yR1njr/Lw==} engines: {node: '>=6'} @@ -2111,16 +3414,55 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 - dev: false /globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} dev: true + /globals@13.23.0: + resolution: {integrity: sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /globalthis@1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.1 + dev: true + + /globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.0 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.2 + dev: true + /graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + + /has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + /has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} @@ -2129,6 +3471,29 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + /has-property-descriptors@1.0.1: + resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} + dependencies: + get-intrinsic: 1.2.2 + dev: true + + /has-proto@1.0.1: + resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + engines: {node: '>= 0.4'} + dev: true + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag@1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + /hasown@2.0.0: resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} engines: {node: '>= 0.4'} @@ -2146,6 +3511,10 @@ packages: engines: {node: '>=12.0.0'} dev: false + /hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + dev: true + /html-minifier-terser@6.1.0: resolution: {integrity: sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==} engines: {node: '>=12'} @@ -2165,6 +3534,15 @@ packages: engines: {node: '>=8'} dev: true + /htmlparser2@8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + entities: 4.5.0 + dev: true + /iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -2173,6 +3551,11 @@ packages: safer-buffer: 2.1.2 optional: true + /ignore@5.3.0: + resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} + engines: {node: '>= 4'} + dev: true + /image-size@0.5.5: resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==} engines: {node: '>=0.10.0'} @@ -2186,7 +3569,16 @@ packages: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 - dev: false + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true /inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} @@ -2197,9 +3589,42 @@ packages: /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + /internal-slot@1.0.6: + resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.2 + hasown: 2.0.0 + side-channel: 1.0.4 + dev: true + + /is-alphabetical@1.0.4: + resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} + dev: true + + /is-alphanumerical@1.0.4: + resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} + dependencies: + is-alphabetical: 1.0.4 + is-decimal: 1.0.4 + dev: true + + /is-array-buffer@3.0.2: + resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + is-typed-array: 1.1.12 + dev: true + /is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - dev: false + + /is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true /is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} @@ -2208,12 +3633,43 @@ packages: binary-extensions: 2.2.0 dev: true + /is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + has-tostringtag: 1.0.0 + dev: true + + /is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + dependencies: + builtin-modules: 3.3.0 + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + /is-core-module@2.13.1: resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} dependencies: hasown: 2.0.0 dev: true + /is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-decimal@1.0.4: + resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} + dev: true + /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -2226,19 +3682,89 @@ packages: is-extglob: 2.1.1 dev: true + /is-hexadecimal@1.0.4: + resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} + dev: true + + /is-negative-zero@2.0.2: + resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} dev: true + /is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + /is-plain-object@3.0.1: resolution: {integrity: sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==} engines: {node: '>=0.10.0'} dev: false + /is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + has-tostringtag: 1.0.0 + dev: true + + /is-shared-array-buffer@1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + dependencies: + call-bind: 1.0.5 + dev: true + + /is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-typed-array@1.1.12: + resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.13 + dev: true + + /is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.5 + dev: true + /is-what@3.14.1: resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==} + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + /jake@10.8.7: resolution: {integrity: sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==} engines: {node: '>=10'} @@ -2258,15 +3784,56 @@ packages: /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsdoc-type-pratt-parser@4.0.0: + resolution: {integrity: sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==} + engines: {node: '>=12.0.0'} + dev: true + + /jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + dev: true + /jsesc@2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} hasBin: true dev: true + /jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true + /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - dev: false + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: true /json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} @@ -2274,6 +3841,16 @@ packages: hasBin: true dev: true + /jsonc-eslint-parser@2.4.0: + resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.11.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + semver: 7.5.4 + dev: true + /jsonc-parser@3.2.0: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} dev: true @@ -2286,6 +3863,12 @@ packages: graceful-fs: 4.2.11 dev: true + /keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + dependencies: + json-buffer: 3.0.1 + dev: true + /less@4.2.0: resolution: {integrity: sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==} engines: {node: '>=6'} @@ -2305,6 +3888,14 @@ packages: transitivePeerDependencies: - supports-color + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + /lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} @@ -2331,6 +3922,20 @@ packages: pkg-types: 1.0.3 dev: true + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + /lodash-es@4.17.21: resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} dev: false @@ -2339,9 +3944,12 @@ packages: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} dev: false + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: false /loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} @@ -2397,6 +4005,22 @@ packages: hasBin: true dev: false + /mdast-util-from-markdown@0.8.5: + resolution: {integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==} + dependencies: + '@types/mdast': 3.0.15 + mdast-util-to-string: 2.0.0 + micromark: 2.11.4 + parse-entities: 2.0.0 + unist-util-stringify-position: 2.0.3 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-to-string@2.0.0: + resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==} + dev: true + /mdn-data@2.0.28: resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} dev: true @@ -2410,6 +4034,15 @@ packages: engines: {node: '>= 8'} dev: true + /micromark@2.11.4: + resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==} + dependencies: + debug: 4.3.4 + parse-entities: 2.0.0 + transitivePeerDependencies: + - supports-color + dev: true + /micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} @@ -2437,6 +4070,11 @@ packages: requiresBuild: true optional: true + /min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + dev: true + /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: @@ -2456,6 +4094,10 @@ packages: brace-expansion: 2.0.1 dev: true + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true + /mlly@1.4.2: resolution: {integrity: sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==} dependencies: @@ -2472,7 +4114,6 @@ packages: /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} requiresBuild: true - optional: true /muggle-string@0.3.1: resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==} @@ -2495,6 +4136,10 @@ packages: resolution: {integrity: sha512-fzN+T2K7/Ah25XU02MJkPZ5q4Tj5FpjmIYq4rvoHX4yb16HzFdCO6JxFFn5Y/oBhQ8no8fUZavnyIv9/+xkBBw==} dev: false + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + /needle@3.2.0: resolution: {integrity: sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==} engines: {node: '>= 4.4.x'} @@ -2526,6 +4171,15 @@ packages: resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} dev: true + /normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.8 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + dev: true + /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -2556,11 +4210,102 @@ packages: engines: {node: '>= 6'} dev: true + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + dev: true + + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign@4.1.4: + resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /object.fromentries@2.0.7: + resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + + /object.groupby@1.0.1: + resolution: {integrity: sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 + dev: true + + /object.values@1.1.7: + resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: wrappy: 1.0.2 + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + /param-case@3.0.4: resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} dependencies: @@ -2573,7 +4318,17 @@ packages: engines: {node: '>=6'} dependencies: callsites: 3.1.0 - dev: false + + /parse-entities@2.0.0: + resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} + dependencies: + character-entities: 1.2.4 + character-entities-legacy: 1.1.4 + character-reference-invalid: 1.1.4 + is-alphanumerical: 1.0.4 + is-decimal: 1.0.4 + is-hexadecimal: 1.0.4 + dev: true /parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} @@ -2583,7 +4338,6 @@ packages: error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - dev: false /parse-node-version@1.0.1: resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==} @@ -2610,10 +4364,20 @@ packages: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} dev: true + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} dev: true @@ -2621,7 +4385,6 @@ packages: /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - dev: false /pathe@0.2.0: resolution: {integrity: sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==} @@ -2689,6 +4452,11 @@ packages: pathe: 1.1.1 dev: true + /pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + dev: true + /pofile@1.0.11: resolution: {integrity: sha512-Vy9eH1dRD9wHjYt/QqXcTz+RnX/zg53xK+KljFSX30PvdDMb2z+c6uDUeblUGqqJgz3QFsdlA0IJvHziPmWtQg==} dev: false @@ -2766,6 +4534,11 @@ packages: picocolors: 1.0.0 source-map-js: 1.0.2 + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} dev: false @@ -2775,6 +4548,11 @@ packages: requiresBuild: true optional: true + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + dev: true + /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true @@ -2785,6 +4563,25 @@ packages: pify: 2.3.0 dev: true + /read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + dev: true + + /read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + dev: true + /readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -2800,6 +4597,27 @@ packages: resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} dev: false + /regexp-tree@0.1.27: + resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} + hasBin: true + dev: true + + /regexp.prototype.flags@1.5.1: + resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + set-function-name: 2.0.1 + dev: true + + /regjsparser@0.10.0: + resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==} + hasBin: true + dependencies: + jsesc: 0.5.0 + dev: true + /relateurl@0.2.7: resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} engines: {node: '>= 0.10'} @@ -2812,7 +4630,10 @@ packages: /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} - dev: false + + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true /resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} @@ -2833,7 +4654,6 @@ packages: hasBin: true dependencies: glob: 7.2.3 - dev: false /rollup@3.29.4: resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==} @@ -2869,6 +4689,24 @@ packages: queue-microtask: 1.2.3 dev: true + /safe-array-concat@1.0.1: + resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + has-symbols: 1.0.3 + isarray: 2.0.5 + dev: true + + /safe-regex-test@1.0.0: + resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + is-regex: 1.1.4 + dev: true + /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} requiresBuild: true @@ -2893,7 +4731,6 @@ packages: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true requiresBuild: true - optional: true /semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} @@ -2908,10 +4745,54 @@ packages: lru-cache: 6.0.0 dev: true + /set-function-length@1.1.1: + resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + dev: true + + /set-function-name@2.0.1: + resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.1 + dev: true + /shallow-equal@1.2.1: resolution: {integrity: sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==} dev: false + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /side-channel@1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + object-inspect: 1.13.1 + dev: true + + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + /sortablejs@1.14.0: resolution: {integrity: sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==} dev: false @@ -2935,6 +4816,77 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + /spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.16 + dev: true + + /spdx-exceptions@2.3.0: + resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + dev: true + + /spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + dependencies: + spdx-exceptions: 2.3.0 + spdx-license-ids: 3.0.16 + dev: true + + /spdx-license-ids@3.0.16: + resolution: {integrity: sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==} + dev: true + + /string.prototype.trim@1.2.8: + resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + + /string.prototype.trimend@1.0.7: + resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + + /string.prototype.trimstart@1.0.7: + resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + dependencies: + min-indent: 1.0.1 + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + /strip-literal@1.3.0: resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} dependencies: @@ -3079,6 +5031,11 @@ packages: - ts-node dev: true + /tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + dev: true + /terser@5.24.0: resolution: {integrity: sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw==} engines: {node: '>=10'} @@ -3090,6 +5047,10 @@ packages: source-map-support: 0.5.21 dev: true + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + /thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -3119,13 +5080,105 @@ packages: is-number: 7.0.0 dev: true + /ts-api-utils@1.0.3(typescript@5.3.2): + resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} + engines: {node: '>=16.13.0'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 5.3.2 + dev: true + /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} dev: true + /tsconfig-paths@3.14.2: + resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + dev: true + + /tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: true + /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + /tsutils@3.21.0(typescript@5.3.2): + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + dependencies: + tslib: 1.14.1 + typescript: 5.3.2 + dev: true + + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + + /type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + dev: true + + /type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + dev: true + + /typed-array-buffer@1.0.0: + resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + is-typed-array: 1.1.12 + dev: true + + /typed-array-byte-length@1.0.0: + resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + for-each: 0.3.3 + has-proto: 1.0.1 + is-typed-array: 1.1.12 + dev: true + + /typed-array-byte-offset@1.0.0: + resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.5 + for-each: 0.3.3 + has-proto: 1.0.1 + is-typed-array: 1.1.12 + dev: true + + /typed-array-length@1.0.4: + resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + dependencies: + call-bind: 1.0.5 + for-each: 0.3.3 + is-typed-array: 1.1.12 + dev: true + /typescript@4.9.5: resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} engines: {node: '>=4.2.0'} @@ -3146,6 +5199,15 @@ packages: resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==} dev: true + /unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.5 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} dev: false @@ -3168,12 +5230,18 @@ packages: - rollup dev: true + /unist-util-stringify-position@2.0.3: + resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} + dependencies: + '@types/unist': 2.0.10 + dev: true + /universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} dev: true - /unplugin-auto-import@0.17.1: + /unplugin-auto-import@0.17.1(@vueuse/core@10.6.1): resolution: {integrity: sha512-QvdJKtFK0COSuRXzVnwjG3ir870zVhdMg6O8GKG3UO/O5W4fmJm5h71QvzI7Gp8Sx0qfCvC3f+2v0Vm489fnqQ==} engines: {node: '>=14'} peerDependencies: @@ -3187,6 +5255,7 @@ packages: dependencies: '@antfu/utils': 0.7.6 '@rollup/pluginutils': 5.0.5 + '@vueuse/core': 10.6.1(vue@3.3.9) fast-glob: 3.3.2 local-pkg: 0.5.0 magic-string: 0.30.5 @@ -3258,10 +5327,23 @@ packages: picocolors: 1.0.0 dev: true + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.1 + dev: true + /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true + /validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + dev: true + /vite-plugin-build-id@0.2.3(less@4.2.0): resolution: {integrity: sha512-PJf7cOpmAcW4KXh7NlqLAp9/7KxeaoQSXEBFmSkN460w70VGVCJfCcSy7IWpyyiKMbbm2VkTTUBwxrBnDv/YgQ==} dependencies: @@ -3393,7 +5475,24 @@ packages: optional: true dependencies: vue: 3.3.9(typescript@5.3.2) - dev: false + + /vue-eslint-parser@9.3.2(eslint@8.54.0): + resolution: {integrity: sha512-q7tWyCVaV9f8iQyIA5Mkj/S6AoJ9KBN8IeUSf3XEmBrOtxOZnfTg5s4KClbZBCK3GtnT/+RyCLZyDHuZwTuBjg==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + debug: 4.3.4 + eslint: 8.54.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + lodash: 4.17.21 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + dev: true /vue-router@4.2.5(vue@3.3.9): resolution: {integrity: sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw==} @@ -3514,9 +5613,43 @@ packages: resolution: {integrity: sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==} dev: true + /which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which-typed-array@1.1.13: + resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.5 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + /xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + dev: true + /xterm-addon-attach@0.9.0(xterm@5.3.0): resolution: {integrity: sha512-NykWWOsobVZPPK3P9eFkItrnBK9Lw0f94uey5zhqIVB1bhswdVBfl+uziEzSOhe2h0rT9wD0wOeAYsdSXeavPw==} peerDependencies: @@ -3545,6 +5678,15 @@ packages: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true + /yaml-eslint-parser@1.2.2: + resolution: {integrity: sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg==} + engines: {node: ^14.17.0 || >=16.0.0} + dependencies: + eslint-visitor-keys: 3.4.3 + lodash: 4.17.21 + yaml: 2.3.4 + dev: true + /yaml@1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} @@ -3555,6 +5697,11 @@ packages: engines: {node: '>= 14'} dev: true + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true + github.com/0xJacky/vue-github-button/fc3c93355a790d3249de6610de3ebe35949ee314: resolution: {tarball: https://codeload.github.com/0xJacky/vue-github-button/tar.gz/fc3c93355a790d3249de6610de3ebe35949ee314} name: vue-github-button diff --git a/app/src/App.vue b/app/src/App.vue index 37654e9d..f27b4070 100644 --- a/app/src/App.vue +++ b/app/src/App.vue @@ -1,25 +1,26 @@ diff --git a/app/src/components/Chart/RadialBarChart.vue b/app/src/components/Chart/RadialBarChart.vue index de2b51bb..af1a2fa6 100644 --- a/app/src/components/Chart/RadialBarChart.vue +++ b/app/src/components/Chart/RadialBarChart.vue @@ -1,21 +1,28 @@ - diff --git a/app/src/components/StdDataEntry/index.tsx b/app/src/components/StdDataEntry/index.tsx deleted file mode 100644 index 8dfd62ab..00000000 --- a/app/src/components/StdDataEntry/index.tsx +++ /dev/null @@ -1,133 +0,0 @@ -import StdDataEntry from './StdDataEntry.js' -import {h} from 'vue' -import {Input, InputNumber, Switch, Textarea} from 'ant-design-vue' -import StdSelector from './components/StdSelector.vue' -import StdSelect from './components/StdSelect.vue' -import StdPassword from './components/StdPassword.vue' - -interface IEdit { - type: Function - placeholder: any - mask: any - key: any - value: any - recordValueIndex: any - selectionType: any - api: Object, - columns: any, - data_key: any, - disable_search: boolean, - get_params: Object, - description: string - generate: boolean - min: number - max: number, - extra: string -} - -function fn(obj: Object, desc: any) { - let arr: string[] - if (typeof desc === 'string') { - arr = desc.split('.') - } else { - arr = [...desc] - } - - while (arr.length) { - // @ts-ignore - const top = obj[arr.shift()] - if (top === undefined) { - return null - } - obj = top - } - return obj -} - -function readonly(edit: IEdit, dataSource: any, dataIndex: any) { - return h('p', fn(dataSource, dataIndex)) -} - -function input(edit: IEdit, dataSource: any, dataIndex: any) { - return h(Input, { - placeholder: edit.placeholder?.() ?? '', - value: dataSource?.[dataIndex], - 'onUpdate:value': value => { - dataSource[dataIndex] = value - } - }) -} - -function inputNumber(edit: IEdit, dataSource: any, dataIndex: any) { - return h(InputNumber, { - placeholder: edit.placeholder?.() ?? '', - min: edit.min, - max: edit.max, - value: dataSource?.[dataIndex], - 'onUpdate:value': value => { - dataSource[dataIndex] = value - } - }) -} - -function textarea(edit: IEdit, dataSource: any, dataIndex: any) { - return h(Textarea, { - placeholder: edit.placeholder?.() ?? '', - value: dataSource?.[dataIndex], - 'onUpdate:value': value => { - dataSource[dataIndex] = value - } - }) -} - -function password(edit: IEdit, dataSource: any, dataIndex: any) { - return -} - -function select(edit: IEdit, dataSource: any, dataIndex: any) { - return -} - -function selector(edit: IEdit, dataSource: any, dataIndex: any) { - return -} - -function antSwitch(edit: IEdit, dataSource: any, dataIndex: any) { - return h(Switch, { - checked: dataSource?.[dataIndex], - 'onUpdate:checked': (value: any) => { - dataSource[dataIndex] = value - } - }) -} - -export { - readonly, - input, - textarea, - select, - selector, - password, - inputNumber, - antSwitch -} - -export default StdDataEntry diff --git a/app/src/components/StdDataDisplay/StdBatchEdit.vue b/app/src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue similarity index 69% rename from app/src/components/StdDataDisplay/StdBatchEdit.vue rename to app/src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue index 25d0f914..57d9faaa 100644 --- a/app/src/components/StdDataDisplay/StdBatchEdit.vue +++ b/app/src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue @@ -1,21 +1,24 @@ diff --git a/app/src/components/StdDataEntry/components/StdSelector.vue b/app/src/components/StdDesign/StdDataEntry/components/StdSelector.vue similarity index 58% rename from app/src/components/StdDataEntry/components/StdSelector.vue rename to app/src/components/StdDesign/StdDataEntry/components/StdSelector.vue index 303ada52..a182a625 100644 --- a/app/src/components/StdDataEntry/components/StdSelector.vue +++ b/app/src/components/StdDesign/StdDataEntry/components/StdSelector.vue @@ -1,13 +1,25 @@ diff --git a/app/src/components/StdDesign/StdDataEntry/index.tsx b/app/src/components/StdDesign/StdDataEntry/index.tsx new file mode 100644 index 00000000..82741714 --- /dev/null +++ b/app/src/components/StdDesign/StdDataEntry/index.tsx @@ -0,0 +1,101 @@ +import { h } from 'vue' +import { Input, InputNumber, Switch, Textarea } from 'ant-design-vue' +import _ from 'lodash' +import StdDataEntry from './StdDataEntry' +import StdSelector from './components/StdSelector.vue' +import StdSelect from './components/StdSelect.vue' +import StdPassword from './components/StdPassword.vue' +import type { StdDesignEdit } from '@/components/StdDesign/types' + +const fn = _.get +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function readonly(edit: StdDesignEdit, dataSource: any, dataIndex: any) { + return h('p', fn(dataSource, dataIndex)) +} + +function placeholder_helper(edit: StdDesignEdit) { + return typeof edit.config?.placeholder === 'function' ? edit.config?.placeholder() : edit.config?.placeholder +} +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function input(edit: StdDesignEdit, dataSource: any, dataIndex: any) { + return h(Input, { + 'placeholder': placeholder_helper(edit), + 'value': dataSource?.[dataIndex], + 'onUpdate:value': value => { + dataSource[dataIndex] = value + }, + }) +} +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function inputNumber(edit: StdDesignEdit, dataSource: any, dataIndex: any) { + return h(InputNumber, { + 'placeholder': placeholder_helper(edit), + 'min': edit.config?.min, + 'max': edit.config?.max, + 'value': dataSource?.[dataIndex], + 'onUpdate:value': value => { + dataSource[dataIndex] = value + }, + }) +} +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function textarea(edit: StdDesignEdit, dataSource: any, dataIndex: any) { + return h(Textarea, { + 'placeholder': placeholder_helper(edit), + 'value': dataSource?.[dataIndex], + 'onUpdate:value': value => { + dataSource[dataIndex] = value + }, + }) +} +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function password(edit: StdDesignEdit, dataSource: any, dataIndex: any) { + return +} +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function select(edit: StdDesignEdit, dataSource: any, dataIndex: any) { + return +} +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function selector(edit: StdDesignEdit, dataSource: any, dataIndex: any) { + return +} +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function switcher(edit: StdDesignEdit, dataSource: any, dataIndex: any) { + return h(Switch, { + 'checked': dataSource?.[dataIndex], + // eslint-disable-next-line @typescript-eslint/no-explicit-any + 'onUpdate:checked': (value: any) => { + dataSource[dataIndex] = value + }, + }) +} + +export { + readonly, + input, + textarea, + select, + selector, + password, + inputNumber, + switcher, +} + +export default StdDataEntry diff --git a/app/src/components/StdDataEntry/style.less b/app/src/components/StdDesign/StdDataEntry/style.less similarity index 100% rename from app/src/components/StdDataEntry/style.less rename to app/src/components/StdDesign/StdDataEntry/style.less diff --git a/app/src/components/StdDesign/types.d.ts b/app/src/components/StdDesign/types.d.ts new file mode 100644 index 00000000..316b073d --- /dev/null +++ b/app/src/components/StdDesign/types.d.ts @@ -0,0 +1,49 @@ +import Curd from '@/api/curd' +import {IKeyEvt} from '@/components/StdDesign/StdDataDisplay/types' +import {Ref} from 'vue' + +export interface StdDesignEdit { + type?: function // component type + + mask?: { + [key: string]: () => string + } // use for select-option + + rules?: [] // validator rules + + selector?: { + get_params?: {} + recordValueIndex: any // relative to api return + selectionType: any + api: Curd, + valueApi?: Curd, + columns: any + disable_search?: boolean + description?: string + bind?: any + itemKey?: any // default is id + dataSourceValueIndex?: any // relative to dataSource + } // StdSelector Config + + config?: { + label?: string | (() => string) // label for form item + size?: string // class size of Std image upload + placeholder?: string | (() => string) // placeholder for input + generate?: boolean // generate btn for StdPassword + min?: number // min value for input number + max?: number // max value for input number + error_messages?: Ref + hint?: string | (() => string) // hint form item + } + + flex?: Flex +} + + +export interface Flex { + sm?: string | number | boolean + md?: string | number | boolean + lg?: string | number | boolean + xl?: string | number | boolean + xxl?: string | number | boolean +} diff --git a/app/src/components/SwitchAppearance/SwitchAppearance.vue b/app/src/components/SwitchAppearance/SwitchAppearance.vue index ef623595..3dc59864 100644 --- a/app/src/components/SwitchAppearance/SwitchAppearance.vue +++ b/app/src/components/SwitchAppearance/SwitchAppearance.vue @@ -1,12 +1,13 @@ @@ -38,8 +37,8 @@ async function toggleAppearance() { :aria-checked="isDark" @click="toggleAppearance" > - - + + diff --git a/app/src/components/SwitchAppearance/icons/VPIconMoon.vue b/app/src/components/SwitchAppearance/icons/VPIconMoon.vue index a6bc34cd..1907e541 100644 --- a/app/src/components/SwitchAppearance/icons/VPIconMoon.vue +++ b/app/src/components/SwitchAppearance/icons/VPIconMoon.vue @@ -1,6 +1,10 @@ diff --git a/app/src/components/SwitchAppearance/icons/VPIconSun.vue b/app/src/components/SwitchAppearance/icons/VPIconSun.vue index 622df216..64abf464 100644 --- a/app/src/components/SwitchAppearance/icons/VPIconSun.vue +++ b/app/src/components/SwitchAppearance/icons/VPIconSun.vue @@ -1,18 +1,18 @@ diff --git a/app/src/components/VPSwitch/VPSwitch.vue b/app/src/components/VPSwitch/VPSwitch.vue index 27df45d1..6f1677f8 100644 --- a/app/src/components/VPSwitch/VPSwitch.vue +++ b/app/src/components/VPSwitch/VPSwitch.vue @@ -1,8 +1,15 @@