From 8dca0afc083825ebbd4d0a805eb3a1340de6dd39 Mon Sep 17 00:00:00 2001 From: chris <5303221@gmail.com> Date: Mon, 1 Apr 2024 00:26:39 +0800 Subject: [PATCH] docs: update Server --- docs/404.html | 4 +- docs/architecture.html | 10 +-- .../{app.Cm_CKtZi.js => app.C-CesJ6t.js} | 2 +- ...gxL.js => @localSearchIndexen.ZbBo-S2V.js} | 2 +- .../chunks/@localSearchIndexroot.BKsY5Ty1.js | 1 - .../chunks/@localSearchIndexroot.R25TFYOj.js | 1 + ...8VqG1H.js => VPLocalSearchBox.Bp9Nb2eD.js} | 2 +- docs/assets/chunks/metadata.622e4ed2.js | 1 - docs/assets/chunks/metadata.ae0ba16e.js | 1 + .../{theme.VdBoP6hP.js => theme.B8LElrRV.js} | 4 +- ...{cli.md.S0KmBxg6.js => cli.md.C_7YL7i5.js} | 2 +- ...KmBxg6.lean.js => cli.md.C_7YL7i5.lean.js} | 2 +- ...CLxj.js => getting-started.md.Be3tXPfD.js} | 4 +- ...js => getting-started.md.Be3tXPfD.lean.js} | 2 +- docs/assets/grpc.md.CeHujcK9.js | 1 + docs/assets/grpc.md.CeHujcK9.lean.js | 1 + docs/assets/http.md.Bm5lEonH.js | 9 +++ docs/assets/http.md.Bm5lEonH.lean.js | 1 + docs/assets/job.md.CSi1p9px.js | 1 + docs/assets/job.md.CSi1p9px.lean.js | 1 + docs/assets/migration.md.BDgzs4ZZ.js | 1 + docs/assets/migration.md.BDgzs4ZZ.lean.js | 1 + docs/assets/server.md.BzwyYWXt.js | 33 ++++++++++ docs/assets/server.md.BzwyYWXt.lean.js | 1 + docs/assets/server.md.yFMvW0F3.js | 4 -- docs/assets/server.md.yFMvW0F3.lean.js | 1 - docs/assets/task.md.eQQGFK-A.js | 1 + docs/assets/task.md.eQQGFK-A.lean.js | 1 + docs/assets/websocket.md.BB9hRzFp.js | 1 + docs/assets/websocket.md.BB9hRzFp.lean.js | 1 + docs/cli.html | 10 +-- docs/database.html | 8 +-- docs/docker.html | 8 +-- docs/en/architecture.html | 8 +-- docs/en/cli.html | 8 +-- docs/en/database.html | 8 +-- docs/en/docker.html | 8 +-- docs/en/foo.html | 8 +-- docs/en/getting-started.html | 8 +-- docs/en/guide.html | 8 +-- docs/en/handler.html | 8 +-- docs/en/index.html | 6 +- docs/en/k8s.html | 8 +-- docs/en/logger.html | 8 +-- docs/en/middleware.html | 8 +-- docs/en/model.html | 8 +-- docs/en/nginx.html | 8 +-- docs/en/pkg.html | 8 +-- docs/en/pr.html | 8 +-- docs/en/redis.html | 8 +-- docs/en/repository.html | 8 +-- docs/en/server.html | 8 +-- docs/en/service.html | 8 +-- docs/en/swagger.html | 8 +-- docs/en/swarm.html | 8 +-- docs/en/unit-test.html | 8 +-- docs/en/wire.html | 8 +-- docs/foo.html | 8 +-- docs/getting-started.html | 12 ++-- docs/grpc.html | 33 ++++++++++ docs/guide.html | 8 +-- docs/handler.html | 8 +-- docs/hashmap.json | 2 +- docs/http.html | 41 +++++++++++++ docs/index.html | 6 +- docs/job.html | 33 ++++++++++ docs/k8s.html | 8 +-- docs/logger.html | 8 +-- docs/middleware.html | 8 +-- docs/migration.html | 33 ++++++++++ docs/model.html | 8 +-- docs/nginx.html | 10 +-- docs/pkg.html | 8 +-- docs/pr.html | 8 +-- docs/redis.html | 8 +-- docs/repository.html | 8 +-- docs/server.html | 41 +++++++++++-- docs/service.html | 8 +-- docs/sitemap.xml | 2 +- docs/src/.vitepress/config/en.ts | 2 +- docs/src/.vitepress/config/zh.ts | 13 +++- docs/src/.vitepress/dist/en/architecture.html | 8 +-- docs/src/.vitepress/dist/en/cli.html | 8 +-- docs/src/.vitepress/dist/en/database.html | 8 +-- docs/src/.vitepress/dist/en/docker.html | 8 +-- docs/src/.vitepress/dist/en/foo.html | 8 +-- .../.vitepress/dist/en/getting-started.html | 8 +-- docs/src/.vitepress/dist/en/guide.html | 8 +-- docs/src/.vitepress/dist/en/handler.html | 8 +-- docs/src/.vitepress/dist/en/index.html | 6 +- docs/src/.vitepress/dist/en/k8s.html | 8 +-- docs/src/.vitepress/dist/en/logger.html | 8 +-- docs/src/.vitepress/dist/en/middleware.html | 8 +-- docs/src/.vitepress/dist/en/model.html | 8 +-- docs/src/.vitepress/dist/en/nginx.html | 8 +-- docs/src/.vitepress/dist/en/pkg.html | 8 +-- docs/src/.vitepress/dist/en/pr.html | 8 +-- docs/src/.vitepress/dist/en/redis.html | 8 +-- docs/src/.vitepress/dist/en/repository.html | 8 +-- docs/src/.vitepress/dist/en/server.html | 8 +-- docs/src/.vitepress/dist/en/service.html | 8 +-- docs/src/.vitepress/dist/en/swagger.html | 8 +-- docs/src/.vitepress/dist/en/swarm.html | 8 +-- docs/src/.vitepress/dist/en/unit-test.html | 8 +-- docs/src/.vitepress/dist/en/wire.html | 8 +-- docs/src/grpc.md | 3 + docs/src/http.md | 32 ++++++++++ docs/src/job.md | 9 +++ docs/src/migration.md | 11 ++++ docs/src/server.md | 61 +++++++++++-------- docs/src/task.md | 9 +++ docs/src/websocket.md | 3 + docs/swagger.html | 8 +-- docs/swarm.html | 8 +-- docs/task.html | 33 ++++++++++ docs/unit-test.html | 8 +-- docs/websocket.html | 33 ++++++++++ docs/wire.html | 10 +-- 118 files changed, 711 insertions(+), 344 deletions(-) rename docs/assets/{app.Cm_CKtZi.js => app.C-CesJ6t.js} (95%) rename docs/assets/chunks/{@localSearchIndexen.DVdHZgxL.js => @localSearchIndexen.ZbBo-S2V.js} (78%) delete mode 100644 docs/assets/chunks/@localSearchIndexroot.BKsY5Ty1.js create mode 100644 docs/assets/chunks/@localSearchIndexroot.R25TFYOj.js rename docs/assets/chunks/{VPLocalSearchBox.De8VqG1H.js => VPLocalSearchBox.Bp9Nb2eD.js} (99%) delete mode 100644 docs/assets/chunks/metadata.622e4ed2.js create mode 100644 docs/assets/chunks/metadata.ae0ba16e.js rename docs/assets/chunks/{theme.VdBoP6hP.js => theme.B8LElrRV.js} (99%) rename docs/assets/{cli.md.S0KmBxg6.js => cli.md.C_7YL7i5.js} (90%) rename docs/assets/{cli.md.S0KmBxg6.lean.js => cli.md.C_7YL7i5.lean.js} (51%) rename docs/assets/{getting-started.md.Rp5FCLxj.js => getting-started.md.Be3tXPfD.js} (95%) rename docs/assets/{getting-started.md.Rp5FCLxj.lean.js => getting-started.md.Be3tXPfD.lean.js} (84%) create mode 100644 docs/assets/grpc.md.CeHujcK9.js create mode 100644 docs/assets/grpc.md.CeHujcK9.lean.js create mode 100644 docs/assets/http.md.Bm5lEonH.js create mode 100644 docs/assets/http.md.Bm5lEonH.lean.js create mode 100644 docs/assets/job.md.CSi1p9px.js create mode 100644 docs/assets/job.md.CSi1p9px.lean.js create mode 100644 docs/assets/migration.md.BDgzs4ZZ.js create mode 100644 docs/assets/migration.md.BDgzs4ZZ.lean.js create mode 100644 docs/assets/server.md.BzwyYWXt.js create mode 100644 docs/assets/server.md.BzwyYWXt.lean.js delete mode 100644 docs/assets/server.md.yFMvW0F3.js delete mode 100644 docs/assets/server.md.yFMvW0F3.lean.js create mode 100644 docs/assets/task.md.eQQGFK-A.js create mode 100644 docs/assets/task.md.eQQGFK-A.lean.js create mode 100644 docs/assets/websocket.md.BB9hRzFp.js create mode 100644 docs/assets/websocket.md.BB9hRzFp.lean.js create mode 100644 docs/grpc.html create mode 100644 docs/http.html create mode 100644 docs/job.html create mode 100644 docs/migration.html create mode 100644 docs/src/grpc.md create mode 100644 docs/src/http.md create mode 100644 docs/src/job.md create mode 100644 docs/src/migration.md create mode 100644 docs/src/task.md create mode 100644 docs/src/websocket.md create mode 100644 docs/task.html create mode 100644 docs/websocket.html diff --git a/docs/404.html b/docs/404.html index ba2ad59..e5e031a 100644 --- a/docs/404.html +++ b/docs/404.html @@ -7,8 +7,8 @@ - - + + diff --git a/docs/architecture.html b/docs/architecture.html index a993ac3..c813fb9 100644 --- a/docs/architecture.html +++ b/docs/architecture.html @@ -7,11 +7,11 @@ - - + + - + @@ -27,7 +27,7 @@ -
Skip to content

Nunu架构详解

Nunu采用了经典的分层架构。同时,为了更好地实现模块化和解耦,采用了依赖注入框架Wire

Nunu Layout

目录结构

.
+    
Skip to content

Nunu架构详解

Nunu采用了经典的分层架构。同时,为了更好地实现模块化和解耦,采用了依赖注入框架Wire

Nunu Layout

目录结构

.
 ├── api
 │   └── v1
 ├── cmd
@@ -56,7 +56,7 @@
 ├── web
 ├── Makefile
 ├── go.mod
-└── go.sum
  • cmd:应用程序的入口,包含了不同的子命令。
  • config:配置文件。
  • deploy:部署相关的文件,如 Dockerfile 、 docker-compose.yml等。
  • internal:应用程序的主要代码,按照分层架构进行组织。
  • pkg:公共的代码,包括配置、日志、HTTP 等。
  • script:脚本文件,用于部署和其他自动化任务。
  • storage:存储文件,如日志文件。
  • test:测试代码。
  • web:前端代码。

internal

  • internal/handler( or controller):处理 HTTP 请求,调用业务逻辑层的服务,返回 HTTP 响应。
  • internal/server(or router):HTTP 服务器,启动 HTTP 服务,监听端口,处理 HTTP 请求。
  • internal/service(or logic):服务,实现具体的业务逻辑,调用数据访问层repository。
  • internal/model(or entity):数据模型,定义了业务逻辑层需要的数据结构。
  • internal/repository(or dao):数据访问对象,封装了数据库操作,提供了对数据的增删改查。

依赖注入

本项目采用了依赖注入框架Wire,实现了模块化和解耦。Wire通过预编译wire.go,自动生成依赖注入的代码wire_gen.go,简化了依赖注入的过程。

  • cmd/job/wire.goWire配置文件,定义了job子命令需要的依赖关系。
  • cmd/migration/wire.goWire配置文件,定义了migration子命令需要的依赖关系。
  • cmd/server/wire.goWire配置文件,定义了server子命令需要的依赖关系。

Wire官方文档:https://github.com/google/wire/blob/main/docs/guide.md

注意:wire_gen.go文件为自动编译生成,禁止手动修改

公共代码

为了实现代码的复用和统一管理,本项目采用了公共代码的方式,将一些通用的代码放在了pkg目录下。

  • pkg/config:配置文件的读取和解析。
  • pkg/helper:一些通用的辅助函数,如 MD5 加密、UUID 生成等。
  • pkg/http:HTTP 相关的代码,如 HTTP 客户端、HTTP 服务器等。
  • pkg/log:日志相关的代码,如日志的初始化、日志的写入等。
  • more...:当然,你可以自由添加扩展更多的pkg。

基于 MIT 许可发布

+└── go.sum
  • cmd:应用程序的入口,包含了不同的子命令。
  • config:配置文件。
  • deploy:部署相关的文件,如 Dockerfile 、 docker-compose.yml等。
  • internal:应用程序的主要代码,按照分层架构进行组织。
  • pkg:公共的代码,包括配置、日志、HTTP 等。
  • script:脚本文件,用于部署和其他自动化任务。
  • storage:存储文件,如日志文件。
  • test:测试代码。
  • web:前端代码。

internal

  • internal/handler( or controller):处理 HTTP 请求,调用业务逻辑层的服务,返回 HTTP 响应。
  • internal/server(or router):HTTP 服务器,启动 HTTP 服务,监听端口,处理 HTTP 请求。
  • internal/service(or logic):服务,实现具体的业务逻辑,调用数据访问层repository。
  • internal/model(or entity):数据模型,定义了业务逻辑层需要的数据结构。
  • internal/repository(or dao):数据访问对象,封装了数据库操作,提供了对数据的增删改查。

依赖注入

本项目采用了依赖注入框架Wire,实现了模块化和解耦。Wire通过预编译wire.go,自动生成依赖注入的代码wire_gen.go,简化了依赖注入的过程。

  • cmd/job/wire.goWire配置文件,定义了job子命令需要的依赖关系。
  • cmd/migration/wire.goWire配置文件,定义了migration子命令需要的依赖关系。
  • cmd/server/wire.goWire配置文件,定义了server子命令需要的依赖关系。

Wire官方文档:https://github.com/google/wire/blob/main/docs/guide.md

注意:wire_gen.go文件为自动编译生成,禁止手动修改

公共代码

为了实现代码的复用和统一管理,本项目采用了公共代码的方式,将一些通用的代码放在了pkg目录下。

  • pkg/config:配置文件的读取和解析。
  • pkg/helper:一些通用的辅助函数,如 MD5 加密、UUID 生成等。
  • pkg/http:HTTP 相关的代码,如 HTTP 客户端、HTTP 服务器等。
  • pkg/log:日志相关的代码,如日志的初始化、日志的写入等。
  • more...:当然,你可以自由添加扩展更多的pkg。

基于 MIT 许可发布

diff --git a/docs/assets/app.Cm_CKtZi.js b/docs/assets/app.C-CesJ6t.js similarity index 95% rename from docs/assets/app.Cm_CKtZi.js rename to docs/assets/app.C-CesJ6t.js index e6584c0..19e5396 100644 --- a/docs/assets/app.Cm_CKtZi.js +++ b/docs/assets/app.C-CesJ6t.js @@ -1 +1 @@ -import{j as o,a5 as p,a6 as u,a7 as l,a8 as c,a9 as f,aa as d,ab as m,ac as h,ad as g,ae as A,Y as P,d as _,u as v,l as y,z as C,af as E,ag as b,ah as w,ai as R}from"./chunks/framework.DZjeu1b3.js";import{t as S}from"./chunks/theme.VdBoP6hP.js";function i(e){if(e.extends){const a=i(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const s=i(S),T=_({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=v();return y(()=>{C(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&E(),b(),w(),s.setup&&s.setup(),()=>R(s.Layout)}});async function D(){globalThis.__VITEPRESS__=!0;const e=L(),a=j();a.provide(u,e);const t=l(e.route);return a.provide(c,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),s.enhanceApp&&await s.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function j(){return h(T)}function L(){let e=o,a;return g(t=>{let n=A(t),r=null;return n&&(e&&(a=n),(e||a===n)&&(n=n.replace(/\.js$/,".lean.js")),r=P(()=>import(n),[])),o&&(e=!1),r},s.NotFound)}o&&D().then(({app:e,router:a,data:t})=>{a.go().then(()=>{p(a.route,t.site),e.mount("#app")})});export{D as createApp}; +import{j as o,a5 as p,a6 as u,a7 as l,a8 as c,a9 as f,aa as d,ab as m,ac as h,ad as g,ae as A,Y as P,d as _,u as v,l as y,z as C,af as E,ag as b,ah as w,ai as R}from"./chunks/framework.DZjeu1b3.js";import{t as S}from"./chunks/theme.B8LElrRV.js";function i(e){if(e.extends){const a=i(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const s=i(S),T=_({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=v();return y(()=>{C(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&E(),b(),w(),s.setup&&s.setup(),()=>R(s.Layout)}});async function D(){globalThis.__VITEPRESS__=!0;const e=L(),a=j();a.provide(u,e);const t=l(e.route);return a.provide(c,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),s.enhanceApp&&await s.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function j(){return h(T)}function L(){let e=o,a;return g(t=>{let n=A(t),r=null;return n&&(e&&(a=n),(e||a===n)&&(n=n.replace(/\.js$/,".lean.js")),r=P(()=>import(n),[])),o&&(e=!1),r},s.NotFound)}o&&D().then(({app:e,router:a,data:t})=>{a.go().then(()=>{p(a.route,t.site),e.mount("#app")})});export{D as createApp}; diff --git a/docs/assets/chunks/@localSearchIndexen.DVdHZgxL.js b/docs/assets/chunks/@localSearchIndexen.ZbBo-S2V.js similarity index 78% rename from docs/assets/chunks/@localSearchIndexen.DVdHZgxL.js rename to docs/assets/chunks/@localSearchIndexen.ZbBo-S2V.js index 9f264e9..c928632 100644 --- a/docs/assets/chunks/@localSearchIndexen.DVdHZgxL.js +++ b/docs/assets/chunks/@localSearchIndexen.ZbBo-S2V.js @@ -1 +1 @@ -const e='{"documentCount":54,"nextId":54,"documentIds":{"0":"/nunu/en/architecture#nunu架构详解","1":"/nunu/en/architecture#目录结构","2":"/nunu/en/architecture#internal","3":"/nunu/en/architecture#依赖注入","4":"/nunu/en/architecture#公共代码","5":"/nunu/en/cli#info","6":"/nunu/en/cli#new","7":"/nunu/en/cli#run","8":"/nunu/en/cli#create","9":"/nunu/en/cli#创建handler","10":"/nunu/en/cli#waire","11":"/nunu/en/cli#upgrade","12":"/nunu/en/database#数据库","13":"/nunu/en/docker#docker","14":"/nunu/en/docker#镜像构建","15":"/nunu/en/docker#容器运行","16":"/nunu/en/getting-started#install","17":"/nunu/en/getting-started#创建新项目","18":"/nunu/en/getting-started#启动服务","19":"/nunu/en/guide#what-is-nunu","20":"/nunu/en/guide#developer-experience","21":"/nunu/en/guide#performance","22":"/nunu/en/handler#handler","23":"/nunu/en/k8s#k8s集群部署","24":"/nunu/en/logger#日志功能","25":"/nunu/en/middleware#http中间件","26":"/nunu/en/middleware#限流器","27":"/nunu/en/middleware#日志trace","28":"/nunu/en/middleware#签名验证","29":"/nunu/en/middleware#跨域","30":"/nunu/en/model#model","31":"/nunu/en/nginx#非容器部署-pm2-nginx","32":"/nunu/en/nginx#pm2","33":"/nunu/en/nginx#nginx配置","34":"/nunu/en/pkg#扩展包","35":"/nunu/en/pr#贡献指南","36":"/nunu/en/redis#redis","37":"/nunu/en/repository#repository","38":"/nunu/en/server#server基础概念","39":"/nunu/en/server#http","40":"/nunu/en/server#task","41":"/nunu/en/server#job","42":"/nunu/en/server#migration","43":"/nunu/en/service#service","44":"/nunu/en/swagger#自动化文档","45":"/nunu/en/swarm#docker-swarm集群部署","46":"/nunu/en/swarm#swarm-yml配置","47":"/nunu/en/swarm#滚动更新","48":"/nunu/en/unit-test#单元测试","49":"/nunu/en/wire#依赖注入","50":"/nunu/en/wire#why-do-we-need-dependency-injection","51":"/nunu/en/wire#global-variable-issues","52":"/nunu/en/wire#manual-dependency-injection","53":"/nunu/en/wire#automatic-dependency-injection"},"fieldIds":{"title":0,"titles":1,"text":2},"fieldLength":{"0":[1,1,5],"1":[1,1,55],"2":[1,1,30],"3":[1,1,30],"4":[1,1,26],"5":[1,1,13],"6":[1,1,4],"7":[1,1,3],"8":[1,1,6],"9":[1,2,5],"10":[1,1,4],"11":[1,1,3],"12":[1,1,1],"13":[1,1,1],"14":[1,1,1],"15":[1,1,1],"16":[1,1,27],"17":[1,1,45],"18":[1,1,22],"19":[3,1,11],"20":[1,3,16],"21":[1,3,13],"22":[1,1,1],"23":[1,1,1],"24":[1,1,1],"25":[1,1,1],"26":[1,1,1],"27":[1,1,1],"28":[1,1,1],"29":[1,1,1],"30":[1,1,1],"31":[3,1,1],"32":[1,3,35],"33":[1,3,87],"34":[1,1,1],"35":[1,1,1],"36":[1,1,1],"37":[1,1,1],"38":[1,1,19],"39":[1,1,6],"40":[1,1,6],"41":[1,1,6],"42":[1,1,6],"43":[1,1,1],"44":[1,1,1],"45":[2,1,1],"46":[2,2,1],"47":[1,2,1],"48":[1,1,1],"49":[1,1,1],"50":[2,1,6],"51":[1,1,65],"52":[1,1,59],"53":[1,1,147]},"averageFieldLength":[1.1296296296296298,1.2037037037037037,14.53703703703704],"storedFields":{"0":{"title":"Nunu架构详解","titles":[]},"1":{"title":"目录结构","titles":["Nunu架构详解"]},"2":{"title":"internal","titles":["Nunu架构详解"]},"3":{"title":"依赖注入","titles":["Nunu架构详解"]},"4":{"title":"公共代码","titles":["Nunu架构详解"]},"5":{"title":"nunu命令行工具","titles":[]},"6":{"title":"创建项目","titles":["nunu命令行工具"]},"7":{"title":"启动项目","titles":["nunu命令行工具"]},"8":{"title":"创建组件","titles":["nunu命令行工具"]},"9":{"title":"创建handler","titles":["nunu命令行工具","创建组件"]},"10":{"title":"编译wire","titles":["nunu命令行工具"]},"11":{"title":"版本升级","titles":["nunu命令行工具"]},"12":{"title":"数据库","titles":[]},"13":{"title":"Docker","titles":[]},"14":{"title":"镜像构建","titles":["Docker"]},"15":{"title":"容器运行","titles":["Docker"]},"16":{"title":"安装","titles":[]},"17":{"title":"创建新项目","titles":[]},"18":{"title":"启动服务","titles":[]},"19":{"title":"Nunu 是什么?","titles":[]},"20":{"title":"开发体验","titles":["Nunu 是什么?"]},"21":{"title":"性能","titles":["Nunu 是什么?"]},"22":{"title":"Handler","titles":[]},"23":{"title":"k8s集群部署","titles":[]},"24":{"title":"日志功能","titles":[]},"25":{"title":"HTTP中间件","titles":[]},"26":{"title":"限流器","titles":["HTTP中间件"]},"27":{"title":"日志Trace","titles":["HTTP中间件"]},"28":{"title":"签名验证","titles":["HTTP中间件"]},"29":{"title":"跨域","titles":["HTTP中间件"]},"30":{"title":"Model","titles":[]},"31":{"title":"非容器部署(PM2+Nginx)","titles":[]},"32":{"title":"PM2","titles":["非容器部署(PM2+Nginx)"]},"33":{"title":"Nginx配置","titles":["非容器部署(PM2+Nginx)"]},"34":{"title":"扩展包","titles":[]},"35":{"title":"贡献指南","titles":[]},"36":{"title":"Redis","titles":[]},"37":{"title":"Repository","titles":[]},"38":{"title":"Server基础概念","titles":[]},"39":{"title":"HTTP","titles":["Server基础概念"]},"40":{"title":"Task","titles":["Server基础概念"]},"41":{"title":"Job","titles":["Server基础概念"]},"42":{"title":"Migration","titles":["Server基础概念"]},"43":{"title":"Service","titles":[]},"44":{"title":"自动化文档","titles":[]},"45":{"title":"Docker Swarm集群部署","titles":[]},"46":{"title":"swarm.yml配置","titles":["Docker Swarm集群部署"]},"47":{"title":"滚动更新","titles":["Docker Swarm集群部署"]},"48":{"title":"单元测试","titles":[]},"49":{"title":"依赖注入","titles":[]},"50":{"title":"为什么需要依赖注入?","titles":["依赖注入"]},"51":{"title":"全局变量","titles":["依赖注入"]},"52":{"title":"手动依赖注入","titles":["依赖注入"]},"53":{"title":"自动依赖注入","titles":["依赖注入"]}},"dirtCount":0,"index":[["前往到wire官方文档",{"2":{"53":1}}],["前端代码",{"2":{"1":1}}],["想学习更多关于wire知识",{"2":{"53":1}}],["代码大概像下面这样",{"2":{"53":1}}],["代码变得更易于理解和维护",{"2":{"52":1}}],["声明依赖关系的代码非常简单",{"2":{"53":1}}],["就会自动帮我们生成代码",{"2":{"53":1}}],["执行wire命令后",{"2":{"53":1}}],["但其实这段代码并不是人工手写的",{"2":{"53":1}}],["但是在调用该函数之前",{"2":{"51":1}}],["相信你一定会感觉依赖注入使我们代码使变得复杂",{"2":{"53":1}}],["相关的代码",{"2":{"4":1}}],["看到这样的代码",{"2":{"53":1}}],["手动进行依赖注入可能会变得繁琐",{"2":{"53":1}}],["手动依赖注入",{"0":{"52":1}}],["的行为",{"2":{"52":1}}],["的目录",{"2":{"17":1}}],["现在我们可以轻松地通过传递模拟的数据库连接来测试",{"2":{"52":1}}],["易于测试",{"2":{"52":1}}],["更易于重用和测试",{"2":{"52":1}}],["解耦",{"2":{"52":1}}],["函数",{"2":{"52":1}}],["作为参数传递给",{"2":{"52":1}}],["来执行数据库操作",{"2":{"52":1}}],["来保存数据库连接",{"2":{"51":1}}],["下面是使用依赖注入改进上面示例的代码",{"2":{"52":1}}],["方法参数或者其他方式传递进来",{"2":{"52":1}}],["依赖关系不再硬编码到组件内部",{"2":{"52":1}}],["依赖注入可以帮助解决这些问题",{"2":{"52":1}}],["依赖注入是一种编程模式",{"2":{"50":1}}],["依赖注入",{"0":{"3":1,"49":1},"1":{"50":1,"51":1,"52":1,"53":1}}],["降低了代码的可维护性",{"2":{"51":1}}],["当项目变得庞大时",{"2":{"53":1}}],["当代码规模增大时",{"2":{"51":1}}],["当然",{"2":{"4":1}}],["使得",{"2":{"52":1}}],["使得代码难以重构和维护",{"2":{"51":1}}],["使用服务进行操作",{"2":{"52":1}}],["使用",{"2":{"52":1}}],["使用全局变量",{"2":{"51":1}}],["使用基础模板",{"2":{"17":1}}],["使用高级模板",{"2":{"17":1}}],["从而改变函数的行为",{"2":{"51":1}}],["从而引发难以调试的错误",{"2":{"51":1}}],["另一个部分的代码可能会修改该全局变量",{"2":{"51":1}}],["例如",{"2":{"51":1}}],["不可控的副作用",{"2":{"51":1}}],["因为在测试过程中很难控制全局变量的状态",{"2":{"51":1}}],["因此",{"2":{"39":1,"40":1,"41":1,"42":1}}],["难以测试",{"2":{"51":1}}],["很容易引发意外的行为",{"2":{"51":1}}],["多个并发执行的程序可能会同时访问和修改全局变量",{"2":{"51":1}}],["并将数据库连接传递进去",{"2":{"52":1}}],["并发安全问题",{"2":{"51":1}}],["并在其中生成一个优雅的",{"2":{"17":1}}],["=",{"2":{"51":1,"52":2,"53":44}}],["初始化数据库连接",{"2":{"51":1,"52":1}}],["viper",{"2":{"53":2}}],["viperviper",{"2":{"53":13}}],["var",{"2":{"51":1,"53":4}}],["v1",{"2":{"1":1}}],["假设我们有一个简单的服务",{"2":{"51":1}}],["语言示例来说明",{"2":{"51":1}}],["语言编写的web框架",{"2":{"21":1}}],["让我们通过一个简单的",{"2":{"51":1}}],["全局变量会导致代码难以理解和修改",{"2":{"51":1}}],["全局变量增加了代码的耦合性",{"2":{"51":1}}],["全局变量的值可以在程序的任何地方被修改",{"2":{"51":1}}],["全局变量的状态不受控制",{"2":{"51":1}}],["全局变量使得单元测试变得困难",{"2":{"51":1}}],["全局变量",{"0":{"51":1}}],["这样做带来了以下好处",{"2":{"52":1}}],["这样做可能会引发以下问题",{"2":{"51":1}}],["这可能导致不可预测的副作用",{"2":{"51":1}}],["这可能导致测试覆盖不全或者需要编写更多的集成测试来覆盖全局变量的不同状态",{"2":{"51":1}}],["这可能导致竞态条件和数据竞争",{"2":{"51":1}}],["这里可能会有很多其他的逻辑",{"2":{"51":1}}],["这种方式会带来一些问题",{"2":{"50":1}}],["这是因为环境变量没有配置",{"2":{"16":1}}],["通常会使用全局变量或硬编码的方式来获取所需的依赖",{"2":{"50":1}}],["通过明确地传递依赖关系",{"2":{"52":1}}],["通过",{"2":{"5":1}}],["用于管理代码中各个组件之间的依赖关系",{"2":{"50":1}}],["用于部署和其他自动化任务",{"2":{"1":1}}],["为什么需要依赖注入",{"0":{"50":1}}],["为了实现代码的复用和统一管理",{"2":{"4":1}}],["为了更好地实现模块化和解耦",{"2":{"0":1}}],["单元测试",{"0":{"48":1}}],["滚动更新",{"0":{"47":1}}],["自动依赖注入",{"0":{"53":1}}],["自动化文档",{"0":{"44":1}}],["自动生成依赖注入的代码wire",{"2":{"3":1}}],["也就是start",{"2":{"38":1}}],["每个server都必须实现server接口中的方法",{"2":{"38":1}}],["\\t\\tnewapp",{"2":{"53":1}}],["\\t\\tjwt",{"2":{"53":1}}],["\\t\\tsid",{"2":{"53":1}}],["\\t\\tserverset",{"2":{"53":1}}],["\\t\\tserviceset",{"2":{"53":1}}],["\\t\\thandlerset",{"2":{"53":1}}],["\\t\\trepositoryset",{"2":{"53":1}}],["\\t\\tapp",{"2":{"53":2}}],["\\tpanic",{"2":{"53":1}}],["\\treturn",{"2":{"53":1}}],["\\trepository",{"2":{"53":6}}],["\\tserver",{"2":{"53":3}}],["\\tservice",{"2":{"53":2}}],["\\tstop",{"2":{"38":1}}],["\\tstart",{"2":{"38":1}}],["\\thandler",{"2":{"53":3}}],["\\tdb",{"2":{"51":1}}],["\\t",{"2":{"51":5,"53":2}}],["\\tlisten",{"2":{"33":1}}],["在依赖注入中",{"2":{"52":1}}],["在并发环境中",{"2":{"51":1}}],["在上面的代码中",{"2":{"51":1,"52":1}}],["在没有依赖注入的情况下",{"2":{"50":1,"51":1}}],["在nunu中",{"2":{"38":1}}],["在项目根目录",{"2":{"32":1}}],["贡献指南",{"0":{"35":1}}],["扩展包",{"0":{"34":1}}],["x26",{"2":{"52":1}}],["x",{"2":{"33":4}}],["xxx",{"2":{"33":4}}],["修改为你自己的go服务端口",{"2":{"33":1}}],["open",{"2":{"51":1,"52":1}}],["officialaccount",{"2":{"53":2}}],["off",{"2":{"33":2}}],["on",{"2":{"33":1}}],["orderrepository",{"2":{"53":2}}],["or",{"2":{"2":5}}],["3306",{"2":{"51":1,"52":1}}],["3",{"2":{"33":1}}],["2",{"2":{"33":1}}],["key",{"2":{"33":1}}],["k8s集群部署",{"0":{"23":1}}],["fileservice",{"2":{"53":2}}],["filerepository",{"2":{"53":3}}],["func",{"2":{"51":2,"52":3,"53":3}}],["fullchain",{"2":{"33":1}}],["for",{"2":{"33":3}}],["forwarded",{"2":{"33":3}}],["fork",{"2":{"32":1}}],["404",{"2":{"33":2}}],["443",{"2":{"33":1}}],["替换为你的真实部署路径",{"2":{"33":1}}],["填写你的域名",{"2":{"33":1}}],["yml配置",{"0":{"46":1}}],["yml",{"2":{"32":1}}],["yml等",{"2":{"1":1}}],["err",{"2":{"53":6}}],["error",{"2":{"33":1,"38":2,"53":1}}],["eecdh+3des",{"2":{"33":1}}],["eecdh+aes256",{"2":{"33":1}}],["eecdh+aes128",{"2":{"33":1}}],["eecdh+chacha20",{"2":{"33":2}}],["exec",{"2":{"32":1}}],["env",{"2":{"16":2}}],["entity",{"2":{"2":1}}],["if",{"2":{"53":2}}],["import",{"2":{"51":1,"52":1}}],["ip",{"2":{"33":1}}],["i",{"2":{"32":1}}],["init",{"2":{"51":1}}],["interface",{"2":{"38":1}}],["internal",{"0":{"2":1},"2":{"1":2,"2":5}}],["instances",{"2":{"32":1}}],["install成功",{"2":{"16":1}}],["install",{"2":{"16":2,"32":1}}],["index",{"2":{"18":1,"33":4}}],["然后直接使用npm安装pm2即可",{"2":{"32":1}}],["所以需要在你的服务器先安装nodejs",{"2":{"32":1}}],["由于pm2依赖于nodejs",{"2":{"32":1}}],["查看进程日志以及资源占用情况等信息",{"2":{"32":1}}],["还可以可以监控进程状态",{"2":{"32":1}}],["是一个进程管理器",{"2":{"32":1}}],["是什么",{"0":{"19":1},"1":{"20":1,"21":1}}],["非容器部署",{"0":{"31":1},"1":{"32":1,"33":1}}],["跨域",{"0":{"29":1}}],["签名验证",{"0":{"28":1}}],["限流器",{"0":{"26":1}}],["保证原生组件的性能与稳定性",{"2":{"21":1}}],["而是通过wire自动生成的",{"2":{"53":1}}],["而是通过构造函数",{"2":{"52":1}}],["而是简洁直观的导入第三方包",{"2":{"21":1}}],["而是在编译期通过静态代码生成的方式达成这个目的",{"2":{"21":1}}],["轻度的组件封装",{"2":{"21":1}}],["无损的依赖注入",{"2":{"21":1}}],["以其轻量级和高性能著称",{"2":{"21":1}}],["又称为golang",{"2":{"21":1}}],["高性能gin",{"2":{"21":1}}],["高级模板",{"2":{"17":1}}],["性能",{"0":{"21":1}}],["确保您的应用程序按预期工作",{"2":{"20":1}}],["帮助您快速入门",{"2":{"20":1}}],["文档完善和测试完备",{"2":{"20":1}}],["模块化和可扩展",{"2":{"20":1}}],["超低学习成本和定制",{"2":{"20":1}}],["旨在golang项目开发时提供出色的开发体验",{"2":{"20":1}}],["跳到快速开始",{"2":{"19":1}}],["只是想尝试一下",{"2":{"19":1}}],["可维护性",{"2":{"52":1}}],["可维护性差",{"2":{"51":1}}],["可以管理后端服务进程",{"2":{"32":1}}],["可以把",{"2":{"16":1}}],["可靠的应用程序",{"2":{"19":1}}],["它使用了依赖注入来管理各个组件之间的依赖关系",{"2":{"53":1}}],["它需要一个数据库连接",{"2":{"51":1}}],["它还包括一套测试套件",{"2":{"20":1}}],["它提供了全面的文档和示例",{"2":{"20":1}}],["它们的组合可以帮助你快速构建一个高效",{"2":{"19":1}}],["它是由golang生态中各种非常流行的库整合而成的",{"2":{"19":1}}],["它的名字来自于英雄联盟中的游戏角色",{"2":{"19":1}}],["该项目也是站在巨人的肩膀上",{"2":{"19":1}}],["和数据库连接之间的关系解耦",{"2":{"52":1}}],["和stop",{"2":{"38":1}}],["和努努一样",{"2":{"19":1}}],["和部署",{"2":{"5":1}}],["一个函数可能会依赖于某个全局变量的值",{"2":{"51":1}}],["一个骑在雪怪肩膀上的小男孩",{"2":{"19":1}}],["一些通用的辅助函数",{"2":{"4":1}}],["80",{"2":{"33":1}}],["8000",{"2":{"18":1,"33":1}}],["8080即可看到欢迎页面",{"2":{"18":1}}],["10m",{"2":{"33":2}}],["1",{"2":{"18":1,"32":1,"33":2}}],["127",{"2":{"18":1,"33":1}}],["0",{"2":{"18":2,"33":2}}],["随后打开浏览器访问http",{"2":{"18":1}}],["我们需要做的仅仅是需要声明我们的依赖关系",{"2":{"53":1}}],["我们通过将",{"2":{"52":1}}],["我们可能会这样实现",{"2":{"51":1}}],["我们只需要将migrate作为server即可",{"2":{"42":1}}],["我们只需要将cron作为server即可",{"2":{"40":1,"41":1}}],["我们只需要将engine作为server即可",{"2":{"39":1}}],["我们使用了全局变量",{"2":{"51":1}}],["我们使用migrate作为migration框架",{"2":{"42":1}}],["我们使用cron作为job框架",{"2":{"41":1}}],["我们使用cron作为task框架",{"2":{"40":1}}],["我们使用gin作为http框架",{"2":{"39":1}}],["我们将http",{"2":{"38":1}}],["我们进入项目执行nunu",{"2":{"18":1}}],["我们推荐新手优先选择使用advanced",{"2":{"17":1}}],["建议",{"2":{"17":1}}],["适合开发者快速学习了解nunu的架构思想",{"2":{"17":1}}],["适合非常熟悉nunu项目的开发者使用",{"2":{"17":1}}],["json",{"2":{"32":3}}],["jwtjwt",{"2":{"53":2}}],["jwt",{"2":{"17":1,"53":1}}],["job服务",{"2":{"41":1}}],["job等服务都抽象为server",{"2":{"38":1}}],["job",{"0":{"41":1},"2":{"3":1,"53":5}}],["基础模板",{"2":{"17":1}}],["推荐",{"2":{"17":1}}],["推荐新用户选择advanced",{"2":{"17":1}}],["你也可以使用国内加速仓库",{"2":{"17":1}}],["你可以自由添加扩展更多的pkg",{"2":{"4":1}}],["国内加速源",{"2":{"17":1}}],["国内用户可以使用goproxy加速go",{"2":{"16":1}}],["此命令将创建一个名为",{"2":{"17":1}}],["目录配置到环境变量中即可",{"2":{"16":1}}],["目录结构",{"0":{"1":1}}],["却提示找不到nunu命令",{"2":{"16":1}}],["$proxy",{"2":{"33":1}}],["$remote",{"2":{"33":2}}],["$server",{"2":{"33":1}}],["$host",{"2":{"33":1}}],["$",{"2":{"16":2}}],["listen",{"2":{"33":1}}],["location",{"2":{"33":1}}],["localhost",{"2":{"18":1,"51":1,"52":1}}],["logger",{"2":{"53":7}}],["log",{"2":{"4":1,"53":1}}],["logic",{"2":{"2":1}}],["layout",{"2":{"17":8}}],["latest",{"2":{"16":1}}],["build",{"2":{"53":2}}],["buffering",{"2":{"33":1}}],["bin",{"2":{"32":1}}],["basic",{"2":{"17":3}}],["bashnunu",{"2":{"17":1}}],["bashgo",{"2":{"16":1}}],["blob",{"2":{"3":1}}],["您可以通过使用第三方库或编写自己的模块轻松添加新功能和功能",{"2":{"20":1}}],["您可以通过以下命令安装",{"2":{"16":1}}],["您可以轻松定制应用程序以满足特定需求",{"2":{"20":1}}],["您可以使用以下命令创建一个新的",{"2":{"17":1}}],["您可以很容易的进行",{"2":{"5":1}}],["安装pm2",{"2":{"32":1}}],["安装",{"0":{"16":1}}],["容器运行",{"0":{"15":1}}],["镜像构建",{"0":{"14":1}}],["uploadhandler",{"2":{"53":2}}],["upgrade",{"2":{"11":1}}],["userhandler",{"2":{"53":2}}],["userservice",{"2":{"53":4}}],["userrepository",{"2":{"53":4}}],["user",{"2":{"51":1,"52":1}}],["uuid",{"2":{"4":1}}],["版本升级",{"0":{"11":1}}],["authhandler",{"2":{"53":2}}],["add",{"2":{"33":1}}],["addr",{"2":{"33":2}}],["advanced",{"2":{"17":3}}],["args",{"2":{"32":1}}],["app",{"2":{"53":6}}],["appapp",{"2":{"53":1}}],["apps",{"2":{"32":1}}],["api文档地址",{"2":{"18":1}}],["api",{"2":{"1":1,"32":1}}],["all",{"2":{"10":1}}],["编译wire",{"0":{"10":1}}],["创建服务实例",{"2":{"52":1}}],["创建pm2配置文件pm2",{"2":{"32":1}}],["创建好项目之后",{"2":{"18":1}}],["创建新项目",{"0":{"17":1}}],["创建handler",{"0":{"9":1}}],["创建组件",{"0":{"8":1},"1":{"9":1}}],["创建项目",{"0":{"6":1}}],["port",{"2":{"33":1}}],["password",{"2":{"51":1,"52":1}}],["pass",{"2":{"33":1}}],["page",{"2":{"33":1}}],["prefer",{"2":{"33":1}}],["privkey",{"2":{"33":1}}],["prompthandler",{"2":{"53":2}}],["promptservice",{"2":{"53":2}}],["promptrepository",{"2":{"53":3}}],["proxy",{"2":{"33":7}}],["protocols",{"2":{"33":1}}],["prod",{"2":{"32":1}}],["projectname",{"2":{"6":1,"17":4}}],["pem",{"2":{"33":2}}],["php",{"2":{"33":2}}],["pm2",{"0":{"32":1},"2":{"32":4}}],["pm2+nginx",{"0":{"31":1},"1":{"32":1,"33":1}}],["pkg",{"2":{"1":2,"4":4}}],["nil",{"2":{"53":6}}],["nginxserver",{"2":{"33":1}}],["nginx配置",{"0":{"33":1}}],["npm",{"2":{"32":1}}],["name",{"2":{"8":1,"9":1,"32":1,"33":1}}],["newtask",{"2":{"53":1}}],["newtranslatehandler",{"2":{"53":1}}],["newtranslateservice",{"2":{"53":1}}],["newapp",{"2":{"53":3}}],["newauthhandler",{"2":{"53":1}}],["newjob",{"2":{"53":2}}],["newjwt",{"2":{"53":2}}],["newhttpserver",{"2":{"53":2}}],["newhandler",{"2":{"53":2}}],["neworderrepository",{"2":{"53":1}}],["newprompthandler",{"2":{"53":1}}],["newpromptservice",{"2":{"53":1}}],["newpromptrepository",{"2":{"53":1}}],["newuploadhandler",{"2":{"53":1}}],["newuserhandler",{"2":{"53":2}}],["newuserservice",{"2":{"53":2}}],["newuserrepository",{"2":{"53":2}}],["newfileservice",{"2":{"53":1}}],["newfilerepository",{"2":{"53":1}}],["newcaptchaservice",{"2":{"53":1}}],["newcaptcharepository",{"2":{"53":1}}],["newcategoryhandler",{"2":{"53":2}}],["newcategoryservice",{"2":{"53":1}}],["newcategoryrepository",{"2":{"53":1}}],["newcosrepository",{"2":{"53":1}}],["newcosclient",{"2":{"53":1}}],["newwire",{"2":{"53":1}}],["newwallethandler",{"2":{"53":1}}],["newwalletservice",{"2":{"53":1}}],["newwalletrepository",{"2":{"53":1}}],["newwechathandler",{"2":{"53":1}}],["newwechatservice",{"2":{"53":1}}],["newwechatrepository",{"2":{"53":1}}],["newwechatpay",{"2":{"53":2}}],["newwechatofficial",{"2":{"53":2}}],["newrepository",{"2":{"53":2}}],["newredis",{"2":{"53":2}}],["newdb",{"2":{"53":2}}],["newset",{"2":{"53":4}}],["newservice",{"2":{"52":3,"53":2}}],["newsid",{"2":{"53":2}}],["new默认拉取github源",{"2":{"17":1}}],["new",{"2":{"6":1,"17":3}}],["nunu没有过度的封装一些常用组件",{"2":{"21":1}}],["nunu文档完善",{"2":{"20":1}}],["nunu旨在具有模块化和可扩展性",{"2":{"20":1}}],["nunu封装了gopher最熟悉的一些流行库",{"2":{"20":1}}],["nunu是一个基于golang的应用脚手架",{"2":{"19":1}}],["nunu内置了两种类型的layout",{"2":{"17":1}}],["nunu",{"0":{"19":1},"1":{"20":1,"21":1},"2":{"5":2,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"16":3,"17":7,"18":1,"20":1,"32":1}}],["nunu命令行工具",{"0":{"5":1},"1":{"6":1,"7":1,"8":1,"9":1,"10":1,"11":1}}],["nunu采用了经典的分层架构",{"2":{"0":1}}],["nunu架构详解",{"0":{"0":1},"1":{"1":1,"2":1,"3":1,"4":1}}],["测试完备",{"2":{"20":1}}],["测试",{"2":{"5":1}}],["测试代码",{"2":{"1":1}}],["开发体验",{"0":{"20":1}}],["开发",{"2":{"5":1}}],["热编译",{"2":{"5":1}}],["项目结构",{"2":{"17":1}}],["项目",{"2":{"17":1}}],["项目的创建",{"2":{"5":1}}],["项目而创建的项目",{"2":{"5":1}}],["命令行工具",{"2":{"5":1}}],["命令行工具是一个为了协助快速开发",{"2":{"5":1}}],["客户端",{"2":{"4":1}}],["生成等",{"2":{"4":1}}],["加密",{"2":{"4":1}}],["将一些通用的代码放在了pkg目录下",{"2":{"4":1}}],["本项目采用了公共代码的方式",{"2":{"4":1}}],["本项目采用了依赖注入框架wire",{"2":{"3":1}}],["公共代码",{"0":{"4":1}}],["公共的代码",{"2":{"1":1}}],["禁止手动修改",{"2":{"3":1}}],["注意",{"2":{"3":1}}],["定义了server子命令需要的依赖关系",{"2":{"3":1}}],["定义了migration子命令需要的依赖关系",{"2":{"3":1}}],["定义了job子命令需要的依赖关系",{"2":{"3":1}}],["定义了业务逻辑层需要的数据结构",{"2":{"2":1}}],["简化了依赖注入的过程",{"2":{"3":1}}],["实现了依赖注入",{"2":{"52":1}}],["实现了模块化和解耦",{"2":{"3":1}}],["实现具体的业务逻辑",{"2":{"2":1}}],["提供了对数据的增删改查",{"2":{"2":1}}],["封装了数据库操作",{"2":{"2":1}}],["数据库",{"0":{"12":1}}],["数据访问对象",{"2":{"2":1}}],["数据模型",{"2":{"2":1}}],["调用数据访问层repository",{"2":{"2":1}}],["调用业务逻辑层的服务",{"2":{"2":1}}],["监听端口",{"2":{"2":1}}],["服务",{"2":{"2":2}}],["服务器等",{"2":{"4":1}}],["服务器",{"2":{"2":1}}],["启动服务",{"0":{"18":1},"2":{"32":1}}],["启动项目",{"0":{"7":1}}],["启动",{"2":{"2":1}}],["rsa+3des",{"2":{"33":1}}],["rsa+aes256",{"2":{"33":1}}],["rsa+aes128",{"2":{"33":1}}],["root",{"2":{"33":1}}],["router",{"2":{"2":1}}],["return",{"2":{"52":1,"53":2}}],["redirect",{"2":{"33":1}}],["redis",{"0":{"36":1},"2":{"17":1}}],["real",{"2":{"33":1}}],["repositoryset",{"2":{"53":1}}],["repositoryrepository",{"2":{"53":11}}],["repository",{"0":{"37":1},"2":{"1":1,"2":1,"53":15}}],["r",{"2":{"17":2}}],["run命令即可启动服务",{"2":{"18":1}}],["run",{"2":{"7":1,"18":1}}],["响应",{"2":{"2":1}}],["返回",{"2":{"2":1}}],["请求",{"2":{"2":2}}],["处理",{"2":{"2":2}}],["存储文件",{"2":{"1":1}}],["脚本文件",{"2":{"1":1}}],["等",{"2":{"1":1}}],["host",{"2":{"33":1}}],["header",{"2":{"33":4}}],["helper",{"2":{"4":1}}],["htm",{"2":{"33":2}}],["html",{"2":{"18":1,"33":3}}],["http服务",{"2":{"39":1}}],["http2",{"2":{"33":1}}],["http中间件",{"0":{"25":1},"1":{"26":1,"27":1,"28":1,"29":1}}],["httpserver",{"2":{"53":4}}],["https",{"2":{"3":1,"17":2}}],["http",{"0":{"39":1},"2":{"1":1,"2":5,"4":4,"18":1,"33":2,"53":1}}],["handlerset",{"2":{"53":1}}],["handlerhandler",{"2":{"53":9}}],["handler",{"0":{"22":1},"2":{"1":1,"2":1,"8":1,"9":2,"53":9}}],["日志trace",{"0":{"27":1}}],["日志功能",{"0":{"24":1}}],["日志的写入等",{"2":{"4":1}}],["日志相关的代码",{"2":{"4":1}}],["日志",{"2":{"1":1}}],["包含了很多nunu的用法示例",{"2":{"17":1}}],["包含了不同的子命令",{"2":{"1":1}}],["包含一个非常精简的架构目录结构",{"2":{"17":1}}],["包括配置",{"2":{"1":1}}],["按照分层架构进行组织",{"2":{"1":1}}],["应用程序的主要代码",{"2":{"1":1}}],["应用程序的入口",{"2":{"1":1}}],["如下是一个真实项目的部分代码",{"2":{"53":1}}],["如果go",{"2":{"16":1}}],["如日志的初始化",{"2":{"4":1}}],["如日志文件",{"2":{"1":1}}],["如",{"2":{"1":1,"4":2}}],["部署相关的文件",{"2":{"1":1}}],["配置文件的读取和解析",{"2":{"4":1}}],["配置文件",{"2":{"1":1}}],["withname",{"2":{"53":1}}],["withserver",{"2":{"53":1}}],["wire不是在运行时通过反射动态地进行依赖注入",{"2":{"21":1}}],["wire官方文档",{"2":{"3":1}}],["wire配置文件",{"2":{"3":3}}],["wire通过预编译wire",{"2":{"3":1}}],["wire",{"2":{"1":3,"3":5,"10":1,"53":5}}],["wallethandler",{"2":{"53":2}}],["walletservice",{"2":{"53":2}}],["walletrepository",{"2":{"53":5}}],["wechathandler",{"2":{"53":2}}],["wechatservice",{"2":{"53":2}}],["wechatrepository",{"2":{"53":3}}],["websocket",{"2":{"38":1}}],["web",{"2":{"1":2}}],["wwwroot",{"2":{"33":1}}],["www",{"2":{"33":1}}],["w",{"2":{"16":2}}],["translatehandler",{"2":{"53":2}}],["translateservice",{"2":{"53":2}}],["tcp",{"2":{"51":1,"52":1}}],["timeout",{"2":{"33":1}}],["tips",{"2":{"16":1}}],["tlsv1",{"2":{"33":3}}],["type",{"2":{"8":1,"52":1}}],["test",{"2":{"1":2}}],["task服务",{"2":{"40":1}}],["task",{"0":{"40":1},"2":{"1":1,"38":1}}],["sid",{"2":{"53":1}}],["sidsid",{"2":{"53":3}}],["s",{"2":{"52":2}}],["sql",{"2":{"51":4,"52":5}}],["swarm",{"0":{"46":1}}],["swarm集群部署",{"0":{"45":1},"1":{"46":1,"47":1}}],["swagger",{"2":{"18":1}}],["shared",{"2":{"33":1}}],["set",{"2":{"33":4}}],["session",{"2":{"33":2}}],["serviceset",{"2":{"53":1}}],["serviceservice",{"2":{"53":9}}],["service",{"0":{"43":1},"2":{"1":1,"2":1,"52":9,"53":9}}],["serverset",{"2":{"53":1}}],["server基础概念",{"0":{"38":1},"1":{"39":1,"40":1,"41":1,"42":1}}],["server",{"2":{"1":3,"2":1,"3":1,"18":1,"32":1,"33":2,"38":1,"53":5}}],["ssl证书路径",{"2":{"33":2}}],["ssl",{"2":{"33":9}}],["struct",{"2":{"52":1}}],["start",{"2":{"32":1}}],["storage",{"2":{"1":1}}],["script",{"2":{"1":1,"32":1}}],["scripts",{"2":{"1":1}}],["sum",{"2":{"1":1}}],["dosomething",{"2":{"52":2}}],["docker",{"0":{"13":1,"45":1},"1":{"14":1,"15":1,"46":1,"47":1},"2":{"1":1}}],["dockerfile",{"2":{"1":1}}],["docs",{"2":{"1":1,"3":1}}],["driver",{"2":{"51":1,"52":1}}],["draft",{"2":{"33":1}}],["database",{"2":{"51":1,"52":1}}],["data",{"2":{"33":1}}],["dao",{"2":{"2":1}}],["demo",{"2":{"53":1}}],["default",{"2":{"33":3}}],["deploy",{"2":{"1":2}}],["dbname",{"2":{"51":1,"52":1}}],["db",{"2":{"17":1,"51":4,"52":9,"53":2}}],["direct",{"2":{"16":1}}],["captchaservice",{"2":{"53":2}}],["captcharepository",{"2":{"53":3}}],["categoryhandler",{"2":{"53":2}}],["categoryservice",{"2":{"53":2}}],["categoryrepository",{"2":{"53":3}}],["cache",{"2":{"33":1}}],["clientv3",{"2":{"53":3}}],["client",{"2":{"53":2}}],["ctx",{"2":{"38":2}}],["ciphers",{"2":{"33":2}}],["certificate",{"2":{"33":2}}],["cron的cron实现了server接口",{"2":{"40":1,"41":1}}],["cron",{"2":{"17":1}}],["create",{"2":{"8":1,"9":1}}],["cn",{"2":{"16":1}}],["cosrepository",{"2":{"53":4}}],["cosclient",{"2":{"53":2}}],["com",{"2":{"3":1,"16":1,"17":2,"33":2,"51":1,"52":1}}],["compose",{"2":{"1":1}}],["context",{"2":{"38":4}}],["controller",{"2":{"2":1}}],["conf=config",{"2":{"32":1}}],["config",{"2":{"1":2,"4":1}}],["cmd",{"2":{"1":2,"3":3,"18":1}}],["mysql",{"2":{"51":2,"52":2}}],["md5",{"2":{"4":1,"33":1}}],["md",{"2":{"3":1}}],["makefile",{"2":{"1":1}}],["main",{"2":{"1":1,"3":1,"18":1,"51":2,"52":2}}],["more",{"2":{"4":1}}],["mode",{"2":{"32":1}}],["model",{"0":{"30":1},"2":{"1":1,"2":1}}],["mod",{"2":{"1":1}}],["mocks",{"2":{"1":1}}],["migrate的migrate实现了server接口",{"2":{"42":1}}],["migration服务",{"2":{"42":1}}],["migration等",{"2":{"17":1}}],["migration",{"0":{"42":1},"2":{"1":1,"3":1}}],["middleware",{"2":{"1":1}}],["grpc",{"2":{"38":1}}],["g",{"2":{"32":1}}],["gin的engine实现了server接口",{"2":{"39":1}}],["gin是一个go",{"2":{"21":1}}],["git",{"2":{"17":2}}],["gitee",{"2":{"17":2}}],["github",{"2":{"3":1,"16":1,"51":1,"52":1}}],["guide",{"2":{"3":1}}],["gen",{"2":{"1":1,"3":2}}],["gojwtjwt",{"2":{"53":1}}],["gopackage",{"2":{"51":1,"52":1}}],["goproxy",{"2":{"16":1}}],["goproxy=https",{"2":{"16":1}}],["gotype",{"2":{"38":1}}],["gobin",{"2":{"16":1}}],["go111module=on",{"2":{"16":1}}],["golang",{"2":{"5":2,"17":2}}],["go文件为自动编译生成",{"2":{"3":1}}],["google",{"2":{"3":1}}],["go",{"2":{"1":5,"3":5,"16":3,"17":2,"18":1,"51":2,"52":1}}],["└──",{"2":{"1":7}}],["│",{"2":{"1":22}}],["├──",{"2":{"1":22}}],["采用了依赖注入框架wire",{"2":{"0":1}}],["同时",{"2":{"0":1}}]],"serializationVersion":2}';export{e as default}; +const e='{"documentCount":54,"nextId":54,"documentIds":{"0":"/nunu/en/architecture#nunu架构详解","1":"/nunu/en/architecture#目录结构","2":"/nunu/en/architecture#internal","3":"/nunu/en/architecture#依赖注入","4":"/nunu/en/architecture#公共代码","5":"/nunu/en/cli#info","6":"/nunu/en/cli#new","7":"/nunu/en/cli#run","8":"/nunu/en/cli#create","9":"/nunu/en/cli#创建handler","10":"/nunu/en/cli#waire","11":"/nunu/en/cli#upgrade","12":"/nunu/en/database#数据库","13":"/nunu/en/getting-started#install","14":"/nunu/en/getting-started#创建新项目","15":"/nunu/en/getting-started#启动服务","16":"/nunu/en/docker#docker","17":"/nunu/en/docker#镜像构建","18":"/nunu/en/docker#容器运行","19":"/nunu/en/guide#what-is-nunu","20":"/nunu/en/guide#developer-experience","21":"/nunu/en/guide#performance","22":"/nunu/en/handler#handler","23":"/nunu/en/k8s#k8s集群部署","24":"/nunu/en/logger#日志功能","25":"/nunu/en/middleware#http中间件","26":"/nunu/en/middleware#限流器","27":"/nunu/en/middleware#日志trace","28":"/nunu/en/middleware#签名验证","29":"/nunu/en/middleware#跨域","30":"/nunu/en/model#model","31":"/nunu/en/nginx#非容器部署-pm2-nginx","32":"/nunu/en/nginx#pm2","33":"/nunu/en/nginx#nginx配置","34":"/nunu/en/pr#贡献指南","35":"/nunu/en/redis#redis","36":"/nunu/en/repository#repository","37":"/nunu/en/pkg#扩展包","38":"/nunu/en/server#server基础概念","39":"/nunu/en/server#http","40":"/nunu/en/server#task","41":"/nunu/en/server#job","42":"/nunu/en/server#migration","43":"/nunu/en/service#service","44":"/nunu/en/swagger#自动化文档","45":"/nunu/en/swarm#docker-swarm集群部署","46":"/nunu/en/swarm#swarm-yml配置","47":"/nunu/en/swarm#滚动更新","48":"/nunu/en/unit-test#单元测试","49":"/nunu/en/wire#依赖注入","50":"/nunu/en/wire#why-do-we-need-dependency-injection","51":"/nunu/en/wire#global-variable-issues","52":"/nunu/en/wire#manual-dependency-injection","53":"/nunu/en/wire#automatic-dependency-injection"},"fieldIds":{"title":0,"titles":1,"text":2},"fieldLength":{"0":[1,1,5],"1":[1,1,55],"2":[1,1,30],"3":[1,1,30],"4":[1,1,26],"5":[1,1,13],"6":[1,1,4],"7":[1,1,3],"8":[1,1,6],"9":[1,2,5],"10":[1,1,4],"11":[1,1,3],"12":[1,1,1],"13":[1,1,27],"14":[1,1,45],"15":[1,1,22],"16":[1,1,1],"17":[1,1,1],"18":[1,1,1],"19":[3,1,11],"20":[1,3,16],"21":[1,3,13],"22":[1,1,1],"23":[1,1,1],"24":[1,1,1],"25":[1,1,1],"26":[1,1,1],"27":[1,1,1],"28":[1,1,1],"29":[1,1,1],"30":[1,1,1],"31":[3,1,1],"32":[1,3,35],"33":[1,3,87],"34":[1,1,1],"35":[1,1,1],"36":[1,1,1],"37":[1,1,1],"38":[1,1,19],"39":[1,1,6],"40":[1,1,6],"41":[1,1,6],"42":[1,1,6],"43":[1,1,1],"44":[1,1,1],"45":[2,1,1],"46":[2,2,1],"47":[1,2,1],"48":[1,1,1],"49":[1,1,1],"50":[2,1,6],"51":[1,1,65],"52":[1,1,59],"53":[1,1,147]},"averageFieldLength":[1.1296296296296298,1.2037037037037037,14.53703703703704],"storedFields":{"0":{"title":"Nunu架构详解","titles":[]},"1":{"title":"目录结构","titles":["Nunu架构详解"]},"2":{"title":"internal","titles":["Nunu架构详解"]},"3":{"title":"依赖注入","titles":["Nunu架构详解"]},"4":{"title":"公共代码","titles":["Nunu架构详解"]},"5":{"title":"nunu命令行工具","titles":[]},"6":{"title":"创建项目","titles":["nunu命令行工具"]},"7":{"title":"启动项目","titles":["nunu命令行工具"]},"8":{"title":"创建组件","titles":["nunu命令行工具"]},"9":{"title":"创建handler","titles":["nunu命令行工具","创建组件"]},"10":{"title":"编译wire","titles":["nunu命令行工具"]},"11":{"title":"版本升级","titles":["nunu命令行工具"]},"12":{"title":"数据库","titles":[]},"13":{"title":"安装","titles":[]},"14":{"title":"创建新项目","titles":[]},"15":{"title":"启动服务","titles":[]},"16":{"title":"Docker","titles":[]},"17":{"title":"镜像构建","titles":["Docker"]},"18":{"title":"容器运行","titles":["Docker"]},"19":{"title":"Nunu 是什么?","titles":[]},"20":{"title":"开发体验","titles":["Nunu 是什么?"]},"21":{"title":"性能","titles":["Nunu 是什么?"]},"22":{"title":"Handler","titles":[]},"23":{"title":"k8s集群部署","titles":[]},"24":{"title":"日志功能","titles":[]},"25":{"title":"HTTP中间件","titles":[]},"26":{"title":"限流器","titles":["HTTP中间件"]},"27":{"title":"日志Trace","titles":["HTTP中间件"]},"28":{"title":"签名验证","titles":["HTTP中间件"]},"29":{"title":"跨域","titles":["HTTP中间件"]},"30":{"title":"Model","titles":[]},"31":{"title":"非容器部署(PM2+Nginx)","titles":[]},"32":{"title":"PM2","titles":["非容器部署(PM2+Nginx)"]},"33":{"title":"Nginx配置","titles":["非容器部署(PM2+Nginx)"]},"34":{"title":"贡献指南","titles":[]},"35":{"title":"Redis","titles":[]},"36":{"title":"Repository","titles":[]},"37":{"title":"扩展包","titles":[]},"38":{"title":"Server基础概念","titles":[]},"39":{"title":"HTTP","titles":["Server基础概念"]},"40":{"title":"Task","titles":["Server基础概念"]},"41":{"title":"Job","titles":["Server基础概念"]},"42":{"title":"Migration","titles":["Server基础概念"]},"43":{"title":"Service","titles":[]},"44":{"title":"自动化文档","titles":[]},"45":{"title":"Docker Swarm集群部署","titles":[]},"46":{"title":"swarm.yml配置","titles":["Docker Swarm集群部署"]},"47":{"title":"滚动更新","titles":["Docker Swarm集群部署"]},"48":{"title":"单元测试","titles":[]},"49":{"title":"依赖注入","titles":[]},"50":{"title":"为什么需要依赖注入?","titles":["依赖注入"]},"51":{"title":"全局变量","titles":["依赖注入"]},"52":{"title":"手动依赖注入","titles":["依赖注入"]},"53":{"title":"自动依赖注入","titles":["依赖注入"]}},"dirtCount":0,"index":[["前往到wire官方文档",{"2":{"53":1}}],["前端代码",{"2":{"1":1}}],["想学习更多关于wire知识",{"2":{"53":1}}],["代码大概像下面这样",{"2":{"53":1}}],["代码变得更易于理解和维护",{"2":{"52":1}}],["声明依赖关系的代码非常简单",{"2":{"53":1}}],["就会自动帮我们生成代码",{"2":{"53":1}}],["执行wire命令后",{"2":{"53":1}}],["但其实这段代码并不是人工手写的",{"2":{"53":1}}],["但是在调用该函数之前",{"2":{"51":1}}],["相信你一定会感觉依赖注入使我们代码使变得复杂",{"2":{"53":1}}],["相关的代码",{"2":{"4":1}}],["看到这样的代码",{"2":{"53":1}}],["手动进行依赖注入可能会变得繁琐",{"2":{"53":1}}],["手动依赖注入",{"0":{"52":1}}],["的行为",{"2":{"52":1}}],["的目录",{"2":{"14":1}}],["现在我们可以轻松地通过传递模拟的数据库连接来测试",{"2":{"52":1}}],["易于测试",{"2":{"52":1}}],["更易于重用和测试",{"2":{"52":1}}],["解耦",{"2":{"52":1}}],["函数",{"2":{"52":1}}],["作为参数传递给",{"2":{"52":1}}],["来执行数据库操作",{"2":{"52":1}}],["来保存数据库连接",{"2":{"51":1}}],["下面是使用依赖注入改进上面示例的代码",{"2":{"52":1}}],["方法参数或者其他方式传递进来",{"2":{"52":1}}],["依赖关系不再硬编码到组件内部",{"2":{"52":1}}],["依赖注入可以帮助解决这些问题",{"2":{"52":1}}],["依赖注入是一种编程模式",{"2":{"50":1}}],["依赖注入",{"0":{"3":1,"49":1},"1":{"50":1,"51":1,"52":1,"53":1}}],["降低了代码的可维护性",{"2":{"51":1}}],["当项目变得庞大时",{"2":{"53":1}}],["当代码规模增大时",{"2":{"51":1}}],["当然",{"2":{"4":1}}],["使得",{"2":{"52":1}}],["使得代码难以重构和维护",{"2":{"51":1}}],["使用服务进行操作",{"2":{"52":1}}],["使用",{"2":{"52":1}}],["使用全局变量",{"2":{"51":1}}],["使用基础模板",{"2":{"14":1}}],["使用高级模板",{"2":{"14":1}}],["从而改变函数的行为",{"2":{"51":1}}],["从而引发难以调试的错误",{"2":{"51":1}}],["另一个部分的代码可能会修改该全局变量",{"2":{"51":1}}],["例如",{"2":{"51":1}}],["不可控的副作用",{"2":{"51":1}}],["因为在测试过程中很难控制全局变量的状态",{"2":{"51":1}}],["因此",{"2":{"39":1,"40":1,"41":1,"42":1}}],["难以测试",{"2":{"51":1}}],["很容易引发意外的行为",{"2":{"51":1}}],["多个并发执行的程序可能会同时访问和修改全局变量",{"2":{"51":1}}],["并将数据库连接传递进去",{"2":{"52":1}}],["并发安全问题",{"2":{"51":1}}],["并在其中生成一个优雅的",{"2":{"14":1}}],["=",{"2":{"51":1,"52":2,"53":44}}],["初始化数据库连接",{"2":{"51":1,"52":1}}],["viper",{"2":{"53":2}}],["viperviper",{"2":{"53":13}}],["var",{"2":{"51":1,"53":4}}],["v1",{"2":{"1":1}}],["假设我们有一个简单的服务",{"2":{"51":1}}],["语言示例来说明",{"2":{"51":1}}],["语言编写的web框架",{"2":{"21":1}}],["让我们通过一个简单的",{"2":{"51":1}}],["全局变量会导致代码难以理解和修改",{"2":{"51":1}}],["全局变量增加了代码的耦合性",{"2":{"51":1}}],["全局变量的值可以在程序的任何地方被修改",{"2":{"51":1}}],["全局变量的状态不受控制",{"2":{"51":1}}],["全局变量使得单元测试变得困难",{"2":{"51":1}}],["全局变量",{"0":{"51":1}}],["这样做带来了以下好处",{"2":{"52":1}}],["这样做可能会引发以下问题",{"2":{"51":1}}],["这可能导致不可预测的副作用",{"2":{"51":1}}],["这可能导致测试覆盖不全或者需要编写更多的集成测试来覆盖全局变量的不同状态",{"2":{"51":1}}],["这可能导致竞态条件和数据竞争",{"2":{"51":1}}],["这里可能会有很多其他的逻辑",{"2":{"51":1}}],["这种方式会带来一些问题",{"2":{"50":1}}],["这是因为环境变量没有配置",{"2":{"13":1}}],["通常会使用全局变量或硬编码的方式来获取所需的依赖",{"2":{"50":1}}],["通过明确地传递依赖关系",{"2":{"52":1}}],["通过",{"2":{"5":1}}],["用于管理代码中各个组件之间的依赖关系",{"2":{"50":1}}],["用于部署和其他自动化任务",{"2":{"1":1}}],["为什么需要依赖注入",{"0":{"50":1}}],["为了实现代码的复用和统一管理",{"2":{"4":1}}],["为了更好地实现模块化和解耦",{"2":{"0":1}}],["单元测试",{"0":{"48":1}}],["滚动更新",{"0":{"47":1}}],["自动依赖注入",{"0":{"53":1}}],["自动化文档",{"0":{"44":1}}],["自动生成依赖注入的代码wire",{"2":{"3":1}}],["也就是start",{"2":{"38":1}}],["每个server都必须实现server接口中的方法",{"2":{"38":1}}],["\\t\\tnewapp",{"2":{"53":1}}],["\\t\\tjwt",{"2":{"53":1}}],["\\t\\tsid",{"2":{"53":1}}],["\\t\\tserverset",{"2":{"53":1}}],["\\t\\tserviceset",{"2":{"53":1}}],["\\t\\thandlerset",{"2":{"53":1}}],["\\t\\trepositoryset",{"2":{"53":1}}],["\\t\\tapp",{"2":{"53":2}}],["\\tpanic",{"2":{"53":1}}],["\\treturn",{"2":{"53":1}}],["\\trepository",{"2":{"53":6}}],["\\tserver",{"2":{"53":3}}],["\\tservice",{"2":{"53":2}}],["\\tstop",{"2":{"38":1}}],["\\tstart",{"2":{"38":1}}],["\\thandler",{"2":{"53":3}}],["\\tdb",{"2":{"51":1}}],["\\t",{"2":{"51":5,"53":2}}],["\\tlisten",{"2":{"33":1}}],["在依赖注入中",{"2":{"52":1}}],["在并发环境中",{"2":{"51":1}}],["在上面的代码中",{"2":{"51":1,"52":1}}],["在没有依赖注入的情况下",{"2":{"50":1,"51":1}}],["在nunu中",{"2":{"38":1}}],["在项目根目录",{"2":{"32":1}}],["扩展包",{"0":{"37":1}}],["贡献指南",{"0":{"34":1}}],["x26",{"2":{"52":1}}],["x",{"2":{"33":4}}],["xxx",{"2":{"33":4}}],["修改为你自己的go服务端口",{"2":{"33":1}}],["open",{"2":{"51":1,"52":1}}],["officialaccount",{"2":{"53":2}}],["off",{"2":{"33":2}}],["on",{"2":{"33":1}}],["orderrepository",{"2":{"53":2}}],["or",{"2":{"2":5}}],["3306",{"2":{"51":1,"52":1}}],["3",{"2":{"33":1}}],["2",{"2":{"33":1}}],["key",{"2":{"33":1}}],["k8s集群部署",{"0":{"23":1}}],["fileservice",{"2":{"53":2}}],["filerepository",{"2":{"53":3}}],["func",{"2":{"51":2,"52":3,"53":3}}],["fullchain",{"2":{"33":1}}],["for",{"2":{"33":3}}],["forwarded",{"2":{"33":3}}],["fork",{"2":{"32":1}}],["404",{"2":{"33":2}}],["443",{"2":{"33":1}}],["替换为你的真实部署路径",{"2":{"33":1}}],["填写你的域名",{"2":{"33":1}}],["yml配置",{"0":{"46":1}}],["yml",{"2":{"32":1}}],["yml等",{"2":{"1":1}}],["err",{"2":{"53":6}}],["error",{"2":{"33":1,"38":2,"53":1}}],["eecdh+3des",{"2":{"33":1}}],["eecdh+aes256",{"2":{"33":1}}],["eecdh+aes128",{"2":{"33":1}}],["eecdh+chacha20",{"2":{"33":2}}],["exec",{"2":{"32":1}}],["env",{"2":{"13":2}}],["entity",{"2":{"2":1}}],["if",{"2":{"53":2}}],["import",{"2":{"51":1,"52":1}}],["ip",{"2":{"33":1}}],["i",{"2":{"32":1}}],["init",{"2":{"51":1}}],["interface",{"2":{"38":1}}],["internal",{"0":{"2":1},"2":{"1":2,"2":5}}],["instances",{"2":{"32":1}}],["install成功",{"2":{"13":1}}],["install",{"2":{"13":2,"32":1}}],["index",{"2":{"15":1,"33":4}}],["然后直接使用npm安装pm2即可",{"2":{"32":1}}],["所以需要在你的服务器先安装nodejs",{"2":{"32":1}}],["由于pm2依赖于nodejs",{"2":{"32":1}}],["查看进程日志以及资源占用情况等信息",{"2":{"32":1}}],["还可以可以监控进程状态",{"2":{"32":1}}],["是一个进程管理器",{"2":{"32":1}}],["是什么",{"0":{"19":1},"1":{"20":1,"21":1}}],["非容器部署",{"0":{"31":1},"1":{"32":1,"33":1}}],["跨域",{"0":{"29":1}}],["签名验证",{"0":{"28":1}}],["限流器",{"0":{"26":1}}],["保证原生组件的性能与稳定性",{"2":{"21":1}}],["而是通过wire自动生成的",{"2":{"53":1}}],["而是通过构造函数",{"2":{"52":1}}],["而是简洁直观的导入第三方包",{"2":{"21":1}}],["而是在编译期通过静态代码生成的方式达成这个目的",{"2":{"21":1}}],["轻度的组件封装",{"2":{"21":1}}],["无损的依赖注入",{"2":{"21":1}}],["以其轻量级和高性能著称",{"2":{"21":1}}],["又称为golang",{"2":{"21":1}}],["高性能gin",{"2":{"21":1}}],["高级模板",{"2":{"14":1}}],["性能",{"0":{"21":1}}],["确保您的应用程序按预期工作",{"2":{"20":1}}],["帮助您快速入门",{"2":{"20":1}}],["文档完善和测试完备",{"2":{"20":1}}],["模块化和可扩展",{"2":{"20":1}}],["超低学习成本和定制",{"2":{"20":1}}],["旨在golang项目开发时提供出色的开发体验",{"2":{"20":1}}],["跳到快速开始",{"2":{"19":1}}],["只是想尝试一下",{"2":{"19":1}}],["可维护性",{"2":{"52":1}}],["可维护性差",{"2":{"51":1}}],["可以管理后端服务进程",{"2":{"32":1}}],["可以把",{"2":{"13":1}}],["可靠的应用程序",{"2":{"19":1}}],["它使用了依赖注入来管理各个组件之间的依赖关系",{"2":{"53":1}}],["它需要一个数据库连接",{"2":{"51":1}}],["它还包括一套测试套件",{"2":{"20":1}}],["它提供了全面的文档和示例",{"2":{"20":1}}],["它们的组合可以帮助你快速构建一个高效",{"2":{"19":1}}],["它是由golang生态中各种非常流行的库整合而成的",{"2":{"19":1}}],["它的名字来自于英雄联盟中的游戏角色",{"2":{"19":1}}],["该项目也是站在巨人的肩膀上",{"2":{"19":1}}],["和数据库连接之间的关系解耦",{"2":{"52":1}}],["和stop",{"2":{"38":1}}],["和努努一样",{"2":{"19":1}}],["和部署",{"2":{"5":1}}],["一个函数可能会依赖于某个全局变量的值",{"2":{"51":1}}],["一个骑在雪怪肩膀上的小男孩",{"2":{"19":1}}],["一些通用的辅助函数",{"2":{"4":1}}],["容器运行",{"0":{"18":1}}],["镜像构建",{"0":{"17":1}}],["80",{"2":{"33":1}}],["8000",{"2":{"15":1,"33":1}}],["8080即可看到欢迎页面",{"2":{"15":1}}],["10m",{"2":{"33":2}}],["1",{"2":{"15":1,"32":1,"33":2}}],["127",{"2":{"15":1,"33":1}}],["0",{"2":{"15":2,"33":2}}],["随后打开浏览器访问http",{"2":{"15":1}}],["我们需要做的仅仅是需要声明我们的依赖关系",{"2":{"53":1}}],["我们通过将",{"2":{"52":1}}],["我们可能会这样实现",{"2":{"51":1}}],["我们只需要将migrate作为server即可",{"2":{"42":1}}],["我们只需要将cron作为server即可",{"2":{"40":1,"41":1}}],["我们只需要将engine作为server即可",{"2":{"39":1}}],["我们使用了全局变量",{"2":{"51":1}}],["我们使用migrate作为migration框架",{"2":{"42":1}}],["我们使用cron作为job框架",{"2":{"41":1}}],["我们使用cron作为task框架",{"2":{"40":1}}],["我们使用gin作为http框架",{"2":{"39":1}}],["我们将http",{"2":{"38":1}}],["我们进入项目执行nunu",{"2":{"15":1}}],["我们推荐新手优先选择使用advanced",{"2":{"14":1}}],["建议",{"2":{"14":1}}],["适合开发者快速学习了解nunu的架构思想",{"2":{"14":1}}],["适合非常熟悉nunu项目的开发者使用",{"2":{"14":1}}],["json",{"2":{"32":3}}],["jwtjwt",{"2":{"53":2}}],["jwt",{"2":{"14":1,"53":1}}],["job服务",{"2":{"41":1}}],["job等服务都抽象为server",{"2":{"38":1}}],["job",{"0":{"41":1},"2":{"3":1,"53":5}}],["基础模板",{"2":{"14":1}}],["推荐",{"2":{"14":1}}],["推荐新用户选择advanced",{"2":{"14":1}}],["你也可以使用国内加速仓库",{"2":{"14":1}}],["你可以自由添加扩展更多的pkg",{"2":{"4":1}}],["国内加速源",{"2":{"14":1}}],["国内用户可以使用goproxy加速go",{"2":{"13":1}}],["此命令将创建一个名为",{"2":{"14":1}}],["目录配置到环境变量中即可",{"2":{"13":1}}],["目录结构",{"0":{"1":1}}],["却提示找不到nunu命令",{"2":{"13":1}}],["$proxy",{"2":{"33":1}}],["$remote",{"2":{"33":2}}],["$server",{"2":{"33":1}}],["$host",{"2":{"33":1}}],["$",{"2":{"13":2}}],["listen",{"2":{"33":1}}],["location",{"2":{"33":1}}],["localhost",{"2":{"15":1,"51":1,"52":1}}],["logger",{"2":{"53":7}}],["log",{"2":{"4":1,"53":1}}],["logic",{"2":{"2":1}}],["layout",{"2":{"14":8}}],["latest",{"2":{"13":1}}],["build",{"2":{"53":2}}],["buffering",{"2":{"33":1}}],["bin",{"2":{"32":1}}],["basic",{"2":{"14":3}}],["bashnunu",{"2":{"14":1}}],["bashgo",{"2":{"13":1}}],["blob",{"2":{"3":1}}],["您可以通过使用第三方库或编写自己的模块轻松添加新功能和功能",{"2":{"20":1}}],["您可以通过以下命令安装",{"2":{"13":1}}],["您可以轻松定制应用程序以满足特定需求",{"2":{"20":1}}],["您可以使用以下命令创建一个新的",{"2":{"14":1}}],["您可以很容易的进行",{"2":{"5":1}}],["安装pm2",{"2":{"32":1}}],["安装",{"0":{"13":1}}],["uploadhandler",{"2":{"53":2}}],["upgrade",{"2":{"11":1}}],["userhandler",{"2":{"53":2}}],["userservice",{"2":{"53":4}}],["userrepository",{"2":{"53":4}}],["user",{"2":{"51":1,"52":1}}],["uuid",{"2":{"4":1}}],["版本升级",{"0":{"11":1}}],["authhandler",{"2":{"53":2}}],["add",{"2":{"33":1}}],["addr",{"2":{"33":2}}],["advanced",{"2":{"14":3}}],["args",{"2":{"32":1}}],["app",{"2":{"53":6}}],["appapp",{"2":{"53":1}}],["apps",{"2":{"32":1}}],["api文档地址",{"2":{"15":1}}],["api",{"2":{"1":1,"32":1}}],["all",{"2":{"10":1}}],["编译wire",{"0":{"10":1}}],["创建服务实例",{"2":{"52":1}}],["创建pm2配置文件pm2",{"2":{"32":1}}],["创建好项目之后",{"2":{"15":1}}],["创建新项目",{"0":{"14":1}}],["创建handler",{"0":{"9":1}}],["创建组件",{"0":{"8":1},"1":{"9":1}}],["创建项目",{"0":{"6":1}}],["port",{"2":{"33":1}}],["password",{"2":{"51":1,"52":1}}],["pass",{"2":{"33":1}}],["page",{"2":{"33":1}}],["prefer",{"2":{"33":1}}],["privkey",{"2":{"33":1}}],["prompthandler",{"2":{"53":2}}],["promptservice",{"2":{"53":2}}],["promptrepository",{"2":{"53":3}}],["proxy",{"2":{"33":7}}],["protocols",{"2":{"33":1}}],["prod",{"2":{"32":1}}],["projectname",{"2":{"6":1,"14":4}}],["pem",{"2":{"33":2}}],["php",{"2":{"33":2}}],["pm2",{"0":{"32":1},"2":{"32":4}}],["pm2+nginx",{"0":{"31":1},"1":{"32":1,"33":1}}],["pkg",{"2":{"1":2,"4":4}}],["nil",{"2":{"53":6}}],["nginxserver",{"2":{"33":1}}],["nginx配置",{"0":{"33":1}}],["npm",{"2":{"32":1}}],["name",{"2":{"8":1,"9":1,"32":1,"33":1}}],["newtask",{"2":{"53":1}}],["newtranslatehandler",{"2":{"53":1}}],["newtranslateservice",{"2":{"53":1}}],["newapp",{"2":{"53":3}}],["newauthhandler",{"2":{"53":1}}],["newjob",{"2":{"53":2}}],["newjwt",{"2":{"53":2}}],["newhttpserver",{"2":{"53":2}}],["newhandler",{"2":{"53":2}}],["neworderrepository",{"2":{"53":1}}],["newprompthandler",{"2":{"53":1}}],["newpromptservice",{"2":{"53":1}}],["newpromptrepository",{"2":{"53":1}}],["newuploadhandler",{"2":{"53":1}}],["newuserhandler",{"2":{"53":2}}],["newuserservice",{"2":{"53":2}}],["newuserrepository",{"2":{"53":2}}],["newfileservice",{"2":{"53":1}}],["newfilerepository",{"2":{"53":1}}],["newcaptchaservice",{"2":{"53":1}}],["newcaptcharepository",{"2":{"53":1}}],["newcategoryhandler",{"2":{"53":2}}],["newcategoryservice",{"2":{"53":1}}],["newcategoryrepository",{"2":{"53":1}}],["newcosrepository",{"2":{"53":1}}],["newcosclient",{"2":{"53":1}}],["newwire",{"2":{"53":1}}],["newwallethandler",{"2":{"53":1}}],["newwalletservice",{"2":{"53":1}}],["newwalletrepository",{"2":{"53":1}}],["newwechathandler",{"2":{"53":1}}],["newwechatservice",{"2":{"53":1}}],["newwechatrepository",{"2":{"53":1}}],["newwechatpay",{"2":{"53":2}}],["newwechatofficial",{"2":{"53":2}}],["newrepository",{"2":{"53":2}}],["newredis",{"2":{"53":2}}],["newdb",{"2":{"53":2}}],["newset",{"2":{"53":4}}],["newservice",{"2":{"52":3,"53":2}}],["newsid",{"2":{"53":2}}],["new默认拉取github源",{"2":{"14":1}}],["new",{"2":{"6":1,"14":3}}],["nunu没有过度的封装一些常用组件",{"2":{"21":1}}],["nunu文档完善",{"2":{"20":1}}],["nunu旨在具有模块化和可扩展性",{"2":{"20":1}}],["nunu封装了gopher最熟悉的一些流行库",{"2":{"20":1}}],["nunu是一个基于golang的应用脚手架",{"2":{"19":1}}],["nunu内置了两种类型的layout",{"2":{"14":1}}],["nunu",{"0":{"19":1},"1":{"20":1,"21":1},"2":{"5":2,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"13":3,"14":7,"15":1,"20":1,"32":1}}],["nunu命令行工具",{"0":{"5":1},"1":{"6":1,"7":1,"8":1,"9":1,"10":1,"11":1}}],["nunu采用了经典的分层架构",{"2":{"0":1}}],["nunu架构详解",{"0":{"0":1},"1":{"1":1,"2":1,"3":1,"4":1}}],["测试完备",{"2":{"20":1}}],["测试",{"2":{"5":1}}],["测试代码",{"2":{"1":1}}],["开发体验",{"0":{"20":1}}],["开发",{"2":{"5":1}}],["热编译",{"2":{"5":1}}],["项目结构",{"2":{"14":1}}],["项目",{"2":{"14":1}}],["项目的创建",{"2":{"5":1}}],["项目而创建的项目",{"2":{"5":1}}],["命令行工具",{"2":{"5":1}}],["命令行工具是一个为了协助快速开发",{"2":{"5":1}}],["客户端",{"2":{"4":1}}],["生成等",{"2":{"4":1}}],["加密",{"2":{"4":1}}],["将一些通用的代码放在了pkg目录下",{"2":{"4":1}}],["本项目采用了公共代码的方式",{"2":{"4":1}}],["本项目采用了依赖注入框架wire",{"2":{"3":1}}],["公共代码",{"0":{"4":1}}],["公共的代码",{"2":{"1":1}}],["禁止手动修改",{"2":{"3":1}}],["注意",{"2":{"3":1}}],["定义了server子命令需要的依赖关系",{"2":{"3":1}}],["定义了migration子命令需要的依赖关系",{"2":{"3":1}}],["定义了job子命令需要的依赖关系",{"2":{"3":1}}],["定义了业务逻辑层需要的数据结构",{"2":{"2":1}}],["简化了依赖注入的过程",{"2":{"3":1}}],["实现了依赖注入",{"2":{"52":1}}],["实现了模块化和解耦",{"2":{"3":1}}],["实现具体的业务逻辑",{"2":{"2":1}}],["提供了对数据的增删改查",{"2":{"2":1}}],["封装了数据库操作",{"2":{"2":1}}],["数据库",{"0":{"12":1}}],["数据访问对象",{"2":{"2":1}}],["数据模型",{"2":{"2":1}}],["调用数据访问层repository",{"2":{"2":1}}],["调用业务逻辑层的服务",{"2":{"2":1}}],["监听端口",{"2":{"2":1}}],["服务",{"2":{"2":2}}],["服务器等",{"2":{"4":1}}],["服务器",{"2":{"2":1}}],["启动服务",{"0":{"15":1},"2":{"32":1}}],["启动项目",{"0":{"7":1}}],["启动",{"2":{"2":1}}],["rsa+3des",{"2":{"33":1}}],["rsa+aes256",{"2":{"33":1}}],["rsa+aes128",{"2":{"33":1}}],["root",{"2":{"33":1}}],["router",{"2":{"2":1}}],["return",{"2":{"52":1,"53":2}}],["redirect",{"2":{"33":1}}],["redis",{"0":{"35":1},"2":{"14":1}}],["real",{"2":{"33":1}}],["repositoryset",{"2":{"53":1}}],["repositoryrepository",{"2":{"53":11}}],["repository",{"0":{"36":1},"2":{"1":1,"2":1,"53":15}}],["r",{"2":{"14":2}}],["run命令即可启动服务",{"2":{"15":1}}],["run",{"2":{"7":1,"15":1}}],["响应",{"2":{"2":1}}],["返回",{"2":{"2":1}}],["请求",{"2":{"2":2}}],["处理",{"2":{"2":2}}],["存储文件",{"2":{"1":1}}],["脚本文件",{"2":{"1":1}}],["等",{"2":{"1":1}}],["host",{"2":{"33":1}}],["header",{"2":{"33":4}}],["helper",{"2":{"4":1}}],["htm",{"2":{"33":2}}],["html",{"2":{"15":1,"33":3}}],["http服务",{"2":{"39":1}}],["http2",{"2":{"33":1}}],["http中间件",{"0":{"25":1},"1":{"26":1,"27":1,"28":1,"29":1}}],["httpserver",{"2":{"53":4}}],["https",{"2":{"3":1,"14":2}}],["http",{"0":{"39":1},"2":{"1":1,"2":5,"4":4,"15":1,"33":2,"53":1}}],["handlerset",{"2":{"53":1}}],["handlerhandler",{"2":{"53":9}}],["handler",{"0":{"22":1},"2":{"1":1,"2":1,"8":1,"9":2,"53":9}}],["日志trace",{"0":{"27":1}}],["日志功能",{"0":{"24":1}}],["日志的写入等",{"2":{"4":1}}],["日志相关的代码",{"2":{"4":1}}],["日志",{"2":{"1":1}}],["包含了很多nunu的用法示例",{"2":{"14":1}}],["包含了不同的子命令",{"2":{"1":1}}],["包含一个非常精简的架构目录结构",{"2":{"14":1}}],["包括配置",{"2":{"1":1}}],["按照分层架构进行组织",{"2":{"1":1}}],["应用程序的主要代码",{"2":{"1":1}}],["应用程序的入口",{"2":{"1":1}}],["如下是一个真实项目的部分代码",{"2":{"53":1}}],["如果go",{"2":{"13":1}}],["如日志的初始化",{"2":{"4":1}}],["如日志文件",{"2":{"1":1}}],["如",{"2":{"1":1,"4":2}}],["部署相关的文件",{"2":{"1":1}}],["配置文件的读取和解析",{"2":{"4":1}}],["配置文件",{"2":{"1":1}}],["withname",{"2":{"53":1}}],["withserver",{"2":{"53":1}}],["wire不是在运行时通过反射动态地进行依赖注入",{"2":{"21":1}}],["wire官方文档",{"2":{"3":1}}],["wire配置文件",{"2":{"3":3}}],["wire通过预编译wire",{"2":{"3":1}}],["wire",{"2":{"1":3,"3":5,"10":1,"53":5}}],["wallethandler",{"2":{"53":2}}],["walletservice",{"2":{"53":2}}],["walletrepository",{"2":{"53":5}}],["wechathandler",{"2":{"53":2}}],["wechatservice",{"2":{"53":2}}],["wechatrepository",{"2":{"53":3}}],["websocket",{"2":{"38":1}}],["web",{"2":{"1":2}}],["wwwroot",{"2":{"33":1}}],["www",{"2":{"33":1}}],["w",{"2":{"13":2}}],["translatehandler",{"2":{"53":2}}],["translateservice",{"2":{"53":2}}],["tcp",{"2":{"51":1,"52":1}}],["timeout",{"2":{"33":1}}],["tips",{"2":{"13":1}}],["tlsv1",{"2":{"33":3}}],["type",{"2":{"8":1,"52":1}}],["test",{"2":{"1":2}}],["task服务",{"2":{"40":1}}],["task",{"0":{"40":1},"2":{"1":1,"38":1}}],["sid",{"2":{"53":1}}],["sidsid",{"2":{"53":3}}],["s",{"2":{"52":2}}],["sql",{"2":{"51":4,"52":5}}],["swarm",{"0":{"46":1}}],["swarm集群部署",{"0":{"45":1},"1":{"46":1,"47":1}}],["swagger",{"2":{"15":1}}],["shared",{"2":{"33":1}}],["set",{"2":{"33":4}}],["session",{"2":{"33":2}}],["serviceset",{"2":{"53":1}}],["serviceservice",{"2":{"53":9}}],["service",{"0":{"43":1},"2":{"1":1,"2":1,"52":9,"53":9}}],["serverset",{"2":{"53":1}}],["server基础概念",{"0":{"38":1},"1":{"39":1,"40":1,"41":1,"42":1}}],["server",{"2":{"1":3,"2":1,"3":1,"15":1,"32":1,"33":2,"38":1,"53":5}}],["ssl证书路径",{"2":{"33":2}}],["ssl",{"2":{"33":9}}],["struct",{"2":{"52":1}}],["start",{"2":{"32":1}}],["storage",{"2":{"1":1}}],["script",{"2":{"1":1,"32":1}}],["scripts",{"2":{"1":1}}],["sum",{"2":{"1":1}}],["dosomething",{"2":{"52":2}}],["docker",{"0":{"16":1,"45":1},"1":{"17":1,"18":1,"46":1,"47":1},"2":{"1":1}}],["dockerfile",{"2":{"1":1}}],["docs",{"2":{"1":1,"3":1}}],["driver",{"2":{"51":1,"52":1}}],["draft",{"2":{"33":1}}],["database",{"2":{"51":1,"52":1}}],["data",{"2":{"33":1}}],["dao",{"2":{"2":1}}],["demo",{"2":{"53":1}}],["default",{"2":{"33":3}}],["deploy",{"2":{"1":2}}],["dbname",{"2":{"51":1,"52":1}}],["db",{"2":{"14":1,"51":4,"52":9,"53":2}}],["direct",{"2":{"13":1}}],["captchaservice",{"2":{"53":2}}],["captcharepository",{"2":{"53":3}}],["categoryhandler",{"2":{"53":2}}],["categoryservice",{"2":{"53":2}}],["categoryrepository",{"2":{"53":3}}],["cache",{"2":{"33":1}}],["clientv3",{"2":{"53":3}}],["client",{"2":{"53":2}}],["ctx",{"2":{"38":2}}],["ciphers",{"2":{"33":2}}],["certificate",{"2":{"33":2}}],["cron的cron实现了server接口",{"2":{"40":1,"41":1}}],["cron",{"2":{"14":1}}],["create",{"2":{"8":1,"9":1}}],["cn",{"2":{"13":1}}],["cosrepository",{"2":{"53":4}}],["cosclient",{"2":{"53":2}}],["com",{"2":{"3":1,"13":1,"14":2,"33":2,"51":1,"52":1}}],["compose",{"2":{"1":1}}],["context",{"2":{"38":4}}],["controller",{"2":{"2":1}}],["conf=config",{"2":{"32":1}}],["config",{"2":{"1":2,"4":1}}],["cmd",{"2":{"1":2,"3":3,"15":1}}],["mysql",{"2":{"51":2,"52":2}}],["md5",{"2":{"4":1,"33":1}}],["md",{"2":{"3":1}}],["makefile",{"2":{"1":1}}],["main",{"2":{"1":1,"3":1,"15":1,"51":2,"52":2}}],["more",{"2":{"4":1}}],["mode",{"2":{"32":1}}],["model",{"0":{"30":1},"2":{"1":1,"2":1}}],["mod",{"2":{"1":1}}],["mocks",{"2":{"1":1}}],["migrate的migrate实现了server接口",{"2":{"42":1}}],["migration服务",{"2":{"42":1}}],["migration等",{"2":{"14":1}}],["migration",{"0":{"42":1},"2":{"1":1,"3":1}}],["middleware",{"2":{"1":1}}],["grpc",{"2":{"38":1}}],["g",{"2":{"32":1}}],["gin的engine实现了server接口",{"2":{"39":1}}],["gin是一个go",{"2":{"21":1}}],["git",{"2":{"14":2}}],["gitee",{"2":{"14":2}}],["github",{"2":{"3":1,"13":1,"51":1,"52":1}}],["guide",{"2":{"3":1}}],["gen",{"2":{"1":1,"3":2}}],["gojwtjwt",{"2":{"53":1}}],["gopackage",{"2":{"51":1,"52":1}}],["goproxy",{"2":{"13":1}}],["goproxy=https",{"2":{"13":1}}],["gotype",{"2":{"38":1}}],["gobin",{"2":{"13":1}}],["go111module=on",{"2":{"13":1}}],["golang",{"2":{"5":2,"14":2}}],["go文件为自动编译生成",{"2":{"3":1}}],["google",{"2":{"3":1}}],["go",{"2":{"1":5,"3":5,"13":3,"14":2,"15":1,"51":2,"52":1}}],["└──",{"2":{"1":7}}],["│",{"2":{"1":22}}],["├──",{"2":{"1":22}}],["采用了依赖注入框架wire",{"2":{"0":1}}],["同时",{"2":{"0":1}}]],"serializationVersion":2}';export{e as default}; diff --git a/docs/assets/chunks/@localSearchIndexroot.BKsY5Ty1.js b/docs/assets/chunks/@localSearchIndexroot.BKsY5Ty1.js deleted file mode 100644 index a3ef12f..0000000 --- a/docs/assets/chunks/@localSearchIndexroot.BKsY5Ty1.js +++ /dev/null @@ -1 +0,0 @@ -const e='{"documentCount":54,"nextId":54,"documentIds":{"0":"/nunu/architecture#nunu架构详解","1":"/nunu/architecture#目录结构","2":"/nunu/architecture#internal","3":"/nunu/architecture#依赖注入","4":"/nunu/architecture#公共代码","5":"/nunu/cli#info","6":"/nunu/cli#new","7":"/nunu/cli#run","8":"/nunu/cli#create","9":"/nunu/cli#waire","10":"/nunu/cli#upgrade","11":"/nunu/database#数据库","12":"/nunu/docker#docker","13":"/nunu/docker#镜像构建","14":"/nunu/docker#容器运行","15":"/nunu/getting-started#快速开始","16":"/nunu/getting-started#install","17":"/nunu/getting-started#创建新项目","18":"/nunu/getting-started#启动服务","19":"/nunu/guide#what-is-nunu","20":"/nunu/guide#developer-experience","21":"/nunu/guide#performance","22":"/nunu/handler#handler","23":"/nunu/k8s#k8s集群部署","24":"/nunu/logger#日志功能","25":"/nunu/middleware#http中间件","26":"/nunu/middleware#限流器","27":"/nunu/middleware#日志trace","28":"/nunu/middleware#签名验证","29":"/nunu/middleware#跨域","30":"/nunu/model#model","31":"/nunu/nginx#非容器部署-pm2-nginx","32":"/nunu/nginx#pm2","33":"/nunu/nginx#nginx配置","34":"/nunu/pkg#扩展包","35":"/nunu/pr#贡献指南","36":"/nunu/redis#redis","37":"/nunu/repository#repository","38":"/nunu/server#server基础概念","39":"/nunu/server#http","40":"/nunu/server#task","41":"/nunu/server#job","42":"/nunu/server#migration","43":"/nunu/service#service","44":"/nunu/swagger#自动化文档","45":"/nunu/unit-test#单元测试","46":"/nunu/swarm#docker-swarm集群部署","47":"/nunu/swarm#swarm-yml配置","48":"/nunu/swarm#滚动更新","49":"/nunu/wire#依赖注入","50":"/nunu/wire#why-do-we-need-dependency-injection","51":"/nunu/wire#global-variable-issues","52":"/nunu/wire#manual-dependency-injection","53":"/nunu/wire#automatic-dependency-injection"},"fieldIds":{"title":0,"titles":1,"text":2},"fieldLength":{"0":[1,1,5],"1":[1,1,55],"2":[1,1,30],"3":[1,1,30],"4":[1,1,26],"5":[1,1,13],"6":[1,1,4],"7":[1,1,10],"8":[1,1,16],"9":[1,1,10],"10":[1,1,3],"11":[1,1,1],"12":[1,1,1],"13":[1,1,1],"14":[1,1,1],"15":[1,1,1],"16":[1,1,32],"17":[1,1,45],"18":[1,1,22],"19":[3,1,11],"20":[1,3,16],"21":[1,3,13],"22":[1,1,1],"23":[1,1,1],"24":[1,1,1],"25":[1,1,1],"26":[1,1,1],"27":[1,1,1],"28":[1,1,1],"29":[1,1,1],"30":[1,1,1],"31":[3,1,1],"32":[1,3,35],"33":[1,3,87],"34":[1,1,1],"35":[1,1,1],"36":[1,1,1],"37":[1,1,1],"38":[1,1,19],"39":[1,1,10],"40":[1,1,18],"41":[1,1,20],"42":[1,1,21],"43":[1,1,1],"44":[1,1,1],"45":[1,1,1],"46":[2,1,1],"47":[2,2,1],"48":[1,2,1],"49":[1,1,1],"50":[2,1,6],"51":[1,1,65],"52":[1,1,59],"53":[1,1,148]},"averageFieldLength":[1.1296296296296295,1.185185185185185,15.833333333333334],"storedFields":{"0":{"title":"Nunu架构详解","titles":[]},"1":{"title":"目录结构","titles":["Nunu架构详解"]},"2":{"title":"internal","titles":["Nunu架构详解"]},"3":{"title":"依赖注入","titles":["Nunu架构详解"]},"4":{"title":"公共代码","titles":["Nunu架构详解"]},"5":{"title":"nunu命令行工具","titles":[]},"6":{"title":"创建项目","titles":["nunu命令行工具"]},"7":{"title":"启动项目","titles":["nunu命令行工具"]},"8":{"title":"创建组件","titles":["nunu命令行工具"]},"9":{"title":"编译wire","titles":["nunu命令行工具"]},"10":{"title":"版本升级","titles":["nunu命令行工具"]},"11":{"title":"数据库","titles":[]},"12":{"title":"Docker","titles":[]},"13":{"title":"镜像构建","titles":["Docker"]},"14":{"title":"容器运行","titles":["Docker"]},"15":{"title":"快速开始","titles":[]},"16":{"title":"安装Nunu","titles":["快速开始"]},"17":{"title":"创建新项目","titles":["快速开始"]},"18":{"title":"启动服务","titles":["快速开始"]},"19":{"title":"Nunu 是什么?","titles":[]},"20":{"title":"开发体验","titles":["Nunu 是什么?"]},"21":{"title":"性能","titles":["Nunu 是什么?"]},"22":{"title":"Handler","titles":[]},"23":{"title":"k8s集群部署","titles":[]},"24":{"title":"日志功能","titles":[]},"25":{"title":"HTTP中间件","titles":[]},"26":{"title":"限流器","titles":["HTTP中间件"]},"27":{"title":"日志Trace","titles":["HTTP中间件"]},"28":{"title":"签名验证","titles":["HTTP中间件"]},"29":{"title":"跨域","titles":["HTTP中间件"]},"30":{"title":"Model","titles":[]},"31":{"title":"非容器部署(PM2+Nginx)","titles":[]},"32":{"title":"PM2","titles":["非容器部署(PM2+Nginx)"]},"33":{"title":"Nginx配置","titles":["非容器部署(PM2+Nginx)"]},"34":{"title":"扩展包","titles":[]},"35":{"title":"贡献指南","titles":[]},"36":{"title":"Redis","titles":[]},"37":{"title":"Repository","titles":[]},"38":{"title":"Server基础概念","titles":[]},"39":{"title":"HTTP","titles":["Server基础概念"]},"40":{"title":"Task","titles":["Server基础概念"]},"41":{"title":"Job","titles":["Server基础概念"]},"42":{"title":"Migration","titles":["Server基础概念"]},"43":{"title":"Service","titles":[]},"44":{"title":"自动化文档","titles":[]},"45":{"title":"单元测试","titles":[]},"46":{"title":"Docker Swarm集群部署","titles":[]},"47":{"title":"swarm.yml配置","titles":["Docker Swarm集群部署"]},"48":{"title":"滚动更新","titles":["Docker Swarm集群部署"]},"49":{"title":"依赖注入","titles":[]},"50":{"title":"为什么需要依赖注入?","titles":["依赖注入"]},"51":{"title":"全局变量","titles":["依赖注入"]},"52":{"title":"手动依赖注入","titles":["依赖注入"]},"53":{"title":"自动依赖注入","titles":["依赖注入"]}},"dirtCount":0,"index":[["前往到wire官方文档",{"2":{"53":1}}],["前端代码",{"2":{"1":1}}],["想学习更多关于wire知识",{"2":{"53":1}}],["代码大概像下面这样",{"2":{"53":1}}],["代码变得更易于理解和维护",{"2":{"52":1}}],["声明依赖关系的代码非常简单",{"2":{"53":1}}],["就会自动帮我们生成代码",{"2":{"53":1}}],["执行wire命令后",{"2":{"53":1}}],["相信你一定会感觉依赖注入使我们代码使变得复杂",{"2":{"53":1}}],["相关的代码",{"2":{"4":1}}],["看到这样的代码",{"2":{"53":1}}],["手动进行依赖注入可能会变得繁琐",{"2":{"53":1}}],["手动依赖注入",{"0":{"52":1}}],["的行为",{"2":{"52":1}}],["的目录",{"2":{"17":1}}],["现在我们可以轻松地通过传递模拟的数据库连接来测试",{"2":{"52":1}}],["易于测试",{"2":{"52":1}}],["更易于重用和测试",{"2":{"52":1}}],["解耦",{"2":{"52":1}}],["函数",{"2":{"52":1}}],["作为参数传递给",{"2":{"52":1}}],["来执行数据库操作",{"2":{"52":1}}],["来保存数据库连接",{"2":{"51":1}}],["下面是使用依赖注入改进上面示例的代码",{"2":{"52":1}}],["方法参数或者其他方式传递进来",{"2":{"52":1}}],["依赖关系不再硬编码到组件内部",{"2":{"52":1}}],["依赖注入可以帮助解决这些问题",{"2":{"52":1}}],["依赖注入是一种编程模式",{"2":{"50":1}}],["依赖注入",{"0":{"3":1,"49":1},"1":{"50":1,"51":1,"52":1,"53":1}}],["降低了代码的可维护性",{"2":{"51":1}}],["当项目变得庞大时",{"2":{"53":1}}],["当代码规模增大时",{"2":{"51":1}}],["当然",{"2":{"4":1}}],["使得",{"2":{"52":1}}],["使得代码难以重构和维护",{"2":{"51":1}}],["使用服务进行操作",{"2":{"52":1}}],["使用",{"2":{"52":1}}],["使用全局变量",{"2":{"51":1}}],["使用基础模板",{"2":{"17":1}}],["使用高级模板",{"2":{"17":1}}],["另一个部分的代码可能会修改该全局变量",{"2":{"51":1}}],["但其实这段代码并不是人工手写的",{"2":{"53":1}}],["但是在调用该函数之前",{"2":{"51":1}}],["但同时nunu支持task和http",{"2":{"40":1}}],["不可控的副作用",{"2":{"51":1}}],["因为在测试过程中很难控制全局变量的状态",{"2":{"51":1}}],["难以测试",{"2":{"51":1}}],["很容易引发意外的行为",{"2":{"51":1}}],["从而改变函数的行为",{"2":{"51":1}}],["从而引发难以调试的错误",{"2":{"51":1}}],["从消息队列中获取任务并执行",{"2":{"41":1}}],["多个并发执行的程序可能会同时访问和修改全局变量",{"2":{"51":1}}],["=",{"2":{"51":1,"52":2,"53":44}}],["初始化数据库连接",{"2":{"51":1,"52":1}}],["viper",{"2":{"53":2}}],["viperviper",{"2":{"53":13}}],["var",{"2":{"51":1,"53":3}}],["v1",{"2":{"1":1}}],["假设我们有一个简单的服务",{"2":{"51":1}}],["语言示例来说明",{"2":{"51":1}}],["语言编写的web框架",{"2":{"21":1}}],["让我们通过一个简单的",{"2":{"51":1}}],["全局变量会导致代码难以理解和修改",{"2":{"51":1}}],["全局变量增加了代码的耦合性",{"2":{"51":1}}],["全局变量的值可以在程序的任何地方被修改",{"2":{"51":1}}],["全局变量的状态不受控制",{"2":{"51":1}}],["全局变量使得单元测试变得困难",{"2":{"51":1}}],["全局变量",{"0":{"51":1}}],["这样做带来了以下好处",{"2":{"52":1}}],["这样做可能会引发以下问题",{"2":{"51":1}}],["这可能导致不可预测的副作用",{"2":{"51":1}}],["这可能导致测试覆盖不全或者需要编写更多的集成测试来覆盖全局变量的不同状态",{"2":{"51":1}}],["这可能导致竞态条件和数据竞争",{"2":{"51":1}}],["这里可能会有很多其他的逻辑",{"2":{"51":1}}],["这种方式会带来一些问题",{"2":{"50":1}}],["这是因为环境变量没有配置",{"2":{"16":1}}],["为什么需要依赖注入",{"0":{"50":1}}],["为了实现代码的复用和统一管理",{"2":{"4":1}}],["为了更好地实现模块化和解耦",{"2":{"0":1}}],["滚动更新",{"0":{"48":1}}],["单元测试",{"0":{"45":1}}],["自动依赖注入",{"0":{"53":1}}],["自动化文档",{"0":{"44":1}}],["自动生成依赖注入的代码wire",{"2":{"3":1}}],["以免导致数据丢失或破坏",{"2":{"42":1}}],["以其轻量级和高性能著称",{"2":{"21":1}}],["确保数据库结构与应用程序代码的版本兼容性",{"2":{"42":1}}],["确保您的应用程序按预期工作",{"2":{"20":1}}],["管理数据库版本",{"2":{"42":1}}],["拆分数据等",{"2":{"42":1}}],["合并数据",{"2":{"42":1}}],["迁移数据",{"2":{"42":1}}],["迁移数据库表结构",{"2":{"42":1}}],["修改列的数据类型等",{"2":{"42":1}}],["修改为你自己的go服务端口",{"2":{"33":1}}],["删除旧的列",{"2":{"42":1}}],["例如",{"2":{"51":1}}],["例如将旧数据格式转换为新的格式",{"2":{"42":1}}],["例如添加新的列",{"2":{"42":1}}],["例如在软件升级过程中",{"2":{"42":1}}],["需要更新数据库模式或迁移现有数据以适应新的模式",{"2":{"42":1}}],["也同样支持独立于http",{"2":{"41":1}}],["也就是start",{"2":{"38":1}}],["消息驱动的系统等",{"2":{"41":1}}],["异步任务队列",{"2":{"41":1}}],["文件处理等",{"2":{"41":1}}],["文档完善和测试完备",{"2":{"20":1}}],["中的消息",{"2":{"41":1}}],["避免影响主应用程序的运行",{"2":{"40":1}}],["定时任务建议独立于http",{"2":{"40":1}}],["定时报表生成等",{"2":{"40":1}}],["定时数据清理",{"2":{"40":1}}],["定时数据备份",{"2":{"40":1}}],["定期执行预定义的任务或作业",{"2":{"40":1}}],["定义了server子命令需要的依赖关系",{"2":{"3":1}}],["定义了migration子命令需要的依赖关系",{"2":{"3":1}}],["定义了job子命令需要的依赖关系",{"2":{"3":1}}],["定义了业务逻辑层需要的数据结构",{"2":{"2":1}}],["类似于crontab的功能",{"2":{"40":1}}],["示例应用场景",{"2":{"39":1,"40":1,"41":1,"42":1}}],["并将数据库连接传递进去",{"2":{"52":1}}],["并发安全问题",{"2":{"51":1}}],["并根据接收到的请求执行相应的操作",{"2":{"39":1}}],["并在其中生成一个优雅的",{"2":{"17":1}}],["监听指定的http端口",{"2":{"39":1}}],["监听端口",{"2":{"2":1}}],["工作原理",{"2":{"39":1,"40":1,"41":1,"42":1}}],["用于管理代码中各个组件之间的依赖关系",{"2":{"50":1}}],["用于部署和其他自动化任务",{"2":{"1":1}}],["用途",{"2":{"39":1,"40":1,"41":1,"42":1}}],["每个server都必须实现server接口中的方法",{"2":{"38":1}}],["\\t\\tnewapp",{"2":{"53":1}}],["\\t\\tjwt",{"2":{"53":1}}],["\\t\\tsid",{"2":{"53":1}}],["\\t\\tserverset",{"2":{"53":1}}],["\\t\\tserviceset",{"2":{"53":1}}],["\\t\\thandlerset",{"2":{"53":1}}],["\\t\\trepositoryset",{"2":{"53":1}}],["\\t\\tapp",{"2":{"53":2}}],["\\tpanic",{"2":{"53":1}}],["\\treturn",{"2":{"53":1}}],["\\trepository",{"2":{"53":6}}],["\\tserver",{"2":{"53":3}}],["\\tservice",{"2":{"53":2}}],["\\tstop",{"2":{"38":1}}],["\\tstart",{"2":{"38":1}}],["\\thandler",{"2":{"53":3}}],["\\tdb",{"2":{"51":1}}],["\\t",{"2":{"51":5,"53":2}}],["\\tlisten",{"2":{"33":1}}],["贡献指南",{"0":{"35":1}}],["扩展包",{"0":{"34":1}}],["x26",{"2":{"52":1}}],["x",{"2":{"33":4}}],["xxx",{"2":{"33":4}}],["open",{"2":{"51":1,"52":1}}],["officialaccount",{"2":{"53":2}}],["off",{"2":{"33":2}}],["on",{"2":{"33":1}}],["orderrepository",{"2":{"53":2}}],["or",{"2":{"2":5}}],["3306",{"2":{"51":1,"52":1}}],["3",{"2":{"33":1}}],["2",{"2":{"33":1}}],["key",{"2":{"33":1}}],["k8s集群部署",{"0":{"23":1}}],["fileservice",{"2":{"53":2}}],["filerepository",{"2":{"53":3}}],["func",{"2":{"51":2,"52":3,"53":3}}],["fullchain",{"2":{"33":1}}],["for",{"2":{"33":3}}],["forwarded",{"2":{"33":3}}],["fork",{"2":{"32":1}}],["404",{"2":{"33":2}}],["443",{"2":{"33":1}}],["替换为你的真实部署路径",{"2":{"33":1}}],["填写你的域名",{"2":{"33":1}}],["yml配置",{"0":{"47":1}}],["yml",{"2":{"32":1}}],["yml等",{"2":{"1":1}}],["err",{"2":{"53":6}}],["error",{"2":{"33":1,"38":2,"53":1}}],["eecdh+3des",{"2":{"33":1}}],["eecdh+aes256",{"2":{"33":1}}],["eecdh+aes128",{"2":{"33":1}}],["eecdh+chacha20",{"2":{"33":2}}],["exec",{"2":{"32":1}}],["env",{"2":{"16":2}}],["entity",{"2":{"2":1}}],["在依赖注入中",{"2":{"52":1}}],["在并发环境中",{"2":{"51":1}}],["在上面的代码中",{"2":{"51":1,"52":1}}],["在没有依赖注入的情况下",{"2":{"50":1,"51":1}}],["在nunu中",{"2":{"38":1}}],["在项目根目录",{"2":{"32":1}}],["在创建项目之前",{"2":{"17":1}}],["if",{"2":{"53":2}}],["import",{"2":{"51":1,"52":1}}],["ip",{"2":{"33":1}}],["i",{"2":{"32":1}}],["init",{"2":{"51":1}}],["interface",{"2":{"38":1}}],["internal",{"0":{"2":1},"2":{"1":2,"2":5}}],["instances",{"2":{"32":1}}],["install成功",{"2":{"16":1}}],["install",{"2":{"16":2,"32":1}}],["index",{"2":{"18":1,"33":4}}],["然后返回相应的http响应",{"2":{"39":1}}],["然后直接使用npm安装pm2即可",{"2":{"32":1}}],["然后自己选择对应的文件编译",{"2":{"9":1}}],["所以需要在你的服务器先安装nodejs",{"2":{"32":1}}],["由于pm2依赖于nodejs",{"2":{"32":1}}],["安装pm2",{"2":{"32":1}}],["安装nunu",{"0":{"16":1}}],["查看进程日志以及资源占用情况等信息",{"2":{"32":1}}],["还可以可以监控进程状态",{"2":{"32":1}}],["是一个进程管理器",{"2":{"32":1}}],["是什么",{"0":{"19":1},"1":{"20":1,"21":1}}],["非容器部署",{"0":{"31":1},"1":{"32":1,"33":1}}],["跨域",{"0":{"29":1}}],["签名验证",{"0":{"28":1}}],["限流器",{"0":{"26":1}}],["保证原生组件的性能与稳定性",{"2":{"21":1}}],["轻度的组件封装",{"2":{"21":1}}],["而是通过wire自动生成的",{"2":{"53":1}}],["而是通过构造函数",{"2":{"52":1}}],["而是简洁直观的导入第三方包",{"2":{"21":1}}],["而是在编译期通过静态代码生成的方式达成这个目的",{"2":{"21":1}}],["而你只想编译指定的wire",{"2":{"9":1}}],["无损的依赖注入",{"2":{"21":1}}],["又称为golang",{"2":{"21":1}}],["高性能gin",{"2":{"21":1}}],["高级模板",{"2":{"17":1}}],["性能",{"0":{"21":1}}],["帮助您快速入门",{"2":{"20":1}}],["模块化和可扩展",{"2":{"20":1}}],["超低学习成本和定制",{"2":{"20":1}}],["旨在golang项目开发时提供出色的开发体验",{"2":{"20":1}}],["跳到快速开始",{"2":{"19":1}}],["只是想尝试一下",{"2":{"19":1}}],["可维护性",{"2":{"52":1}}],["可维护性差",{"2":{"51":1}}],["可以是一些需要异步处理的任务",{"2":{"41":1}}],["可以管理后端服务进程",{"2":{"32":1}}],["可以把",{"2":{"16":1}}],["可靠的应用程序",{"2":{"19":1}}],["它使用了依赖注入来管理各个组件之间的依赖关系",{"2":{"53":1}}],["它需要一个数据库连接",{"2":{"51":1}}],["它还包括一套测试套件",{"2":{"20":1}}],["它提供了全面的文档和示例",{"2":{"20":1}}],["它们的组合可以帮助你快速构建一个高效",{"2":{"19":1}}],["它是由golang生态中各种非常流行的库整合而成的",{"2":{"19":1}}],["它的名字来自于英雄联盟中的游戏角色",{"2":{"19":1}}],["该项目也是站在巨人的肩膀上",{"2":{"19":1}}],["和数据库连接之间的关系解耦",{"2":{"52":1}}],["和stop",{"2":{"38":1}}],["和努努一样",{"2":{"19":1}}],["和部署",{"2":{"5":1}}],["一个函数可能会依赖于某个全局变量的值",{"2":{"51":1}}],["一个骑在雪怪肩膀上的小男孩",{"2":{"19":1}}],["一些通用的辅助函数",{"2":{"4":1}}],["80",{"2":{"33":1}}],["8000",{"2":{"18":1,"33":1}}],["8080即可看到欢迎页面",{"2":{"18":1}}],["10m",{"2":{"33":2}}],["1",{"2":{"18":1,"32":1,"33":2}}],["127",{"2":{"18":1,"33":1}}],["0",{"2":{"18":2,"33":2}}],["随后打开浏览器访问http",{"2":{"18":1}}],["我们需要做的仅仅是需要声明我们的依赖关系",{"2":{"53":1}}],["我们需要了解到nunu内置了两种类型的layout",{"2":{"17":1}}],["我们通过将",{"2":{"52":1}}],["我们使用了全局变量",{"2":{"51":1}}],["我们可能会这样实现",{"2":{"51":1}}],["我们将http",{"2":{"38":1}}],["我们进入项目执行nunu",{"2":{"18":1}}],["推荐",{"2":{"17":1}}],["推荐选择advanced",{"2":{"17":1}}],["你也可以使用国内加速仓库",{"2":{"17":1}}],["你可以使用",{"2":{"8":1,"9":1}}],["你可以自由添加扩展更多的pkg",{"2":{"4":1}}],["国内加速源",{"2":{"17":1}}],["国内用户可以使用goproxy加速go",{"2":{"16":1}}],["此命令将创建一个名为",{"2":{"17":1}}],["适合开发者快速学习了解nunu的架构思想",{"2":{"17":1}}],["适合非常熟悉nunu项目的开发者使用",{"2":{"17":1}}],["json",{"2":{"32":3}}],["jwtjwt",{"2":{"53":2}}],["jwt",{"2":{"17":1,"53":1}}],["job等服务都抽象为server",{"2":{"38":1}}],["job",{"0":{"41":1},"2":{"3":1,"53":5}}],["基础模板",{"2":{"17":1}}],["目录配置到环境变量中即可",{"2":{"16":1}}],["目录结构",{"0":{"1":1}}],["却提示找不到nunu命令",{"2":{"16":1}}],["$proxy",{"2":{"33":1}}],["$remote",{"2":{"33":2}}],["$server",{"2":{"33":1}}],["$host",{"2":{"33":1}}],["$",{"2":{"16":1}}],["listen",{"2":{"33":1}}],["linux各不相同",{"2":{"16":1}}],["location",{"2":{"33":1}}],["localhost",{"2":{"18":1,"51":1,"52":1}}],["logger",{"2":{"53":7}}],["log",{"2":{"4":1,"53":1}}],["logic",{"2":{"2":1}}],["layout",{"2":{"17":7}}],["latest",{"2":{"16":1}}],["您可以通过使用第三方库或编写自己的模块轻松添加新功能和功能",{"2":{"20":1}}],["您可以通过以下命令安装",{"2":{"16":1}}],["您可以轻松定制应用程序以满足特定需求",{"2":{"20":1}}],["您可以使用以下命令创建一个新的",{"2":{"17":1}}],["您可以很容易的进行",{"2":{"5":1}}],["快速开始",{"0":{"15":1},"1":{"16":1,"17":1,"18":1}}],["容器运行",{"0":{"14":1}}],["镜像构建",{"0":{"13":1}}],["uploadhandler",{"2":{"53":2}}],["upgrade",{"2":{"10":1}}],["userhandler",{"2":{"53":2}}],["userservice",{"2":{"53":4}}],["userrepository",{"2":{"53":4}}],["user",{"2":{"51":1,"52":1}}],["uuid",{"2":{"4":1}}],["版本升级",{"0":{"10":1}}],["编译wire",{"0":{"9":1}}],["authhandler",{"2":{"53":2}}],["add",{"2":{"33":1}}],["addr",{"2":{"33":2}}],["advanced",{"2":{"17":3}}],["args",{"2":{"32":1}}],["app",{"2":{"53":6}}],["appapp",{"2":{"53":1}}],["apps",{"2":{"32":1}}],["api服务等",{"2":{"39":1}}],["api文档地址",{"2":{"18":1}}],["api",{"2":{"1":1,"32":1}}],["all",{"2":{"8":2,"9":1}}],["详细命令",{"2":{"8":1}}],["创建服务实例",{"2":{"52":1}}],["创建pm2配置文件pm2",{"2":{"32":1}}],["创建好项目之后",{"2":{"18":1}}],["创建新项目",{"0":{"17":1}}],["创建所有组件",{"2":{"8":1}}],["创建handler创建service创建repository创建model",{"2":{"8":1}}],["创建组件",{"0":{"8":1}}],["创建项目",{"0":{"6":1}}],["build",{"2":{"53":2}}],["build之后部署",{"2":{"7":1}}],["buffering",{"2":{"33":1}}],["bin",{"2":{"32":1}}],["basic",{"2":{"17":3}}],["bash$",{"2":{"16":1}}],["bashgo",{"2":{"16":1}}],["bashnunu",{"2":{"8":4,"17":1}}],["blob",{"2":{"3":1}}],["请参考task或是migration的实现",{"2":{"41":1}}],["请参考job的实现",{"2":{"40":1}}],["请自行网络搜索",{"2":{"16":1}}],["请使用",{"2":{"7":1}}],["请求",{"2":{"2":2}}],["命令仅用于本地开发环境快速热编译运行使用",{"2":{"7":1}}],["命令行工具",{"2":{"5":1}}],["命令行工具是一个为了协助快速开发",{"2":{"5":1}}],["通常会使用全局变量或硬编码的方式来获取所需的依赖",{"2":{"50":1}}],["通常用于处理消息队列",{"2":{"41":1}}],["通常用于周期性地执行一些重复性的任务",{"2":{"40":1}}],["通常情况下",{"2":{"7":1}}],["通过明确地传递依赖关系",{"2":{"52":1}}],["通过",{"2":{"5":1}}],["port",{"2":{"33":1}}],["password",{"2":{"51":1,"52":1}}],["pass",{"2":{"33":1}}],["page",{"2":{"33":1}}],["prefer",{"2":{"33":1}}],["privkey",{"2":{"33":1}}],["prompthandler",{"2":{"53":2}}],["promptservice",{"2":{"53":2}}],["promptrepository",{"2":{"53":3}}],["proxy",{"2":{"33":7}}],["protocols",{"2":{"33":1}}],["prod",{"2":{"32":1}}],["projectname",{"2":{"6":1,"17":4}}],["pem",{"2":{"33":2}}],["php",{"2":{"33":2}}],["pm2",{"0":{"32":1},"2":{"32":4}}],["pm2+nginx",{"0":{"31":1},"1":{"32":1,"33":1}}],["pkg",{"2":{"1":2,"4":4}}],["nil",{"2":{"53":6}}],["nginxserver",{"2":{"33":1}}],["nginx配置",{"0":{"33":1}}],["npm",{"2":{"32":1}}],["name",{"2":{"8":6,"32":1,"33":1}}],["newtask",{"2":{"53":1}}],["newtranslatehandler",{"2":{"53":1}}],["newtranslateservice",{"2":{"53":1}}],["newapp",{"2":{"53":3}}],["newauthhandler",{"2":{"53":1}}],["newjob",{"2":{"53":2}}],["newjwt",{"2":{"53":2}}],["newhttpserver",{"2":{"53":2}}],["newhandler",{"2":{"53":2}}],["neworderrepository",{"2":{"53":1}}],["newprompthandler",{"2":{"53":1}}],["newpromptservice",{"2":{"53":1}}],["newpromptrepository",{"2":{"53":1}}],["newuploadhandler",{"2":{"53":1}}],["newuserhandler",{"2":{"53":2}}],["newuserservice",{"2":{"53":2}}],["newuserrepository",{"2":{"53":2}}],["newfileservice",{"2":{"53":1}}],["newfilerepository",{"2":{"53":1}}],["newcaptchaservice",{"2":{"53":1}}],["newcaptcharepository",{"2":{"53":1}}],["newcategoryhandler",{"2":{"53":2}}],["newcategoryservice",{"2":{"53":1}}],["newcategoryrepository",{"2":{"53":1}}],["newcosrepository",{"2":{"53":1}}],["newcosclient",{"2":{"53":1}}],["newwire",{"2":{"53":1}}],["newwallethandler",{"2":{"53":1}}],["newwalletservice",{"2":{"53":1}}],["newwalletrepository",{"2":{"53":1}}],["newwechathandler",{"2":{"53":1}}],["newwechatservice",{"2":{"53":1}}],["newwechatrepository",{"2":{"53":1}}],["newwechatpay",{"2":{"53":2}}],["newwechatofficial",{"2":{"53":2}}],["newrepository",{"2":{"53":2}}],["newredis",{"2":{"53":2}}],["newdb",{"2":{"53":2}}],["newset",{"2":{"53":4}}],["newservice",{"2":{"52":3,"53":2}}],["newsid",{"2":{"53":2}}],["new默认拉取github源",{"2":{"17":1}}],["new",{"2":{"6":1,"17":3}}],["nunu支持job和http",{"2":{"41":1}}],["nunu没有过度的封装一些常用组件",{"2":{"21":1}}],["nunu文档完善",{"2":{"20":1}}],["nunu旨在具有模块化和可扩展性",{"2":{"20":1}}],["nunu封装了gopher最熟悉的一些流行库",{"2":{"20":1}}],["nunu是一个基于golang的应用脚手架",{"2":{"19":1}}],["nunu",{"0":{"19":1},"1":{"20":1,"21":1},"2":{"5":2,"6":1,"7":2,"8":3,"9":2,"10":1,"16":3,"17":7,"18":1,"20":1,"32":1}}],["nunu命令行工具",{"0":{"5":1},"1":{"6":1,"7":1,"8":1,"9":1,"10":1}}],["nunu采用了经典的分层架构",{"2":{"0":1}}],["nunu架构详解",{"0":{"0":1},"1":{"1":1,"2":1,"3":1,"4":1}}],["测试完备",{"2":{"20":1}}],["测试",{"2":{"5":1}}],["测试代码",{"2":{"1":1}}],["开发体验",{"0":{"20":1}}],["开发",{"2":{"5":1}}],["热编译",{"2":{"5":1}}],["项目结构",{"2":{"17":1}}],["项目",{"2":{"17":1}}],["项目的创建",{"2":{"5":1}}],["项目而创建的项目",{"2":{"5":1}}],["客户端",{"2":{"4":1}}],["生成等",{"2":{"4":1}}],["加密",{"2":{"4":1}}],["将一些通用的代码放在了pkg目录下",{"2":{"4":1}}],["本项目采用了公共代码的方式",{"2":{"4":1}}],["本项目采用了依赖注入框架wire",{"2":{"3":1}}],["公共代码",{"0":{"4":1}}],["公共的代码",{"2":{"1":1}}],["禁止手动修改",{"2":{"3":1}}],["注意",{"2":{"3":1}}],["简化了依赖注入的过程",{"2":{"3":1}}],["实现了依赖注入",{"2":{"52":1}}],["实现了模块化和解耦",{"2":{"3":1}}],["实现具体的业务逻辑",{"2":{"2":1}}],["提供了对数据的增删改查",{"2":{"2":1}}],["封装了数据库操作",{"2":{"2":1}}],["数据库",{"0":{"11":1}}],["数据访问对象",{"2":{"2":1}}],["数据模型",{"2":{"2":1}}],["调用数据访问层repository",{"2":{"2":1}}],["调用业务逻辑层的服务",{"2":{"2":1}}],["服务",{"2":{"2":2}}],["服务器等",{"2":{"4":1}}],["服务器",{"2":{"2":1}}],["启动服务",{"0":{"18":1},"2":{"32":1}}],["启动项目",{"0":{"7":1}}],["启动",{"2":{"2":1}}],["rsa+3des",{"2":{"33":1}}],["rsa+aes256",{"2":{"33":1}}],["rsa+aes128",{"2":{"33":1}}],["root",{"2":{"33":1}}],["router",{"2":{"2":1}}],["r",{"2":{"17":2}}],["return",{"2":{"52":1,"53":2}}],["redirect",{"2":{"33":1}}],["redis",{"0":{"36":1},"2":{"17":1}}],["real",{"2":{"33":1}}],["repositoryset",{"2":{"53":1}}],["repositoryrepository",{"2":{"53":11}}],["repository",{"0":{"37":1},"2":{"1":1,"2":1,"8":2,"53":15}}],["run命令即可启动服务",{"2":{"18":1}}],["run",{"2":{"7":2,"18":1}}],["响应",{"2":{"2":1}}],["返回",{"2":{"2":1}}],["处理数据库迁移和数据迁移任务",{"2":{"42":1}}],["处理异步任务",{"2":{"41":1}}],["处理定时任务",{"2":{"40":1}}],["处理基于http协议的请求和响应",{"2":{"39":1}}],["处理",{"2":{"2":2}}],["存储文件",{"2":{"1":1}}],["脚本文件",{"2":{"1":1}}],["等",{"2":{"1":1}}],["host",{"2":{"33":1}}],["header",{"2":{"33":4}}],["helper",{"2":{"4":1}}],["htm",{"2":{"33":2}}],["html",{"2":{"18":1,"33":3}}],["http2",{"2":{"33":1}}],["http中间件",{"0":{"25":1},"1":{"26":1,"27":1,"28":1,"29":1}}],["httpserver",{"2":{"53":4}}],["https",{"2":{"3":1,"17":2}}],["http",{"0":{"39":1},"2":{"1":1,"2":5,"4":4,"18":1,"33":2,"53":1}}],["handlerset",{"2":{"53":1}}],["handlerhandler",{"2":{"53":9}}],["handler",{"0":{"22":1},"2":{"1":1,"2":1,"8":3,"53":9}}],["日志trace",{"0":{"27":1}}],["日志功能",{"0":{"24":1}}],["日志的写入等",{"2":{"4":1}}],["日志相关的代码",{"2":{"4":1}}],["日志",{"2":{"1":1}}],["包含了很多nunu的用法示例",{"2":{"17":1}}],["包含了不同的子命令",{"2":{"1":1}}],["包含一个非常精简的架构目录结构",{"2":{"17":1}}],["包括配置",{"2":{"1":1}}],["按照分层架构进行组织",{"2":{"1":1}}],["应用程序的主要代码",{"2":{"1":1}}],["应用程序的入口",{"2":{"1":1}}],["如下是一个真实项目的部分代码",{"2":{"53":1}}],["如邮件发送",{"2":{"41":1}}],["如果go",{"2":{"16":1}}],["如果你的项目存在多个wire",{"2":{"9":1}}],["如果你觉得每种组件单独创建太麻烦",{"2":{"8":1}}],["如果是生产环境",{"2":{"7":1}}],["如日志的初始化",{"2":{"4":1}}],["如日志文件",{"2":{"1":1}}],["如",{"2":{"1":1,"4":2}}],["部署相关的文件",{"2":{"1":1}}],["配置文件的读取和解析",{"2":{"4":1}}],["配置文件",{"2":{"1":1}}],["withname",{"2":{"53":1}}],["withserver",{"2":{"53":1}}],["wire不是在运行时通过反射动态地进行依赖注入",{"2":{"21":1}}],["wire官方文档",{"2":{"3":1}}],["wire配置文件",{"2":{"3":3}}],["wire通过预编译wire",{"2":{"3":1}}],["wire",{"2":{"1":3,"3":5,"9":2,"53":5}}],["wallethandler",{"2":{"53":2}}],["walletservice",{"2":{"53":2}}],["walletrepository",{"2":{"53":5}}],["wechathandler",{"2":{"53":2}}],["wechatservice",{"2":{"53":2}}],["wechatrepository",{"2":{"53":3}}],["web应用程序",{"2":{"39":1}}],["websocket",{"2":{"38":1}}],["web",{"2":{"1":2}}],["wwwroot",{"2":{"33":1}}],["www",{"2":{"33":1}}],["w",{"2":{"16":2}}],["translatehandler",{"2":{"53":2}}],["translateservice",{"2":{"53":2}}],["tcp",{"2":{"51":1,"52":1}}],["timeout",{"2":{"33":1}}],["tip",{"2":{"7":1,"9":1,"16":1,"40":1,"41":1,"42":1}}],["tlsv1",{"2":{"33":3}}],["type",{"2":{"8":1,"52":1}}],["test",{"2":{"1":2}}],["task",{"0":{"40":1},"2":{"1":1,"38":1}}],["sid",{"2":{"53":1}}],["sidsid",{"2":{"53":3}}],["s",{"2":{"52":2}}],["sql",{"2":{"51":4,"52":5}}],["swarm",{"0":{"47":1}}],["swarm集群部署",{"0":{"46":1},"1":{"47":1,"48":1}}],["swagger",{"2":{"18":1}}],["shared",{"2":{"33":1}}],["sh$",{"2":{"17":2}}],["set",{"2":{"33":4}}],["session",{"2":{"33":2}}],["serviceset",{"2":{"53":1}}],["serviceservice",{"2":{"53":9}}],["service",{"0":{"43":1},"2":{"1":1,"2":1,"8":2,"52":9,"53":9}}],["serverset",{"2":{"53":1}}],["server同时运行",{"2":{"40":1,"41":1}}],["server运行",{"2":{"40":1,"41":1}}],["server基础概念",{"0":{"38":1},"1":{"39":1,"40":1,"41":1,"42":1}}],["server",{"2":{"1":3,"2":1,"3":1,"18":1,"32":1,"33":2,"38":1,"53":5}}],["ssl证书路径",{"2":{"33":2}}],["ssl",{"2":{"33":9}}],["struct",{"2":{"52":1}}],["start",{"2":{"32":1}}],["storage",{"2":{"1":1}}],["script",{"2":{"1":1,"32":1}}],["scripts",{"2":{"1":1}}],["sum",{"2":{"1":1}}],["dosomething",{"2":{"52":2}}],["docker",{"0":{"12":1,"46":1},"1":{"13":1,"14":1,"47":1,"48":1},"2":{"1":1}}],["dockerfile",{"2":{"1":1}}],["docs",{"2":{"1":1,"3":1}}],["driver",{"2":{"51":1,"52":1}}],["draft",{"2":{"33":1}}],["database",{"2":{"51":1,"52":1}}],["data",{"2":{"33":1}}],["dao",{"2":{"2":1}}],["demo",{"2":{"53":1}}],["default",{"2":{"33":3}}],["deploy",{"2":{"1":2}}],["dbname",{"2":{"51":1,"52":1}}],["db",{"2":{"17":1,"51":4,"52":9,"53":2}}],["direct",{"2":{"16":1}}],["captchaservice",{"2":{"53":2}}],["captcharepository",{"2":{"53":3}}],["categoryhandler",{"2":{"53":2}}],["categoryservice",{"2":{"53":2}}],["categoryrepository",{"2":{"53":3}}],["cache",{"2":{"33":1}}],["clientv3",{"2":{"53":3}}],["client",{"2":{"53":2}}],["ctx",{"2":{"38":2}}],["ciphers",{"2":{"33":2}}],["certificate",{"2":{"33":2}}],["cron",{"2":{"17":1}}],["create",{"2":{"8":7}}],["cn",{"2":{"16":1}}],["cosrepository",{"2":{"53":4}}],["cosclient",{"2":{"53":2}}],["com",{"2":{"3":1,"16":1,"17":2,"33":2,"51":1,"52":1}}],["compose",{"2":{"1":1}}],["context",{"2":{"38":4}}],["controller",{"2":{"2":1}}],["conf=config",{"2":{"32":1}}],["config",{"2":{"1":2,"4":1}}],["cmd",{"2":{"1":2,"3":3,"18":1}}],["mysql",{"2":{"51":2,"52":2}}],["mq",{"2":{"41":1}}],["md5",{"2":{"4":1,"33":1}}],["md",{"2":{"3":1}}],["macos",{"2":{"16":1}}],["makefile",{"2":{"1":1}}],["main",{"2":{"1":1,"3":1,"18":1,"51":2,"52":2}}],["more",{"2":{"4":1}}],["mode",{"2":{"32":1}}],["model",{"0":{"30":1},"2":{"1":1,"2":1,"8":2}}],["mod",{"2":{"1":1}}],["mocks",{"2":{"1":1}}],["middleware",{"2":{"1":1}}],["migration须谨慎用于生成环境",{"2":{"42":1}}],["migration服务负责管理数据库结构的变化和数据的迁移",{"2":{"42":1}}],["migration等",{"2":{"17":1}}],["migration",{"0":{"42":1},"2":{"1":1,"3":1}}],["grpc",{"2":{"38":1}}],["g",{"2":{"32":1}}],["gin是一个go",{"2":{"21":1}}],["git",{"2":{"17":2}}],["gitee",{"2":{"17":2}}],["github",{"2":{"3":1,"16":1,"51":1,"52":1}}],["guide",{"2":{"3":1}}],["gen",{"2":{"1":1,"3":2}}],["govar",{"2":{"53":1}}],["gojwtjwt",{"2":{"53":1}}],["gopackage",{"2":{"51":1,"52":1}}],["goproxy",{"2":{"16":1}}],["goproxy=https",{"2":{"16":1}}],["gotype",{"2":{"38":1}}],["gobin的配置方法windows",{"2":{"16":1}}],["gobin",{"2":{"16":1}}],["go111module=on",{"2":{"16":1}}],["go文件",{"2":{"9":2}}],["go文件为自动编译生成",{"2":{"3":1}}],["golang",{"2":{"5":2,"17":2}}],["google",{"2":{"3":1}}],["go",{"2":{"1":5,"3":5,"7":1,"16":3,"17":2,"18":1,"51":2,"52":1}}],["└──",{"2":{"1":7}}],["│",{"2":{"1":22}}],["├──",{"2":{"1":22}}],["采用了依赖注入框架wire",{"2":{"0":1}}],["同时",{"2":{"0":1}}]],"serializationVersion":2}';export{e as default}; diff --git a/docs/assets/chunks/@localSearchIndexroot.R25TFYOj.js b/docs/assets/chunks/@localSearchIndexroot.R25TFYOj.js new file mode 100644 index 0000000..6964b81 --- /dev/null +++ b/docs/assets/chunks/@localSearchIndexroot.R25TFYOj.js @@ -0,0 +1 @@ +const e='{"documentCount":59,"nextId":59,"documentIds":{"0":"/nunu/architecture#nunu架构详解","1":"/nunu/architecture#目录结构","2":"/nunu/architecture#internal","3":"/nunu/architecture#依赖注入","4":"/nunu/architecture#公共代码","5":"/nunu/cli#info","6":"/nunu/cli#new","7":"/nunu/cli#run","8":"/nunu/cli#create","9":"/nunu/cli#waire","10":"/nunu/cli#upgrade","11":"/nunu/docker#docker","12":"/nunu/docker#镜像构建","13":"/nunu/docker#容器运行","14":"/nunu/database#数据库","15":"/nunu/grpc#grpc","16":"/nunu/getting-started#快速开始","17":"/nunu/getting-started#install","18":"/nunu/getting-started#创建新项目","19":"/nunu/getting-started#启动服务","20":"/nunu/guide#what-is-nunu","21":"/nunu/guide#developer-experience","22":"/nunu/guide#performance","23":"/nunu/handler#handler","24":"/nunu/http#http","25":"/nunu/http#路由定义","26":"/nunu/http#依赖注入handler","27":"/nunu/job#job","28":"/nunu/k8s#k8s集群部署","29":"/nunu/logger#日志功能","30":"/nunu/middleware#http中间件","31":"/nunu/middleware#限流器","32":"/nunu/middleware#日志trace","33":"/nunu/middleware#签名验证","34":"/nunu/middleware#跨域","35":"/nunu/migration#migration","36":"/nunu/model#model","37":"/nunu/nginx#非容器部署-pm2-nginx","38":"/nunu/nginx#pm2","39":"/nunu/nginx#nginx配置","40":"/nunu/pkg#扩展包","41":"/nunu/pr#贡献指南","42":"/nunu/redis#redis","43":"/nunu/repository#repository","44":"/nunu/server#server基础概念","45":"/nunu/server#服务依赖注册","46":"/nunu/service#service","47":"/nunu/swagger#自动化文档","48":"/nunu/swarm#docker-swarm集群部署","49":"/nunu/swarm#swarm-yml配置","50":"/nunu/swarm#滚动更新","51":"/nunu/task#task","52":"/nunu/unit-test#单元测试","53":"/nunu/websocket#websocket","54":"/nunu/wire#依赖注入","55":"/nunu/wire#why-do-we-need-dependency-injection","56":"/nunu/wire#global-variable-issues","57":"/nunu/wire#manual-dependency-injection","58":"/nunu/wire#automatic-dependency-injection"},"fieldIds":{"title":0,"titles":1,"text":2},"fieldLength":{"0":[1,1,5],"1":[1,1,55],"2":[1,1,30],"3":[1,1,30],"4":[1,1,26],"5":[1,1,13],"6":[1,1,4],"7":[1,1,10],"8":[1,1,16],"9":[1,1,10],"10":[1,1,3],"11":[1,1,1],"12":[1,1,1],"13":[1,1,1],"14":[1,1,1],"15":[1,1,2],"16":[1,1,1],"17":[1,1,32],"18":[1,1,45],"19":[1,1,22],"20":[3,1,11],"21":[1,3,16],"22":[1,3,13],"23":[1,1,1],"24":[1,1,10],"25":[1,1,34],"26":[1,1,21],"27":[1,1,20],"28":[1,1,1],"29":[1,1,1],"30":[1,1,1],"31":[1,1,1],"32":[1,1,1],"33":[1,1,1],"34":[1,1,1],"35":[1,1,21],"36":[1,1,1],"37":[3,1,1],"38":[1,3,35],"39":[1,3,87],"40":[1,1,1],"41":[1,1,1],"42":[1,1,1],"43":[1,1,1],"44":[1,1,19],"45":[1,1,54],"46":[1,1,1],"47":[1,1,1],"48":[2,1,1],"49":[2,2,1],"50":[1,2,1],"51":[1,1,18],"52":[1,1,1],"53":[1,1,2],"54":[1,1,1],"55":[2,1,6],"56":[1,1,65],"57":[1,1,59],"58":[1,1,148]},"averageFieldLength":[1.11864406779661,1.1694915254237288,16.406779661016948],"storedFields":{"0":{"title":"Nunu架构详解","titles":[]},"1":{"title":"目录结构","titles":["Nunu架构详解"]},"2":{"title":"internal","titles":["Nunu架构详解"]},"3":{"title":"依赖注入","titles":["Nunu架构详解"]},"4":{"title":"公共代码","titles":["Nunu架构详解"]},"5":{"title":"nunu命令行工具","titles":[]},"6":{"title":"创建项目","titles":["nunu命令行工具"]},"7":{"title":"启动项目","titles":["nunu命令行工具"]},"8":{"title":"创建组件","titles":["nunu命令行工具"]},"9":{"title":"编译wire","titles":["nunu命令行工具"]},"10":{"title":"版本升级","titles":["nunu命令行工具"]},"11":{"title":"Docker","titles":[]},"12":{"title":"镜像构建","titles":["Docker"]},"13":{"title":"容器运行","titles":["Docker"]},"14":{"title":"数据库","titles":[]},"15":{"title":"GRPC","titles":[]},"16":{"title":"快速开始","titles":[]},"17":{"title":"安装Nunu","titles":["快速开始"]},"18":{"title":"创建新项目","titles":["快速开始"]},"19":{"title":"启动服务","titles":["快速开始"]},"20":{"title":"Nunu 是什么?","titles":[]},"21":{"title":"开发体验","titles":["Nunu 是什么?"]},"22":{"title":"性能","titles":["Nunu 是什么?"]},"23":{"title":"Handler","titles":[]},"24":{"title":"HTTP","titles":[]},"25":{"title":"路由定义","titles":["HTTP"]},"26":{"title":"依赖注入Handler","titles":["HTTP"]},"27":{"title":"Job","titles":[]},"28":{"title":"k8s集群部署","titles":[]},"29":{"title":"日志功能","titles":[]},"30":{"title":"HTTP中间件","titles":[]},"31":{"title":"限流器","titles":["HTTP中间件"]},"32":{"title":"日志Trace","titles":["HTTP中间件"]},"33":{"title":"签名验证","titles":["HTTP中间件"]},"34":{"title":"跨域","titles":["HTTP中间件"]},"35":{"title":"Migration","titles":[]},"36":{"title":"Model","titles":[]},"37":{"title":"非容器部署(PM2+Nginx)","titles":[]},"38":{"title":"PM2","titles":["非容器部署(PM2+Nginx)"]},"39":{"title":"Nginx配置","titles":["非容器部署(PM2+Nginx)"]},"40":{"title":"扩展包","titles":[]},"41":{"title":"贡献指南","titles":[]},"42":{"title":"Redis","titles":[]},"43":{"title":"Repository","titles":[]},"44":{"title":"Server基础概念","titles":[]},"45":{"title":"服务依赖注册","titles":["Server基础概念"]},"46":{"title":"Service","titles":[]},"47":{"title":"自动化文档","titles":[]},"48":{"title":"Docker Swarm集群部署","titles":[]},"49":{"title":"swarm.yml配置","titles":["Docker Swarm集群部署"]},"50":{"title":"滚动更新","titles":["Docker Swarm集群部署"]},"51":{"title":"Task","titles":[]},"52":{"title":"单元测试","titles":[]},"53":{"title":"Websocket","titles":[]},"54":{"title":"依赖注入","titles":[]},"55":{"title":"为什么需要依赖注入?","titles":["依赖注入"]},"56":{"title":"全局变量","titles":["依赖注入"]},"57":{"title":"手动依赖注入","titles":["依赖注入"]},"58":{"title":"自动依赖注入","titles":["依赖注入"]}},"dirtCount":0,"index":[["前往到wire官方文档",{"2":{"58":1}}],["前端代码",{"2":{"1":1}}],["想学习更多关于wire知识",{"2":{"58":1}}],["代码大概像下面这样",{"2":{"58":1}}],["代码变得更易于理解和维护",{"2":{"57":1}}],["声明依赖关系的代码非常简单",{"2":{"58":1}}],["就会自动帮我们生成代码",{"2":{"58":1}}],["执行wire命令后",{"2":{"58":1}}],["相信你一定会感觉依赖注入使我们代码使变得复杂",{"2":{"58":1}}],["相关的代码",{"2":{"4":1}}],["看到这样的代码",{"2":{"58":1}}],["手动进行依赖注入可能会变得繁琐",{"2":{"58":1}}],["手动依赖注入",{"0":{"57":1}}],["的行为",{"2":{"57":1}}],["的目录",{"2":{"18":1}}],["现在我们可以轻松地通过传递模拟的数据库连接来测试",{"2":{"57":1}}],["易于测试",{"2":{"57":1}}],["更易于重用和测试",{"2":{"57":1}}],["更多handler",{"2":{"26":1}}],["解耦",{"2":{"57":1}}],["函数",{"2":{"57":1}}],["作为参数传递给",{"2":{"57":1}}],["来执行数据库操作",{"2":{"57":1}}],["来保存数据库连接",{"2":{"56":1}}],["下面是使用依赖注入改进上面示例的代码",{"2":{"57":1}}],["方法参数或者其他方式传递进来",{"2":{"57":1}}],["依赖关系不再硬编码到组件内部",{"2":{"57":1}}],["依赖注入可以帮助解决这些问题",{"2":{"57":1}}],["依赖注入是一种编程模式",{"2":{"55":1}}],["依赖注入handler",{"0":{"26":1}}],["依赖注入",{"0":{"3":1,"54":1},"1":{"55":1,"56":1,"57":1,"58":1}}],["降低了代码的可维护性",{"2":{"56":1}}],["当项目变得庞大时",{"2":{"58":1}}],["当代码规模增大时",{"2":{"56":1}}],["当然",{"2":{"4":1}}],["使得",{"2":{"57":1}}],["使得代码难以重构和维护",{"2":{"56":1}}],["使用服务进行操作",{"2":{"57":1}}],["使用",{"2":{"57":1}}],["使用全局变量",{"2":{"56":1}}],["使用基础模板",{"2":{"18":1}}],["使用高级模板",{"2":{"18":1}}],["另一个部分的代码可能会修改该全局变量",{"2":{"56":1}}],["但其实这段代码并不是人工手写的",{"2":{"58":1}}],["但是在调用该函数之前",{"2":{"56":1}}],["但同时nunu支持task和http",{"2":{"51":1}}],["不可控的副作用",{"2":{"56":1}}],["因为在测试过程中很难控制全局变量的状态",{"2":{"56":1}}],["难以测试",{"2":{"56":1}}],["很容易引发意外的行为",{"2":{"56":1}}],["从而改变函数的行为",{"2":{"56":1}}],["从而引发难以调试的错误",{"2":{"56":1}}],["从消息队列中获取任务并执行",{"2":{"27":1}}],["多个并发执行的程序可能会同时访问和修改全局变量",{"2":{"56":1}}],["初始化数据库连接",{"2":{"56":1,"57":1}}],["假设我们有一个简单的服务",{"2":{"56":1}}],["语言示例来说明",{"2":{"56":1}}],["语言编写的web框架",{"2":{"22":1}}],["让我们通过一个简单的",{"2":{"56":1}}],["全局变量会导致代码难以理解和修改",{"2":{"56":1}}],["全局变量增加了代码的耦合性",{"2":{"56":1}}],["全局变量的值可以在程序的任何地方被修改",{"2":{"56":1}}],["全局变量的状态不受控制",{"2":{"56":1}}],["全局变量使得单元测试变得困难",{"2":{"56":1}}],["全局变量",{"0":{"56":1}}],["这样做带来了以下好处",{"2":{"57":1}}],["这样做可能会引发以下问题",{"2":{"56":1}}],["这可能导致不可预测的副作用",{"2":{"56":1}}],["这可能导致测试覆盖不全或者需要编写更多的集成测试来覆盖全局变量的不同状态",{"2":{"56":1}}],["这可能导致竞态条件和数据竞争",{"2":{"56":1}}],["这里可能会有很多其他的逻辑",{"2":{"56":1}}],["这种方式会带来一些问题",{"2":{"55":1}}],["这是因为环境变量没有配置",{"2":{"17":1}}],["为什么需要依赖注入",{"0":{"55":1}}],["为了实现代码的复用和统一管理",{"2":{"4":1}}],["为了更好地实现模块化和解耦",{"2":{"0":1}}],["单元测试",{"0":{"52":1}}],["避免影响主应用程序的运行",{"2":{"51":1}}],["定时任务建议独立于http",{"2":{"51":1}}],["定时报表生成等",{"2":{"51":1}}],["定时数据清理",{"2":{"51":1}}],["定时数据备份",{"2":{"51":1}}],["定期执行预定义的任务或作业",{"2":{"51":1}}],["定义了server子命令需要的依赖关系",{"2":{"3":1}}],["定义了migration子命令需要的依赖关系",{"2":{"3":1}}],["定义了job子命令需要的依赖关系",{"2":{"3":1}}],["定义了业务逻辑层需要的数据结构",{"2":{"2":1}}],["类似于crontab的功能",{"2":{"51":1}}],["滚动更新",{"0":{"50":1}}],["自动依赖注入",{"0":{"58":1}}],["自动化文档",{"0":{"47":1}}],["自动生成依赖注入的代码wire",{"2":{"3":1}}],["集中注册服务",{"2":{"45":1}}],["=",{"2":{"45":1,"56":1,"57":2,"58":44}}],["也就是start",{"2":{"44":1}}],["也同样支持独立于http",{"2":{"27":1}}],["每个server都必须实现server接口中的方法",{"2":{"44":1}}],["贡献指南",{"0":{"41":1}}],["扩展包",{"0":{"40":1}}],["x26",{"2":{"57":1}}],["x",{"2":{"39":4}}],["xxx",{"2":{"39":4}}],["修改为你自己的go服务端口",{"2":{"39":1}}],["修改列的数据类型等",{"2":{"35":1}}],["open",{"2":{"56":1,"57":1}}],["officialaccount",{"2":{"58":2}}],["off",{"2":{"39":2}}],["on",{"2":{"39":1}}],["orderrepository",{"2":{"58":2}}],["or",{"2":{"2":5}}],["3306",{"2":{"56":1,"57":1}}],["3",{"2":{"39":1}}],["2",{"2":{"39":1}}],["key",{"2":{"39":1}}],["k8s集群部署",{"0":{"28":1}}],["fileservice",{"2":{"58":2}}],["filerepository",{"2":{"58":3}}],["func",{"2":{"45":3,"56":2,"57":3,"58":3}}],["fullchain",{"2":{"39":1}}],["for",{"2":{"39":3}}],["forwarded",{"2":{"39":3}}],["fork",{"2":{"38":1}}],["404",{"2":{"39":2}}],["443",{"2":{"39":1}}],["替换为你的真实部署路径",{"2":{"39":1}}],["填写你的域名",{"2":{"39":1}}],["yml配置",{"0":{"49":1}}],["yml",{"2":{"38":1}}],["yml等",{"2":{"1":1}}],["err",{"2":{"58":6}}],["error",{"2":{"39":1,"44":2,"45":1,"58":1}}],["eecdh+3des",{"2":{"39":1}}],["eecdh+aes256",{"2":{"39":1}}],["eecdh+aes128",{"2":{"39":1}}],["eecdh+chacha20",{"2":{"39":2}}],["exec",{"2":{"38":1}}],["engine对象",{"2":{"25":1}}],["env",{"2":{"17":2}}],["entity",{"2":{"2":1}}],["if",{"2":{"58":2}}],["import",{"2":{"56":1,"57":1}}],["ip",{"2":{"39":1}}],["i",{"2":{"38":1}}],["init",{"2":{"56":1}}],["interface",{"2":{"44":1}}],["internal",{"0":{"2":1},"2":{"1":2,"2":5}}],["instances",{"2":{"38":1}}],["install成功",{"2":{"17":1}}],["install",{"2":{"17":2,"38":1}}],["index",{"2":{"19":1,"39":4}}],["所以需要在你的服务器先安装nodejs",{"2":{"38":1}}],["由于pm2依赖于nodejs",{"2":{"38":1}}],["安装pm2",{"2":{"38":1}}],["安装nunu",{"0":{"17":1}}],["查看进程日志以及资源占用情况等信息",{"2":{"38":1}}],["还可以可以监控进程状态",{"2":{"38":1}}],["是一个进程管理器",{"2":{"38":1}}],["是什么",{"0":{"20":1},"1":{"21":1,"22":1}}],["非容器部署",{"0":{"37":1},"1":{"38":1,"39":1}}],["以免导致数据丢失或破坏",{"2":{"35":1}}],["以其轻量级和高性能著称",{"2":{"22":1}}],["确保数据库结构与应用程序代码的版本兼容性",{"2":{"35":1}}],["确保您的应用程序按预期工作",{"2":{"21":1}}],["管理数据库版本",{"2":{"35":1}}],["拆分数据等",{"2":{"35":1}}],["合并数据",{"2":{"35":1}}],["迁移数据",{"2":{"35":1}}],["迁移数据库表结构",{"2":{"35":1}}],["删除旧的列",{"2":{"35":1}}],["跨域",{"0":{"34":1}}],["签名验证",{"0":{"33":1}}],["限流器",{"0":{"31":1}}],["消息驱动的系统等",{"2":{"27":1}}],["异步任务队列",{"2":{"27":1}}],["文件处理等",{"2":{"27":1}}],["文档完善和测试完备",{"2":{"21":1}}],["中的消息",{"2":{"27":1}}],["var",{"2":{"56":1,"58":3}}],["viperviper",{"2":{"58":13}}],["viper",{"2":{"26":2,"45":2,"58":2}}],["v1",{"2":{"1":1}}],["\\trepository",{"2":{"58":6}}],["\\treturn",{"2":{"45":1,"58":1}}],["\\thandler",{"2":{"58":3}}],["\\thttpserver",{"2":{"45":1}}],["\\tdb",{"2":{"56":1}}],["\\t\\tnewapp",{"2":{"45":1,"58":1}}],["\\t\\tjwt",{"2":{"45":1,"58":1}}],["\\t\\tsid",{"2":{"45":1,"58":1}}],["\\t\\tserverset",{"2":{"45":1,"58":1}}],["\\t\\tserviceset",{"2":{"45":1,"58":1}}],["\\t\\thandlerset",{"2":{"45":1,"58":1}}],["\\t\\trepositoryset",{"2":{"45":1,"58":1}}],["\\t\\tapp",{"2":{"45":2,"58":2}}],["\\tpanic",{"2":{"45":1,"58":1}}],["\\tjob",{"2":{"45":1}}],["\\tjwt",{"2":{"26":1}}],["\\tservice",{"2":{"58":2}}],["\\tserver",{"2":{"45":2,"58":3}}],["\\tstop",{"2":{"44":1}}],["\\tstart",{"2":{"44":1}}],["\\tlisten",{"2":{"39":1}}],["\\tlogger",{"2":{"26":1}}],["\\t",{"2":{"26":2,"45":4,"56":5,"58":2}}],["\\tuserhandler",{"2":{"26":1}}],["\\tconf",{"2":{"26":1}}],["只需要在newhttpserver方法中传入的用到的handler结构即可",{"2":{"26":1}}],["只是想尝试一下",{"2":{"20":1}}],["具体中间件的实现可以参考internal",{"2":{"25":1}}],["三个路由组是基于不同的中间件实现的",{"2":{"25":1}}],["需要从参数传入",{"2":{"45":1}}],["需要更新数据库模式或迁移现有数据以适应新的模式",{"2":{"35":1}}],["需要严格认证即可访问",{"2":{"25":1}}],["需要注意的是在高级layout示例中",{"2":{"25":1}}],["例如",{"2":{"56":1}}],["例如将旧数据格式转换为新的格式",{"2":{"35":1}}],["例如添加新的列",{"2":{"35":1}}],["例如在软件升级过程中",{"2":{"35":1}}],["例如修改用户信息等",{"2":{"25":1}}],["例如获取用户信息等",{"2":{"25":1}}],["例如登录",{"2":{"25":1}}],["注册等",{"2":{"25":1}}],["注意",{"2":{"3":1}}],["无需严格认证即可访问",{"2":{"25":1}}],["无需认证即可访问",{"2":{"25":1}}],["无损的依赖注入",{"2":{"22":1}}],["他们的具体用法如下",{"2":{"25":1}}],["在依赖注入中",{"2":{"57":1}}],["在并发环境中",{"2":{"56":1}}],["在上面的代码中",{"2":{"56":1,"57":1}}],["在没有依赖注入的情况下",{"2":{"55":1,"56":1}}],["在nunu中",{"2":{"44":1,"45":1}}],["在newhttpserver方法中",{"2":{"25":1}}],["在项目根目录",{"2":{"38":1}}],["在创建项目之前",{"2":{"18":1}}],["大家可以直接参考internal",{"2":{"25":1}}],["路由定义",{"0":{"25":1}}],["示例应用场景",{"2":{"24":1,"27":1,"35":1,"51":1}}],["然后直接使用npm安装pm2即可",{"2":{"38":1}}],["然后定义了路由规则",{"2":{"25":1}}],["然后返回相应的http响应",{"2":{"24":1}}],["然后自己选择对应的文件编译",{"2":{"9":1}}],["并将数据库连接传递进去",{"2":{"57":1}}],["并发安全问题",{"2":{"56":1}}],["并根据接收到的请求执行相应的操作",{"2":{"24":1}}],["并在其中生成一个优雅的",{"2":{"18":1}}],["监听指定的http端口",{"2":{"24":1}}],["监听端口",{"2":{"2":1}}],["工作原理",{"2":{"24":1,"27":1,"35":1,"51":1}}],["用于管理代码中各个组件之间的依赖关系",{"2":{"55":1}}],["用于一些需要严格认证的接口",{"2":{"25":1}}],["用于一些无需严格认证的接口",{"2":{"25":1}}],["用于一些无需认证的接口",{"2":{"25":1}}],["用于部署和其他自动化任务",{"2":{"1":1}}],["用途",{"2":{"24":1,"27":1,"35":1,"51":1}}],["保证原生组件的性能与稳定性",{"2":{"22":1}}],["轻度的组件封装",{"2":{"22":1}}],["而是通过wire自动生成的",{"2":{"58":1}}],["而是通过构造函数",{"2":{"57":1}}],["而是简洁直观的导入第三方包",{"2":{"22":1}}],["而是在编译期通过静态代码生成的方式达成这个目的",{"2":{"22":1}}],["而你只想编译指定的wire",{"2":{"9":1}}],["又称为golang",{"2":{"22":1}}],["高性能gin",{"2":{"22":1}}],["高级模板",{"2":{"18":1}}],["性能",{"0":{"22":1}}],["帮助您快速入门",{"2":{"21":1}}],["模块化和可扩展",{"2":{"21":1}}],["超低学习成本和定制",{"2":{"21":1}}],["旨在golang项目开发时提供出色的开发体验",{"2":{"21":1}}],["跳到快速开始",{"2":{"20":1}}],["可维护性",{"2":{"57":1}}],["可维护性差",{"2":{"56":1}}],["可以管理后端服务进程",{"2":{"38":1}}],["可以是一些需要异步处理的任务",{"2":{"27":1}}],["可以把",{"2":{"17":1}}],["可靠的应用程序",{"2":{"20":1}}],["它使用了依赖注入来管理各个组件之间的依赖关系",{"2":{"58":1}}],["它需要一个数据库连接",{"2":{"56":1}}],["它还包括一套测试套件",{"2":{"21":1}}],["它提供了全面的文档和示例",{"2":{"21":1}}],["它们的组合可以帮助你快速构建一个高效",{"2":{"20":1}}],["它是由golang生态中各种非常流行的库整合而成的",{"2":{"20":1}}],["它的名字来自于英雄联盟中的游戏角色",{"2":{"20":1}}],["该项目也是站在巨人的肩膀上",{"2":{"20":1}}],["和数据库连接之间的关系解耦",{"2":{"57":1}}],["和stop",{"2":{"44":1}}],["和努努一样",{"2":{"20":1}}],["和部署",{"2":{"5":1}}],["一个函数可能会依赖于某个全局变量的值",{"2":{"56":1}}],["一个骑在雪怪肩膀上的小男孩",{"2":{"20":1}}],["一些通用的辅助函数",{"2":{"4":1}}],["80",{"2":{"39":1}}],["8000",{"2":{"19":1,"39":1}}],["8080即可看到欢迎页面",{"2":{"19":1}}],["10m",{"2":{"39":2}}],["1",{"2":{"19":1,"38":1,"39":2}}],["127",{"2":{"19":1,"39":1}}],["0",{"2":{"19":2,"39":2}}],["随后打开浏览器访问http",{"2":{"19":1}}],["我们需要做的仅仅是需要声明我们的依赖关系",{"2":{"58":1}}],["我们需要了解到nunu内置了两种类型的layout",{"2":{"18":1}}],["我们通过将",{"2":{"57":1}}],["我们使用了全局变量",{"2":{"56":1}}],["我们可能会这样实现",{"2":{"56":1}}],["我们将http",{"2":{"44":1}}],["我们为大家定义了三个路由组",{"2":{"25":1}}],["我们首先创建了一个gin",{"2":{"25":1}}],["我们进入项目执行nunu",{"2":{"19":1}}],["推荐",{"2":{"18":1}}],["推荐选择advanced",{"2":{"18":1}}],["你想注册的其它服务",{"2":{"45":2}}],["你只需要关心cmd",{"2":{"45":1}}],["你也可以使用国内加速仓库",{"2":{"18":1}}],["你可以使用",{"2":{"8":1,"9":1}}],["你可以自由添加扩展更多的pkg",{"2":{"4":1}}],["国内加速源",{"2":{"18":1}}],["国内用户可以使用goproxy加速go",{"2":{"17":1}}],["此命令将创建一个名为",{"2":{"18":1}}],["适合开发者快速学习了解nunu的架构思想",{"2":{"18":1}}],["适合非常熟悉nunu项目的开发者使用",{"2":{"18":1}}],["json",{"2":{"38":3}}],["jwtjwt",{"2":{"58":2}}],["jwt",{"2":{"18":1,"26":2,"58":1}}],["job等服务都抽象为server",{"2":{"44":1}}],["job",{"0":{"27":1},"2":{"3":1,"45":2,"58":5}}],["基础模板",{"2":{"18":1}}],["目录配置到环境变量中即可",{"2":{"17":1}}],["目录结构",{"0":{"1":1}}],["却提示找不到nunu命令",{"2":{"17":1}}],["$proxy",{"2":{"39":1}}],["$remote",{"2":{"39":2}}],["$server",{"2":{"39":1}}],["$host",{"2":{"39":1}}],["$",{"2":{"17":1}}],["listen",{"2":{"39":1}}],["linux各不相同",{"2":{"17":1}}],["location",{"2":{"39":1}}],["localhost",{"2":{"19":1,"56":1,"57":1}}],["logger",{"2":{"26":1,"45":1,"58":7}}],["log",{"2":{"4":1,"26":1,"45":1,"58":1}}],["logic",{"2":{"2":1}}],["layout",{"2":{"18":7}}],["latest",{"2":{"17":1}}],["您可以通过使用第三方库或编写自己的模块轻松添加新功能和功能",{"2":{"21":1}}],["您可以通过以下命令安装",{"2":{"17":1}}],["您可以轻松定制应用程序以满足特定需求",{"2":{"21":1}}],["您可以使用以下命令创建一个新的",{"2":{"18":1}}],["您可以很容易的进行",{"2":{"5":1}}],["快速开始",{"0":{"16":1},"1":{"17":1,"18":1,"19":1}}],["待更新",{"2":{"15":1,"53":1}}],["容器运行",{"0":{"13":1}}],["镜像构建",{"0":{"12":1}}],["uploadhandler",{"2":{"58":2}}],["upgrade",{"2":{"10":1}}],["userservice",{"2":{"58":4}}],["userrepository",{"2":{"58":4}}],["user",{"2":{"56":1,"57":1}}],["userhandler",{"2":{"26":1,"58":2}}],["uuid",{"2":{"4":1}}],["版本升级",{"0":{"10":1}}],["编译wire",{"0":{"9":1}}],["authhandler",{"2":{"58":2}}],["add",{"2":{"39":1}}],["addr",{"2":{"39":2}}],["advanced",{"2":{"18":3}}],["args",{"2":{"38":1}}],["appapp",{"2":{"58":1}}],["app",{"2":{"45":6,"58":6}}],["apps",{"2":{"38":1}}],["api服务等",{"2":{"24":1}}],["api文档地址",{"2":{"19":1}}],["api",{"2":{"1":1,"38":1}}],["all",{"2":{"8":2,"9":1}}],["详细命令",{"2":{"8":1}}],["创建服务实例",{"2":{"57":1}}],["创建pm2配置文件pm2",{"2":{"38":1}}],["创建好项目之后",{"2":{"19":1}}],["创建新项目",{"0":{"18":1}}],["创建所有组件",{"2":{"8":1}}],["创建handler创建service创建repository创建model",{"2":{"8":1}}],["创建组件",{"0":{"8":1}}],["创建项目",{"0":{"6":1}}],["build",{"2":{"45":2,"58":2}}],["build之后部署",{"2":{"7":1}}],["buffering",{"2":{"39":1}}],["bin",{"2":{"38":1}}],["basic",{"2":{"18":3}}],["bash$",{"2":{"17":1}}],["bashgo",{"2":{"17":1}}],["bashnunu",{"2":{"8":4,"18":1}}],["blob",{"2":{"3":1}}],["请参考job的实现",{"2":{"51":1}}],["请参考task或是migration的实现",{"2":{"27":1}}],["请自行网络搜索",{"2":{"17":1}}],["请使用",{"2":{"7":1}}],["请求",{"2":{"2":2}}],["命令仅用于本地开发环境快速热编译运行使用",{"2":{"7":1}}],["命令行工具",{"2":{"5":1}}],["命令行工具是一个为了协助快速开发",{"2":{"5":1}}],["通常会使用全局变量或硬编码的方式来获取所需的依赖",{"2":{"55":1}}],["通常用于周期性地执行一些重复性的任务",{"2":{"51":1}}],["通常用于处理消息队列",{"2":{"27":1}}],["通常情况下",{"2":{"7":1}}],["通过明确地传递依赖关系",{"2":{"57":1}}],["通过",{"2":{"5":1}}],["port",{"2":{"39":1}}],["post",{"2":{"25":1}}],["password",{"2":{"56":1,"57":1}}],["pass",{"2":{"39":1}}],["page",{"2":{"39":1}}],["prefer",{"2":{"39":1}}],["privkey",{"2":{"39":1}}],["prompthandler",{"2":{"58":2}}],["promptservice",{"2":{"58":2}}],["promptrepository",{"2":{"58":3}}],["proxy",{"2":{"39":7}}],["protocols",{"2":{"39":1}}],["prod",{"2":{"38":1}}],["projectname",{"2":{"6":1,"18":4}}],["pem",{"2":{"39":2}}],["php",{"2":{"39":2}}],["pm2",{"0":{"38":1},"2":{"38":4}}],["pm2+nginx",{"0":{"37":1},"1":{"38":1,"39":1}}],["put",{"2":{"25":1}}],["pkg",{"2":{"1":2,"4":4}}],["nil",{"2":{"58":6}}],["nginxserver",{"2":{"39":1}}],["nginx配置",{"0":{"39":1}}],["npm",{"2":{"38":1}}],["nostrictauthrouter",{"2":{"25":1}}],["nostrictauthrouter和strictauthrouter",{"2":{"25":1}}],["noauthrouter",{"2":{"25":2}}],["name",{"2":{"8":6,"38":1,"39":1}}],["newtask",{"2":{"58":1}}],["newtranslatehandler",{"2":{"58":1}}],["newtranslateservice",{"2":{"58":1}}],["newauthhandler",{"2":{"58":1}}],["newapp",{"2":{"45":2,"58":3}}],["neworderrepository",{"2":{"58":1}}],["newprompthandler",{"2":{"58":1}}],["newpromptservice",{"2":{"58":1}}],["newpromptrepository",{"2":{"58":1}}],["newuploadhandler",{"2":{"58":1}}],["newuserhandler",{"2":{"58":2}}],["newuserservice",{"2":{"58":2}}],["newuserrepository",{"2":{"58":2}}],["newfileservice",{"2":{"58":1}}],["newfilerepository",{"2":{"58":1}}],["newcaptchaservice",{"2":{"58":1}}],["newcaptcharepository",{"2":{"58":1}}],["newcategoryhandler",{"2":{"58":2}}],["newcategoryservice",{"2":{"58":1}}],["newcategoryrepository",{"2":{"58":1}}],["newcosrepository",{"2":{"58":1}}],["newcosclient",{"2":{"58":1}}],["newrepository",{"2":{"58":2}}],["newredis",{"2":{"58":2}}],["newwallethandler",{"2":{"58":1}}],["newwalletservice",{"2":{"58":1}}],["newwalletrepository",{"2":{"58":1}}],["newwechathandler",{"2":{"58":1}}],["newwechatservice",{"2":{"58":1}}],["newwechatrepository",{"2":{"58":1}}],["newwechatpay",{"2":{"58":2}}],["newwechatofficial",{"2":{"58":2}}],["newwire",{"2":{"45":1,"58":1}}],["newdb",{"2":{"58":2}}],["newhandler",{"2":{"58":2}}],["newhttpserver",{"2":{"26":1,"45":1,"58":2}}],["newjwt",{"2":{"45":1,"58":2}}],["newjob",{"2":{"45":1,"58":2}}],["newservice",{"2":{"57":3,"58":2}}],["newset",{"2":{"45":1,"58":4}}],["newsid",{"2":{"45":1,"58":2}}],["new默认拉取github源",{"2":{"18":1}}],["new",{"2":{"6":1,"18":3}}],["nunu支持job和http",{"2":{"27":1}}],["nunu没有过度的封装一些常用组件",{"2":{"22":1}}],["nunu文档完善",{"2":{"21":1}}],["nunu旨在具有模块化和可扩展性",{"2":{"21":1}}],["nunu封装了gopher最熟悉的一些流行库",{"2":{"21":1}}],["nunu是一个基于golang的应用脚手架",{"2":{"20":1}}],["nunu",{"0":{"20":1},"1":{"21":1,"22":1},"2":{"5":2,"6":1,"7":2,"8":3,"9":2,"10":1,"17":3,"18":7,"19":1,"21":1,"38":1}}],["nunu命令行工具",{"0":{"5":1},"1":{"6":1,"7":1,"8":1,"9":1,"10":1}}],["nunu采用了经典的分层架构",{"2":{"0":1}}],["nunu架构详解",{"0":{"0":1},"1":{"1":1,"2":1,"3":1,"4":1}}],["测试完备",{"2":{"21":1}}],["测试",{"2":{"5":1}}],["测试代码",{"2":{"1":1}}],["开发体验",{"0":{"21":1}}],["开发",{"2":{"5":1}}],["热编译",{"2":{"5":1}}],["项目结构",{"2":{"18":1}}],["项目",{"2":{"18":1}}],["项目的创建",{"2":{"5":1}}],["项目而创建的项目",{"2":{"5":1}}],["客户端",{"2":{"4":1}}],["生成等",{"2":{"4":1}}],["加密",{"2":{"4":1}}],["将一些通用的代码放在了pkg目录下",{"2":{"4":1}}],["本项目采用了公共代码的方式",{"2":{"4":1}}],["本项目采用了依赖注入框架wire",{"2":{"3":1}}],["公共代码",{"0":{"4":1}}],["公共的代码",{"2":{"1":1}}],["禁止手动修改",{"2":{"3":1}}],["简化了依赖注入的过程",{"2":{"3":1}}],["实现了依赖注入",{"2":{"57":1}}],["实现了模块化和解耦",{"2":{"3":1}}],["实现具体的业务逻辑",{"2":{"2":1}}],["提供了对数据的增删改查",{"2":{"2":1}}],["封装了数据库操作",{"2":{"2":1}}],["数据库",{"0":{"14":1}}],["数据访问对象",{"2":{"2":1}}],["数据模型",{"2":{"2":1}}],["调用数据访问层repository",{"2":{"2":1}}],["调用业务逻辑层的服务",{"2":{"2":1}}],["服务依赖注册",{"0":{"45":1}}],["服务",{"2":{"2":2}}],["服务器名称",{"2":{"45":1}}],["服务器等",{"2":{"4":1}}],["服务器",{"2":{"2":1}}],["启动服务",{"0":{"19":1},"2":{"38":1}}],["启动项目",{"0":{"7":1}}],["启动",{"2":{"2":1}}],["rsa+3des",{"2":{"39":1}}],["rsa+aes256",{"2":{"39":1}}],["rsa+aes128",{"2":{"39":1}}],["root",{"2":{"39":1}}],["router",{"2":{"2":1}}],["r",{"2":{"18":2}}],["return",{"2":{"57":1,"58":2}}],["redirect",{"2":{"39":1}}],["redis",{"0":{"42":1},"2":{"18":1}}],["real",{"2":{"39":1}}],["repositoryset",{"2":{"58":1}}],["repositoryrepository",{"2":{"58":11}}],["repository",{"0":{"43":1},"2":{"1":1,"2":1,"8":2,"58":15}}],["run命令即可启动服务",{"2":{"19":1}}],["run",{"2":{"7":2,"19":1}}],["响应",{"2":{"2":1}}],["返回",{"2":{"2":1}}],["处理定时任务",{"2":{"51":1}}],["处理数据库迁移和数据迁移任务",{"2":{"35":1}}],["处理异步任务",{"2":{"27":1}}],["处理基于http协议的请求和响应",{"2":{"24":1}}],["处理",{"2":{"2":2}}],["存储文件",{"2":{"1":1}}],["脚本文件",{"2":{"1":1}}],["等",{"2":{"1":1}}],["host",{"2":{"39":1}}],["header",{"2":{"39":4}}],["helper",{"2":{"4":1}}],["htm",{"2":{"39":2}}],["html",{"2":{"19":1,"39":3}}],["http2",{"2":{"39":1}}],["http中间件",{"0":{"30":1},"1":{"31":1,"32":1,"33":1,"34":1}}],["http模块的依赖注入非常简单",{"2":{"26":1}}],["http的路由定义非常简单",{"2":{"25":1}}],["httpserver",{"2":{"45":1,"58":4}}],["https",{"2":{"3":1,"18":2}}],["http",{"0":{"24":1},"1":{"25":1,"26":1},"2":{"1":1,"2":5,"4":4,"19":1,"25":1,"26":1,"39":2,"45":1,"58":1}}],["handlerset",{"2":{"58":1}}],["handlerhandler",{"2":{"58":9}}],["handler",{"0":{"23":1},"2":{"1":1,"2":1,"8":3,"26":1,"58":9}}],["日志trace",{"0":{"32":1}}],["日志功能",{"0":{"29":1}}],["日志的写入等",{"2":{"4":1}}],["日志相关的代码",{"2":{"4":1}}],["日志",{"2":{"1":1}}],["包括get",{"2":{"25":1}}],["包括配置",{"2":{"1":1}}],["包含了很多nunu的用法示例",{"2":{"18":1}}],["包含了不同的子命令",{"2":{"1":1}}],["包含一个非常精简的架构目录结构",{"2":{"18":1}}],["按照分层架构进行组织",{"2":{"1":1}}],["应用程序的主要代码",{"2":{"1":1}}],["应用程序的入口",{"2":{"1":1}}],["如下是一个真实项目的部分代码",{"2":{"58":1}}],["如邮件发送",{"2":{"27":1}}],["如果go",{"2":{"17":1}}],["如果你想给你的某个服务进程注册相应的启动服务",{"2":{"45":1}}],["如果你的项目存在多个wire",{"2":{"9":1}}],["如果你觉得每种组件单独创建太麻烦",{"2":{"8":1}}],["如果是生产环境",{"2":{"7":1}}],["如日志的初始化",{"2":{"4":1}}],["如日志文件",{"2":{"1":1}}],["如",{"2":{"1":1,"4":2}}],["部署相关的文件",{"2":{"1":1}}],["配置文件的读取和解析",{"2":{"4":1}}],["配置文件",{"2":{"1":1}}],["wallethandler",{"2":{"58":2}}],["walletservice",{"2":{"58":2}}],["walletrepository",{"2":{"58":5}}],["wechathandler",{"2":{"58":2}}],["wechatservice",{"2":{"58":2}}],["wechatrepository",{"2":{"58":3}}],["websocket",{"0":{"53":1},"2":{"44":1}}],["web应用程序",{"2":{"24":1}}],["web",{"2":{"1":2}}],["withname",{"2":{"45":1,"58":1}}],["withserver",{"2":{"45":1,"58":1}}],["wire不是在运行时通过反射动态地进行依赖注入",{"2":{"22":1}}],["wire官方文档",{"2":{"3":1}}],["wire配置文件",{"2":{"3":3}}],["wire通过预编译wire",{"2":{"3":1}}],["wire",{"2":{"1":3,"3":5,"9":2,"45":4,"58":5}}],["wwwroot",{"2":{"39":1}}],["www",{"2":{"39":1}}],["w",{"2":{"17":2}}],["translatehandler",{"2":{"58":2}}],["translateservice",{"2":{"58":2}}],["tcp",{"2":{"56":1,"57":1}}],["timeout",{"2":{"39":1}}],["tip",{"2":{"7":1,"9":1,"17":1,"27":1,"35":1,"51":1}}],["tlsv1",{"2":{"39":3}}],["type",{"2":{"8":1,"57":1}}],["test",{"2":{"1":2}}],["task",{"0":{"51":1},"2":{"1":1,"44":1}}],["sid",{"2":{"58":1}}],["sidsid",{"2":{"58":3}}],["s",{"2":{"57":2}}],["sql",{"2":{"56":4,"57":5}}],["swarm",{"0":{"49":1}}],["swarm集群部署",{"0":{"48":1},"1":{"49":1,"50":1}}],["swagger",{"2":{"19":1}}],["shared",{"2":{"39":1}}],["sh$",{"2":{"18":2}}],["set",{"2":{"39":4}}],["session",{"2":{"39":2}}],["serviceset",{"2":{"58":1}}],["serviceservice",{"2":{"58":9}}],["service",{"0":{"46":1},"2":{"1":1,"2":1,"8":2,"57":9,"58":9}}],["serverset",{"2":{"45":1,"58":1}}],["server基础概念",{"0":{"44":1},"1":{"45":1}}],["server运行",{"2":{"27":1,"51":1}}],["server同时运行",{"2":{"27":1,"51":1}}],["server",{"2":{"1":3,"2":1,"3":1,"19":1,"25":1,"26":1,"38":1,"39":2,"44":1,"45":3,"58":5}}],["ssl证书路径",{"2":{"39":2}}],["ssl",{"2":{"39":9}}],["struct",{"2":{"57":1}}],["strictauthrouter",{"2":{"25":1}}],["start",{"2":{"38":1}}],["storage",{"2":{"1":1}}],["script",{"2":{"1":1,"38":1}}],["scripts",{"2":{"1":1}}],["sum",{"2":{"1":1}}],["dosomething",{"2":{"57":2}}],["docker",{"0":{"11":1,"48":1},"1":{"12":1,"13":1,"49":1,"50":1},"2":{"1":1}}],["dockerfile",{"2":{"1":1}}],["docs",{"2":{"1":1,"3":1}}],["driver",{"2":{"56":1,"57":1}}],["draft",{"2":{"39":1}}],["database",{"2":{"56":1,"57":1}}],["data",{"2":{"39":1}}],["dao",{"2":{"2":1}}],["demo",{"2":{"45":1,"58":1}}],["default",{"2":{"39":3}}],["delete等方法",{"2":{"25":1}}],["deploy",{"2":{"1":2}}],["dbname",{"2":{"56":1,"57":1}}],["db",{"2":{"18":1,"56":4,"57":9,"58":2}}],["direct",{"2":{"17":1}}],["captchaservice",{"2":{"58":2}}],["captcharepository",{"2":{"58":3}}],["categoryhandler",{"2":{"58":2}}],["categoryservice",{"2":{"58":2}}],["categoryrepository",{"2":{"58":3}}],["cache",{"2":{"39":1}}],["clientv3",{"2":{"58":3}}],["client",{"2":{"58":2}}],["ctx",{"2":{"44":2}}],["ciphers",{"2":{"39":2}}],["certificate",{"2":{"39":2}}],["cron",{"2":{"18":1}}],["create",{"2":{"8":7}}],["cn",{"2":{"17":1}}],["cosrepository",{"2":{"58":4}}],["cosclient",{"2":{"58":2}}],["com",{"2":{"3":1,"17":1,"18":2,"39":2,"56":1,"57":1}}],["compose",{"2":{"1":1}}],["context",{"2":{"44":4}}],["controller",{"2":{"2":1}}],["conf=config",{"2":{"38":1}}],["config",{"2":{"1":2,"4":1}}],["cmd",{"2":{"1":2,"3":3,"19":1}}],["mysql",{"2":{"56":2,"57":2}}],["mq",{"2":{"27":1}}],["md5",{"2":{"4":1,"39":1}}],["md",{"2":{"3":1}}],["macos",{"2":{"17":1}}],["makefile",{"2":{"1":1}}],["main",{"2":{"1":1,"3":1,"19":1,"56":2,"57":2}}],["more",{"2":{"4":1}}],["mode",{"2":{"38":1}}],["model",{"0":{"36":1},"2":{"1":1,"2":1,"8":2}}],["mod",{"2":{"1":1}}],["mocks",{"2":{"1":1}}],["middleware目录下的代码",{"2":{"25":1}}],["middleware",{"2":{"1":1}}],["migration须谨慎用于生成环境",{"2":{"35":1}}],["migration服务负责管理数据库结构的变化和数据的迁移",{"2":{"35":1}}],["migration等",{"2":{"18":1}}],["migration",{"0":{"35":1},"2":{"1":1,"3":1}}],["g",{"2":{"38":1}}],["gin是一个go",{"2":{"22":1}}],["git",{"2":{"18":2}}],["gitee",{"2":{"18":2}}],["github",{"2":{"3":1,"17":1,"56":1,"57":1}}],["grpc",{"0":{"15":1},"2":{"44":1}}],["guide",{"2":{"3":1}}],["gen",{"2":{"1":1,"3":2}}],["gojwtjwt",{"2":{"58":1}}],["gopackage",{"2":{"56":1,"57":1}}],["goproxy",{"2":{"17":1}}],["goproxy=https",{"2":{"17":1}}],["govar",{"2":{"45":1,"58":1}}],["gotype",{"2":{"44":1}}],["gofunc",{"2":{"26":1}}],["go中的newhttpserver方法",{"2":{"25":1}}],["gobin的配置方法windows",{"2":{"17":1}}],["gobin",{"2":{"17":1}}],["go111module=on",{"2":{"17":1}}],["go文件即可",{"2":{"45":1}}],["go文件",{"2":{"9":2}}],["go文件为自动编译生成",{"2":{"3":1}}],["golang",{"2":{"5":2,"18":2}}],["google",{"2":{"3":1}}],["go",{"2":{"1":5,"3":5,"7":1,"17":3,"18":2,"19":1,"56":2,"57":1}}],["└──",{"2":{"1":7}}],["│",{"2":{"1":22}}],["├──",{"2":{"1":22}}],["采用了依赖注入框架wire",{"2":{"0":1}}],["同时",{"2":{"0":1}}]],"serializationVersion":2}';export{e as default}; diff --git a/docs/assets/chunks/VPLocalSearchBox.De8VqG1H.js b/docs/assets/chunks/VPLocalSearchBox.Bp9Nb2eD.js similarity index 99% rename from docs/assets/chunks/VPLocalSearchBox.De8VqG1H.js rename to docs/assets/chunks/VPLocalSearchBox.Bp9Nb2eD.js index 58dd447..5e06459 100644 --- a/docs/assets/chunks/VPLocalSearchBox.De8VqG1H.js +++ b/docs/assets/chunks/VPLocalSearchBox.Bp9Nb2eD.js @@ -1,4 +1,4 @@ -var It=Object.defineProperty;var Dt=(o,e,t)=>e in o?It(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t;var _e=(o,e,t)=>(Dt(o,typeof e!="symbol"?e+"":e,t),t);import{Y as $e,h as oe,y as We,aj as kt,ak as _t,d as Ot,H as xe,al as rt,k as Fe,am as Rt,an as Mt,z as Lt,ao as Pt,l as Oe,U as de,S as Ee,ap as zt,aq as Vt,Z as Bt,j as $t,ar as Wt,o as ee,b as Kt,m as k,a2 as Jt,p as j,as as Ut,at as jt,au as Gt,c as re,n as at,e as Se,G as nt,F as it,a as ve,t as pe,av as qt,q as Ht,s as Qt,aw as ot,ax as Yt,a8 as Zt,ae as Xt,ay as er,_ as tr}from"./framework.DZjeu1b3.js";import{u as rr,c as ar}from"./theme.VdBoP6hP.js";const nr={root:()=>$e(()=>import("./@localSearchIndexroot.BKsY5Ty1.js"),[]),en:()=>$e(()=>import("./@localSearchIndexen.DVdHZgxL.js"),[])};/*! +var It=Object.defineProperty;var Dt=(o,e,t)=>e in o?It(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t;var _e=(o,e,t)=>(Dt(o,typeof e!="symbol"?e+"":e,t),t);import{Y as $e,h as oe,y as We,aj as kt,ak as _t,d as Ot,H as xe,al as rt,k as Fe,am as Rt,an as Mt,z as Lt,ao as Pt,l as Oe,U as de,S as Ee,ap as zt,aq as Vt,Z as Bt,j as $t,ar as Wt,o as ee,b as Kt,m as k,a2 as Jt,p as j,as as Ut,at as jt,au as Gt,c as re,n as at,e as Se,G as nt,F as it,a as ve,t as pe,av as qt,q as Ht,s as Qt,aw as ot,ax as Yt,a8 as Zt,ae as Xt,ay as er,_ as tr}from"./framework.DZjeu1b3.js";import{u as rr,c as ar}from"./theme.B8LElrRV.js";const nr={root:()=>$e(()=>import("./@localSearchIndexroot.R25TFYOj.js"),[]),en:()=>$e(()=>import("./@localSearchIndexen.ZbBo-S2V.js"),[])};/*! * tabbable 6.2.0 * @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE */var mt=["input:not([inert])","select:not([inert])","textarea:not([inert])","a[href]:not([inert])","button:not([inert])","[tabindex]:not(slot):not([inert])","audio[controls]:not([inert])","video[controls]:not([inert])",'[contenteditable]:not([contenteditable="false"]):not([inert])',"details>summary:first-of-type:not([inert])","details:not([inert])"],Ne=mt.join(","),gt=typeof Element>"u",ue=gt?function(){}:Element.prototype.matches||Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector,Ce=!gt&&Element.prototype.getRootNode?function(o){var e;return o==null||(e=o.getRootNode)===null||e===void 0?void 0:e.call(o)}:function(o){return o==null?void 0:o.ownerDocument},Ie=function o(e,t){var r;t===void 0&&(t=!0);var n=e==null||(r=e.getAttribute)===null||r===void 0?void 0:r.call(e,"inert"),a=n===""||n==="true",i=a||t&&e&&o(e.parentNode);return i},ir=function(e){var t,r=e==null||(t=e.getAttribute)===null||t===void 0?void 0:t.call(e,"contenteditable");return r===""||r==="true"},bt=function(e,t,r){if(Ie(e))return[];var n=Array.prototype.slice.apply(e.querySelectorAll(Ne));return t&&ue.call(e,Ne)&&n.unshift(e),n=n.filter(r),n},wt=function o(e,t,r){for(var n=[],a=Array.from(e);a.length;){var i=a.shift();if(!Ie(i,!1))if(i.tagName==="SLOT"){var s=i.assignedElements(),u=s.length?s:i.children,l=o(u,!0,r);r.flatten?n.push.apply(n,l):n.push({scopeParent:i,candidates:l})}else{var h=ue.call(i,Ne);h&&r.filter(i)&&(t||!e.includes(i))&&n.push(i);var d=i.shadowRoot||typeof r.getShadowRoot=="function"&&r.getShadowRoot(i),v=!Ie(d,!1)&&(!r.shadowRootFilter||r.shadowRootFilter(i));if(d&&v){var y=o(d===!0?i.children:d.children,!0,r);r.flatten?n.push.apply(n,y):n.push({scopeParent:i,candidates:y})}else a.unshift.apply(a,i.children)}}return n},xt=function(e){return!isNaN(parseInt(e.getAttribute("tabindex"),10))},se=function(e){if(!e)throw new Error("No node provided");return e.tabIndex<0&&(/^(AUDIO|VIDEO|DETAILS)$/.test(e.tagName)||ir(e))&&!xt(e)?0:e.tabIndex},or=function(e,t){var r=se(e);return r<0&&t&&!xt(e)?0:r},sr=function(e,t){return e.tabIndex===t.tabIndex?e.documentOrder-t.documentOrder:e.tabIndex-t.tabIndex},Ft=function(e){return e.tagName==="INPUT"},ur=function(e){return Ft(e)&&e.type==="hidden"},lr=function(e){var t=e.tagName==="DETAILS"&&Array.prototype.slice.apply(e.children).some(function(r){return r.tagName==="SUMMARY"});return t},cr=function(e,t){for(var r=0;rsummary:first-of-type"),i=a?e.parentElement:e;if(ue.call(i,"details:not([open]) *"))return!0;if(!r||r==="full"||r==="legacy-full"){if(typeof n=="function"){for(var s=e;e;){var u=e.parentElement,l=Ce(e);if(u&&!u.shadowRoot&&n(u)===!0)return st(e);e.assignedSlot?e=e.assignedSlot:!u&&l!==e.ownerDocument?e=l.host:e=u}e=s}if(vr(e))return!e.getClientRects().length;if(r!=="legacy-full")return!0}else if(r==="non-zero-area")return st(e);return!1},yr=function(e){if(/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(e.tagName))for(var t=e.parentElement;t;){if(t.tagName==="FIELDSET"&&t.disabled){for(var r=0;r=0)},gr=function o(e){var t=[],r=[];return e.forEach(function(n,a){var i=!!n.scopeParent,s=i?n.scopeParent:n,u=or(s,i),l=i?o(n.candidates):s;u===0?i?t.push.apply(t,l):t.push(s):r.push({documentOrder:a,tabIndex:u,item:n,isScope:i,content:l})}),r.sort(sr).reduce(function(n,a){return a.isScope?n.push.apply(n,a.content):n.push(a.content),n},[]).concat(t)},br=function(e,t){t=t||{};var r;return t.getShadowRoot?r=wt([e],t.includeContainer,{filter:Ke.bind(null,t),flatten:!1,getShadowRoot:t.getShadowRoot,shadowRootFilter:mr}):r=bt(e,t.includeContainer,Ke.bind(null,t)),gr(r)},wr=function(e,t){t=t||{};var r;return t.getShadowRoot?r=wt([e],t.includeContainer,{filter:De.bind(null,t),flatten:!0,getShadowRoot:t.getShadowRoot}):r=bt(e,t.includeContainer,De.bind(null,t)),r},le=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return ue.call(e,Ne)===!1?!1:Ke(t,e)},xr=mt.concat("iframe").join(","),Re=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return ue.call(e,xr)===!1?!1:De(t,e)};/*! diff --git a/docs/assets/chunks/metadata.622e4ed2.js b/docs/assets/chunks/metadata.622e4ed2.js deleted file mode 100644 index ead2087..0000000 --- a/docs/assets/chunks/metadata.622e4ed2.js +++ /dev/null @@ -1 +0,0 @@ -window.__VP_HASH_MAP__=JSON.parse("{\"en_k8s.md\":\"Bf7IRt2E\",\"en_pr.md\":\"BUl97Mle\",\"en_nginx.md\":\"Cdwn9QPG\",\"en_service.md\":\"B6Xeobs8\",\"en_redis.md\":\"BPYVtQJ-\",\"en_swagger.md\":\"DfK3tpcG\",\"en_swarm.md\":\"B8V6dVOc\",\"en_server.md\":\"x1HgIoWO\",\"k8s.md\":\"CKw5c3qk\",\"logger.md\":\"BjAvD1b-\",\"model.md\":\"CtEMf_iw\",\"guide.md\":\"FsIHc0Yq\",\"pkg.md\":\"XaeMkPOK\",\"getting-started.md\":\"Rp5FCLxj\",\"handler.md\":\"DlTcmCMk\",\"middleware.md\":\"BucLSlWV\",\"repository.md\":\"BVt8EdIP\",\"swagger.md\":\"DwcePXpx\",\"server.md\":\"yFMvW0F3\",\"nginx.md\":\"CNytBq53\",\"swarm.md\":\"BoMXP0pg\",\"en_foo.md\":\"CkNjfvFo\",\"service.md\":\"B33dDhec\",\"en_getting-started.md\":\"birFKQxq\",\"unit-test.md\":\"EIdK7f17\",\"en_architecture.md\":\"DxTxjdVP\",\"architecture.md\":\"Do2lxe98\",\"database.md\":\"B3cyEJAk\",\"docker.md\":\"23k_eWTm\",\"cli.md\":\"S0KmBxg6\",\"en_cli.md\":\"pVdAeU-p\",\"en_logger.md\":\"BWTEHexG\",\"en_unit-test.md\":\"DJ01aLkm\",\"en_middleware.md\":\"D5W_0TF7\",\"en_index.md\":\"5qRl7FvM\",\"en_docker.md\":\"B7GrNYhN\",\"en_model.md\":\"B5_e_RC5\",\"en_guide.md\":\"CUzigoVU\",\"en_repository.md\":\"BrJQ6M7L\",\"foo.md\":\"C1aJzGpm\",\"redis.md\":\"DfPTQc6m\",\"pr.md\":\"CuXISoCC\",\"index.md\":\"DelroEap\",\"en_pkg.md\":\"Cud4pRCk\",\"en_wire.md\":\"Tbcn3on1\",\"en_database.md\":\"Dzwg1sQz\",\"en_handler.md\":\"BlryHOpn\",\"wire.md\":\"DAPteEAd\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Nunu文档\",\"description\":\"A VitePress site\",\"base\":\"/nunu/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":\"dark\",\"themeConfig\":{\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/go-nunu/nunu\"}],\"search\":{\"provider\":\"local\",\"options\":{\"locales\":{\"zh\":{\"placeholder\":\"搜索文档\",\"translations\":{\"button\":{\"buttonText\":\"搜索文档\",\"buttonAriaLabel\":\"搜索文档\"},\"modal\":{\"searchBox\":{\"resetButtonTitle\":\"清除查询条件\",\"resetButtonAriaLabel\":\"清除查询条件\",\"cancelButtonText\":\"取消\",\"cancelButtonAriaLabel\":\"取消\"},\"startScreen\":{\"recentSearchesTitle\":\"搜索历史\",\"noRecentSearchesText\":\"没有搜索历史\",\"saveRecentSearchButtonTitle\":\"保存至搜索历史\",\"removeRecentSearchButtonTitle\":\"从搜索历史中移除\",\"favoriteSearchesTitle\":\"收藏\",\"removeFavoriteSearchButtonTitle\":\"从收藏中移除\"},\"errorScreen\":{\"titleText\":\"无法获取结果\",\"helpText\":\"你可能需要检查你的网络连接\"},\"footer\":{\"selectText\":\"选择\",\"navigateText\":\"切换\",\"closeText\":\"关闭\",\"searchByText\":\"搜索提供者\"},\"noResultsScreen\":{\"noResultsText\":\"无法找到相关结果\",\"suggestedQueryText\":\"你可以尝试查询\",\"reportMissingResultsText\":\"你认为该查询应该有结果?\",\"reportMissingResultsLinkText\":\"点击反馈\"}}}},\"en\":{\"placeholder\":\"搜索文档\",\"translations\":{\"button\":{\"buttonText\":\"搜索文档\",\"buttonAriaLabel\":\"搜索文档\"},\"modal\":{\"searchBox\":{\"resetButtonTitle\":\"清除查询条件\",\"resetButtonAriaLabel\":\"清除查询条件\",\"cancelButtonText\":\"取消\",\"cancelButtonAriaLabel\":\"取消\"},\"startScreen\":{\"recentSearchesTitle\":\"搜索历史\",\"noRecentSearchesText\":\"没有搜索历史\",\"saveRecentSearchButtonTitle\":\"保存至搜索历史\",\"removeRecentSearchButtonTitle\":\"从搜索历史中移除\",\"favoriteSearchesTitle\":\"收藏\",\"removeFavoriteSearchButtonTitle\":\"从收藏中移除\"},\"errorScreen\":{\"titleText\":\"无法获取结果\",\"helpText\":\"你可能需要检查你的网络连接\"},\"footer\":{\"selectText\":\"选择\",\"navigateText\":\"切换\",\"closeText\":\"关闭\",\"searchByText\":\"搜索提供者\"},\"noResultsScreen\":{\"noResultsText\":\"无法找到相关结果\",\"suggestedQueryText\":\"你可以尝试查询\",\"reportMissingResultsText\":\"你认为该查询应该有结果?\",\"reportMissingResultsLinkText\":\"点击反馈\"}}}}}}}},\"locales\":{\"root\":{\"label\":\"简体中文\",\"lang\":\"zh-Hans\",\"description\":\"A CLI tool for building Go applications.\",\"themeConfig\":{\"nav\":[{\"text\":\"首页\",\"link\":\"/\"},{\"text\":\"文档\",\"link\":\"/getting-started\",\"activeMatch\":\"/getting-started\"},{\"text\":\"1.0.14\",\"items\":[{\"text\":\"更新日志\",\"link\":\"https://github.com/go-nunu/nunu/blob/main/CHANGELOG.md\"}]}],\"logo\":\"\",\"title\":\"Nunu\",\"siteTitle\":\"Nunu\",\"sidebar\":{\"/\":{\"base\":\"/\",\"items\":[{\"text\":\"入门指引\",\"collapsed\":false,\"items\":[{\"text\":\"引言\",\"link\":\"guide\"},{\"text\":\"快速开始\",\"link\":\"getting-started\"},{\"text\":\"Nunu命令行\",\"link\":\"cli\"}]},{\"text\":\"基础概念\",\"collapsed\":false,\"items\":[{\"text\":\"分层架构\",\"link\":\"architecture\"},{\"text\":\"Wire依赖注入\",\"link\":\"wire\"}]},{\"text\":\"核心组件\",\"collapsed\":false,\"items\":[{\"text\":\"Server\",\"link\":\"server\"},{\"text\":\"Handler\",\"link\":\"handler\"},{\"text\":\"Middleware\",\"link\":\"middleware\"},{\"text\":\"Service\",\"link\":\"service\"},{\"text\":\"repository\",\"link\":\"repository\",\"items\":[{\"text\":\"数据库\",\"link\":\"database\"},{\"text\":\"Redis\",\"link\":\"redis\"}]},{\"text\":\"Model\",\"link\":\"model\"},{\"text\":\"Pkg\",\"link\":\"pkg\"},{\"text\":\"日志\",\"link\":\"logger\"},{\"text\":\"自动化文档\",\"link\":\"swagger\"},{\"text\":\"单元测试\",\"link\":\"unit-test\"}]},{\"text\":\"构建部署\",\"collapsed\":false,\"items\":[{\"text\":\"PM2+Nginx\",\"link\":\"nginx\"},{\"text\":\"Docker\",\"link\":\"docker\"},{\"text\":\"Swarm\",\"link\":\"swarm\"},{\"text\":\"K8s\",\"link\":\"k8s\"}]},{\"text\":\"参考\",\"collapsed\":false,\"items\":[{\"text\":\"贡献指南\",\"link\":\"pr\"}]}]}},\"editLink\":{\"pattern\":\"https://github.com/go-nunu/nunu/edit/feature/docs/:path\",\"text\":\"在 GitHub 上编辑此页面\"},\"footer\":{\"message\":\"基于 MIT 许可发布\",\"copyright\":\"版权所有 © 2023-2024 go-nunu\"},\"docFooter\":{\"prev\":\"上一页\",\"next\":\"下一页\"},\"outline\":{\"label\":\"页面导航\"},\"lastUpdated\":{\"text\":\"最后更新于\",\"formatOptions\":{\"dateStyle\":\"short\",\"timeStyle\":\"medium\"}},\"langMenuLabel\":\"多语言\",\"returnToTopLabel\":\"回到顶部\",\"sidebarMenuLabel\":\"菜单\",\"darkModeSwitchLabel\":\"主题\",\"lightModeSwitchTitle\":\"切换到浅色模式\",\"darkModeSwitchTitle\":\"切换到深色模式\"}},\"en\":{\"label\":\"English\",\"lang\":\"en-US\",\"description\":\"A CLI tool for building Go applications.\",\"themeConfig\":{\"nav\":[{\"text\":\"首页\",\"link\":\"/en/\"},{\"text\":\"文档\",\"link\":\"/en/getting-started\",\"activeMatch\":\"/en/getting-started\"},{\"text\":\"1.0.14\",\"items\":[{\"text\":\"更新日志\",\"link\":\"https://github.com/go-nunu/nunu/blob/main/CHANGELOG.md\"}]}],\"sidebar\":{\"/en/\":{\"base\":\"/en/\",\"items\":[{\"text\":\"入门指引\",\"collapsed\":false,\"items\":[{\"text\":\"引言\",\"link\":\"guide\"},{\"text\":\"快速开始\",\"link\":\"getting-started\"},{\"text\":\"Nunu命令行\",\"link\":\"cli\"}]},{\"text\":\"基础概念\",\"collapsed\":false,\"items\":[{\"text\":\"分层架构\",\"link\":\"architecture\"},{\"text\":\"Wire依赖注入\",\"link\":\"wire\"}]},{\"text\":\"核心组件\",\"collapsed\":false,\"items\":[{\"text\":\"Server\",\"link\":\"server\"},{\"text\":\"Handler\",\"link\":\"handler\"},{\"text\":\"Middleware\",\"link\":\"middleware\"},{\"text\":\"Service\",\"link\":\"service\"},{\"text\":\"repository\",\"link\":\"repository\",\"items\":[{\"text\":\"数据库\",\"link\":\"database\"},{\"text\":\"Redis\",\"link\":\"redis\"}]},{\"text\":\"Model\",\"link\":\"model\"},{\"text\":\"Pkg\",\"link\":\"pkg\"},{\"text\":\"日志\",\"link\":\"logger\"},{\"text\":\"自动化文档\",\"link\":\"swagger\"},{\"text\":\"单元测试\",\"link\":\"unit-test\"}]},{\"text\":\"构建部署\",\"collapsed\":false,\"items\":[{\"text\":\"PM2+Nginx\",\"link\":\"nginx\"},{\"text\":\"Docker\",\"link\":\"docker\"},{\"text\":\"Swarm\",\"link\":\"swarm\"},{\"text\":\"K8s\",\"link\":\"k8s\"}]},{\"text\":\"参考\",\"collapsed\":false,\"items\":[{\"text\":\"贡献指南\",\"link\":\"pr\"}]},{\"text\":\"加入交流群\",\"base\":\"/zh/reference/\",\"link\":\"site-config\"}]}},\"editLink\":{\"pattern\":\"https://github.com/go-nunu/nunu/edit/feature/docs/:path\",\"text\":\"Edit this page on GitHub\"},\"footer\":{\"message\":\"Released under the MIT License.\",\"copyright\":\"Copyright © 2019-present Evan You\"}}}},\"scrollOffset\":134,\"cleanUrls\":true}"); \ No newline at end of file diff --git a/docs/assets/chunks/metadata.ae0ba16e.js b/docs/assets/chunks/metadata.ae0ba16e.js new file mode 100644 index 0000000..36a8e30 --- /dev/null +++ b/docs/assets/chunks/metadata.ae0ba16e.js @@ -0,0 +1 @@ +window.__VP_HASH_MAP__=JSON.parse("{\"en_cli.md\":\"pVdAeU-p\",\"database.md\":\"B3cyEJAk\",\"docker.md\":\"23k_eWTm\",\"en_architecture.md\":\"DxTxjdVP\",\"en_database.md\":\"Dzwg1sQz\",\"en_docker.md\":\"B7GrNYhN\",\"en_model.md\":\"B5_e_RC5\",\"k8s.md\":\"CKw5c3qk\",\"guide.md\":\"FsIHc0Yq\",\"logger.md\":\"BjAvD1b-\",\"en_k8s.md\":\"Bf7IRt2E\",\"swagger.md\":\"DwcePXpx\",\"handler.md\":\"DlTcmCMk\",\"en_index.md\":\"5qRl7FvM\",\"index.md\":\"DelroEap\",\"service.md\":\"B33dDhec\",\"en_handler.md\":\"BlryHOpn\",\"architecture.md\":\"Do2lxe98\",\"en_swagger.md\":\"DfK3tpcG\",\"en_pkg.md\":\"Cud4pRCk\",\"cli.md\":\"C_7YL7i5\",\"en_guide.md\":\"CUzigoVU\",\"en_getting-started.md\":\"birFKQxq\",\"en_unit-test.md\":\"DJ01aLkm\",\"en_logger.md\":\"BWTEHexG\",\"grpc.md\":\"CeHujcK9\",\"getting-started.md\":\"Be3tXPfD\",\"en_nginx.md\":\"Cdwn9QPG\",\"en_foo.md\":\"CkNjfvFo\",\"server.md\":\"BzwyYWXt\",\"pkg.md\":\"XaeMkPOK\",\"task.md\":\"eQQGFK-A\",\"middleware.md\":\"BucLSlWV\",\"nginx.md\":\"CNytBq53\",\"swarm.md\":\"BoMXP0pg\",\"migration.md\":\"BDgzs4ZZ\",\"redis.md\":\"DfPTQc6m\",\"websocket.md\":\"BB9hRzFp\",\"pr.md\":\"CuXISoCC\",\"en_swarm.md\":\"B8V6dVOc\",\"http.md\":\"Bm5lEonH\",\"en_redis.md\":\"BPYVtQJ-\",\"job.md\":\"CSi1p9px\",\"unit-test.md\":\"EIdK7f17\",\"en_pr.md\":\"BUl97Mle\",\"model.md\":\"CtEMf_iw\",\"en_repository.md\":\"BrJQ6M7L\",\"en_middleware.md\":\"D5W_0TF7\",\"repository.md\":\"BVt8EdIP\",\"wire.md\":\"DAPteEAd\",\"en_service.md\":\"B6Xeobs8\",\"foo.md\":\"C1aJzGpm\",\"en_wire.md\":\"Tbcn3on1\",\"en_server.md\":\"x1HgIoWO\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Nunu文档\",\"description\":\"A VitePress site\",\"base\":\"/nunu/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":\"dark\",\"themeConfig\":{\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/go-nunu/nunu\"}],\"search\":{\"provider\":\"local\",\"options\":{\"locales\":{\"zh\":{\"placeholder\":\"搜索文档\",\"translations\":{\"button\":{\"buttonText\":\"搜索文档\",\"buttonAriaLabel\":\"搜索文档\"},\"modal\":{\"searchBox\":{\"resetButtonTitle\":\"清除查询条件\",\"resetButtonAriaLabel\":\"清除查询条件\",\"cancelButtonText\":\"取消\",\"cancelButtonAriaLabel\":\"取消\"},\"startScreen\":{\"recentSearchesTitle\":\"搜索历史\",\"noRecentSearchesText\":\"没有搜索历史\",\"saveRecentSearchButtonTitle\":\"保存至搜索历史\",\"removeRecentSearchButtonTitle\":\"从搜索历史中移除\",\"favoriteSearchesTitle\":\"收藏\",\"removeFavoriteSearchButtonTitle\":\"从收藏中移除\"},\"errorScreen\":{\"titleText\":\"无法获取结果\",\"helpText\":\"你可能需要检查你的网络连接\"},\"footer\":{\"selectText\":\"选择\",\"navigateText\":\"切换\",\"closeText\":\"关闭\",\"searchByText\":\"搜索提供者\"},\"noResultsScreen\":{\"noResultsText\":\"无法找到相关结果\",\"suggestedQueryText\":\"你可以尝试查询\",\"reportMissingResultsText\":\"你认为该查询应该有结果?\",\"reportMissingResultsLinkText\":\"点击反馈\"}}}},\"en\":{\"placeholder\":\"搜索文档\",\"translations\":{\"button\":{\"buttonText\":\"搜索文档\",\"buttonAriaLabel\":\"搜索文档\"},\"modal\":{\"searchBox\":{\"resetButtonTitle\":\"清除查询条件\",\"resetButtonAriaLabel\":\"清除查询条件\",\"cancelButtonText\":\"取消\",\"cancelButtonAriaLabel\":\"取消\"},\"startScreen\":{\"recentSearchesTitle\":\"搜索历史\",\"noRecentSearchesText\":\"没有搜索历史\",\"saveRecentSearchButtonTitle\":\"保存至搜索历史\",\"removeRecentSearchButtonTitle\":\"从搜索历史中移除\",\"favoriteSearchesTitle\":\"收藏\",\"removeFavoriteSearchButtonTitle\":\"从收藏中移除\"},\"errorScreen\":{\"titleText\":\"无法获取结果\",\"helpText\":\"你可能需要检查你的网络连接\"},\"footer\":{\"selectText\":\"选择\",\"navigateText\":\"切换\",\"closeText\":\"关闭\",\"searchByText\":\"搜索提供者\"},\"noResultsScreen\":{\"noResultsText\":\"无法找到相关结果\",\"suggestedQueryText\":\"你可以尝试查询\",\"reportMissingResultsText\":\"你认为该查询应该有结果?\",\"reportMissingResultsLinkText\":\"点击反馈\"}}}}}}}},\"locales\":{\"root\":{\"label\":\"简体中文\",\"lang\":\"zh-Hans\",\"description\":\"A CLI tool for building Go applications.\",\"themeConfig\":{\"nav\":[{\"text\":\"首页\",\"link\":\"/\"},{\"text\":\"文档\",\"link\":\"/getting-started\",\"activeMatch\":\"/getting-started\"},{\"text\":\"1.0.14\",\"items\":[{\"text\":\"更新日志\",\"link\":\"https://github.com/go-nunu/nunu/blob/main/CHANGELOG.md\"}]}],\"logo\":\"\",\"title\":\"Nunu\",\"siteTitle\":\"Nunu\",\"sidebar\":{\"/\":{\"base\":\"/\",\"items\":[{\"text\":\"入门指引\",\"collapsed\":false,\"items\":[{\"text\":\"引言\",\"link\":\"guide\"},{\"text\":\"快速开始\",\"link\":\"getting-started\"},{\"text\":\"Nunu命令行\",\"link\":\"cli\"}]},{\"text\":\"基础概念\",\"collapsed\":false,\"items\":[{\"text\":\"分层架构\",\"link\":\"architecture\"},{\"text\":\"Wire依赖注入\",\"link\":\"wire\"}]},{\"text\":\"核心组件\",\"collapsed\":false,\"items\":[{\"text\":\"Server\",\"link\":\"server\",\"items\":[{\"text\":\"HTTP路由\",\"link\":\"http\"},{\"text\":\"Task定时任务\",\"link\":\"task\"},{\"text\":\"Job异步事件流\",\"link\":\"job\"},{\"text\":\"Migration数据迁移\",\"link\":\"migration\"},{\"text\":\"GRPC\",\"link\":\"grpc\"},{\"text\":\"Websocket\",\"link\":\"websocket\"}]},{\"text\":\"Handler\",\"link\":\"handler\"},{\"text\":\"Middleware\",\"link\":\"middleware\"},{\"text\":\"Service\",\"link\":\"service\"},{\"text\":\"repository\",\"link\":\"repository\",\"items\":[{\"text\":\"数据库\",\"link\":\"database\"},{\"text\":\"Redis\",\"link\":\"redis\"}]},{\"text\":\"Model\",\"link\":\"model\"},{\"text\":\"Pkg\",\"link\":\"pkg\"},{\"text\":\"日志\",\"link\":\"logger\"},{\"text\":\"自动化文档\",\"link\":\"swagger\"},{\"text\":\"单元测试\",\"link\":\"unit-test\"}]},{\"text\":\"构建部署\",\"collapsed\":false,\"items\":[{\"text\":\"PM2+Nginx\",\"link\":\"nginx\"},{\"text\":\"Docker\",\"link\":\"docker\"},{\"text\":\"Swarm\",\"link\":\"swarm\"},{\"text\":\"K8s\",\"link\":\"k8s\"}]},{\"text\":\"参考\",\"collapsed\":false,\"items\":[{\"text\":\"贡献指南\",\"link\":\"pr\"}]}]}},\"editLink\":{\"pattern\":\"https://github.com/go-nunu/nunu/edit/feature/docs/docs/src/:path\",\"text\":\"在 GitHub 上编辑此页面\"},\"footer\":{\"message\":\"基于 MIT 许可发布\",\"copyright\":\"版权所有 © 2023-2024 go-nunu\"},\"docFooter\":{\"prev\":\"上一页\",\"next\":\"下一页\"},\"outline\":{\"label\":\"页面导航\"},\"lastUpdated\":{\"text\":\"最后更新于\",\"formatOptions\":{\"dateStyle\":\"short\",\"timeStyle\":\"medium\"}},\"langMenuLabel\":\"多语言\",\"returnToTopLabel\":\"回到顶部\",\"sidebarMenuLabel\":\"菜单\",\"darkModeSwitchLabel\":\"主题\",\"lightModeSwitchTitle\":\"切换到浅色模式\",\"darkModeSwitchTitle\":\"切换到深色模式\"}},\"en\":{\"label\":\"English\",\"lang\":\"en-US\",\"description\":\"A CLI tool for building Go applications.\",\"themeConfig\":{\"nav\":[{\"text\":\"首页\",\"link\":\"/en/\"},{\"text\":\"文档\",\"link\":\"/en/getting-started\",\"activeMatch\":\"/en/getting-started\"},{\"text\":\"1.0.14\",\"items\":[{\"text\":\"更新日志\",\"link\":\"https://github.com/go-nunu/nunu/blob/main/CHANGELOG.md\"}]}],\"sidebar\":{\"/en/\":{\"base\":\"/en/\",\"items\":[{\"text\":\"入门指引\",\"collapsed\":false,\"items\":[{\"text\":\"引言\",\"link\":\"guide\"},{\"text\":\"快速开始\",\"link\":\"getting-started\"},{\"text\":\"Nunu命令行\",\"link\":\"cli\"}]},{\"text\":\"基础概念\",\"collapsed\":false,\"items\":[{\"text\":\"分层架构\",\"link\":\"architecture\"},{\"text\":\"Wire依赖注入\",\"link\":\"wire\"}]},{\"text\":\"核心组件\",\"collapsed\":false,\"items\":[{\"text\":\"Server\",\"link\":\"server\"},{\"text\":\"Handler\",\"link\":\"handler\"},{\"text\":\"Middleware\",\"link\":\"middleware\"},{\"text\":\"Service\",\"link\":\"service\"},{\"text\":\"repository\",\"link\":\"repository\",\"items\":[{\"text\":\"数据库\",\"link\":\"database\"},{\"text\":\"Redis\",\"link\":\"redis\"}]},{\"text\":\"Model\",\"link\":\"model\"},{\"text\":\"Pkg\",\"link\":\"pkg\"},{\"text\":\"日志\",\"link\":\"logger\"},{\"text\":\"自动化文档\",\"link\":\"swagger\"},{\"text\":\"单元测试\",\"link\":\"unit-test\"}]},{\"text\":\"构建部署\",\"collapsed\":false,\"items\":[{\"text\":\"PM2+Nginx\",\"link\":\"nginx\"},{\"text\":\"Docker\",\"link\":\"docker\"},{\"text\":\"Swarm\",\"link\":\"swarm\"},{\"text\":\"K8s\",\"link\":\"k8s\"}]},{\"text\":\"参考\",\"collapsed\":false,\"items\":[{\"text\":\"贡献指南\",\"link\":\"pr\"}]},{\"text\":\"加入交流群\",\"base\":\"/zh/reference/\",\"link\":\"site-config\"}]}},\"editLink\":{\"pattern\":\"https://github.com/go-nunu/nunu/edit/feature/docs/docs/src/en/:path\",\"text\":\"Edit this page on GitHub\"},\"footer\":{\"message\":\"Released under the MIT License.\",\"copyright\":\"Copyright © 2019-present Evan You\"}}}},\"scrollOffset\":134,\"cleanUrls\":true}"); \ No newline at end of file diff --git a/docs/assets/chunks/theme.VdBoP6hP.js b/docs/assets/chunks/theme.B8LElrRV.js similarity index 99% rename from docs/assets/chunks/theme.VdBoP6hP.js rename to docs/assets/chunks/theme.B8LElrRV.js index 169ddd6..efa6fb5 100644 --- a/docs/assets/chunks/theme.VdBoP6hP.js +++ b/docs/assets/chunks/theme.B8LElrRV.js @@ -1,7 +1,7 @@ function __vite__mapDeps(indexes) { if (!__vite__mapDeps.viteFileDeps) { - __vite__mapDeps.viteFileDeps = ["assets/chunks/VPLocalSearchBox.De8VqG1H.js","assets/chunks/framework.DZjeu1b3.js"] + __vite__mapDeps.viteFileDeps = ["assets/chunks/VPLocalSearchBox.Bp9Nb2eD.js","assets/chunks/framework.DZjeu1b3.js"] } return indexes.map((i) => __vite__mapDeps.viteFileDeps[i]) } -import{d as _,o as a,c,r as l,n as N,a as F,t as w,b as $,w as d,T as ve,e as f,_ as k,u as Ue,i as Ge,f as je,g as pe,h as T,j as J,k as g,l as z,m as v,p as i,q as B,s as H,v as j,x as ie,y as q,z as x,A as he,B as Pe,C as ze,D as qe,E as K,F as M,G as E,H as Ve,I as ee,J as m,K as R,L as Le,M as te,N as Q,O as oe,P as Ke,Q as Se,R as We,S as le,U as Re,V as we,W as Je,X as Ye,Y as Qe,Z as Ie,$ as Te,a0 as Xe,a1 as Ze,a2 as xe,a3 as et}from"./framework.DZjeu1b3.js";const tt=_({__name:"VPBadge",props:{text:{},type:{default:"tip"}},setup(o){return(e,t)=>(a(),c("span",{class:N(["VPBadge",e.type])},[l(e.$slots,"default",{},()=>[F(w(e.text),1)])],2))}}),ot={key:0,class:"VPBackdrop"},st=_({__name:"VPBackdrop",props:{show:{type:Boolean}},setup(o){return(e,t)=>(a(),$(ve,{name:"fade"},{default:d(()=>[e.show?(a(),c("div",ot)):f("",!0)]),_:1}))}}),nt=k(st,[["__scopeId","data-v-54a304ca"]]),V=Ue;function at(o,e){let t,s=!1;return()=>{t&&clearTimeout(t),s?t=setTimeout(o,e):(o(),(s=!0)&&setTimeout(()=>s=!1,e))}}function ce(o){return/^\//.test(o)?o:`/${o}`}function fe(o){const{pathname:e,search:t,hash:s,protocol:n}=new URL(o,"http://a.com");if(Ge(o)||o.startsWith("#")||!n.startsWith("http")||!je(e))return o;const{site:r}=V(),u=e.endsWith("/")||e.endsWith(".html")?o:o.replace(/(?:(^\.+)\/)?.*$/,`$1${e.replace(/(\.md)?$/,r.value.cleanUrls?"":".html")}${t}${s}`);return pe(u)}const _e=T(J?location.hash:"");J&&window.addEventListener("hashchange",()=>{_e.value=location.hash});function Y({removeCurrent:o=!0,correspondingLink:e=!1}={}){const{site:t,localeIndex:s,page:n,theme:r}=V(),u=g(()=>{var p,b;return{label:(p=t.value.locales[s.value])==null?void 0:p.label,link:((b=t.value.locales[s.value])==null?void 0:b.link)||(s.value==="root"?"/":`/${s.value}/`)}});return{localeLinks:g(()=>Object.entries(t.value.locales).flatMap(([p,b])=>o&&u.value.label===b.label?[]:{text:b.label,link:rt(b.link||(p==="root"?"/":`/${p}/`),r.value.i18nRouting!==!1&&e,n.value.relativePath.slice(u.value.link.length-1),!t.value.cleanUrls)+_e.value})),currentLang:u}}function rt(o,e,t,s){return e?o.replace(/\/$/,"")+ce(t.replace(/(^|\/)index\.md$/,"$1").replace(/\.md$/,s?".html":"")):o}const it=o=>(B("data-v-b9c0c15a"),o=o(),H(),o),lt={class:"NotFound"},ct={class:"code"},ut={class:"title"},dt=it(()=>v("div",{class:"divider"},null,-1)),vt={class:"quote"},pt={class:"action"},ht=["href","aria-label"],ft=_({__name:"NotFound",setup(o){const{site:e,theme:t}=V(),{localeLinks:s}=Y({removeCurrent:!1}),n=T("/");return z(()=>{var u;const r=window.location.pathname.replace(e.value.base,"").replace(/(^.*?\/).*$/,"/$1");s.value.length&&(n.value=((u=s.value.find(({link:h})=>h.startsWith(r)))==null?void 0:u.link)||s.value[0].link)}),(r,u)=>{var h,p,b,P,y;return a(),c("div",lt,[v("p",ct,w(((h=i(t).notFound)==null?void 0:h.code)??"404"),1),v("h1",ut,w(((p=i(t).notFound)==null?void 0:p.title)??"PAGE NOT FOUND"),1),dt,v("blockquote",vt,w(((b=i(t).notFound)==null?void 0:b.quote)??"But if you don't change your direction, and if you keep looking, you may end up where you are heading."),1),v("div",pt,[v("a",{class:"link",href:i(pe)(n.value),"aria-label":((P=i(t).notFound)==null?void 0:P.linkLabel)??"go to home"},w(((y=i(t).notFound)==null?void 0:y.linkText)??"Take me home"),9,ht)])])}}}),_t=k(ft,[["__scopeId","data-v-b9c0c15a"]]);function Ne(o,e){if(Array.isArray(o))return X(o);if(o==null)return[];e=ce(e);const t=Object.keys(o).sort((n,r)=>r.split("/").length-n.split("/").length).find(n=>e.startsWith(ce(n))),s=t?o[t]:[];return Array.isArray(s)?X(s):X(s.items,s.base)}function mt(o){const e=[];let t=0;for(const s in o){const n=o[s];if(n.items){t=e.push(n);continue}e[t]||e.push({items:[]}),e[t].items.push(n)}return e}function kt(o){const e=[];function t(s){for(const n of s)n.text&&n.link&&e.push({text:n.text,link:n.link,docFooterText:n.docFooterText}),n.items&&t(n.items)}return t(o),e}function ue(o,e){return Array.isArray(e)?e.some(t=>ue(o,t)):j(o,e.link)?!0:e.items?ue(o,e.items):!1}function X(o,e){return[...o].map(t=>{const s={...t},n=s.base||e;return n&&s.link&&(s.link=n+s.link),s.items&&(s.items=X(s.items,n)),s})}function O(){const{frontmatter:o,page:e,theme:t}=V(),s=ie("(min-width: 960px)"),n=T(!1),r=g(()=>{const C=t.value.sidebar,S=e.value.relativePath;return C?Ne(C,S):[]}),u=T(r.value);q(r,(C,S)=>{JSON.stringify(C)!==JSON.stringify(S)&&(u.value=r.value)});const h=g(()=>o.value.sidebar!==!1&&u.value.length>0&&o.value.layout!=="home"),p=g(()=>b?o.value.aside==null?t.value.aside==="left":o.value.aside==="left":!1),b=g(()=>o.value.layout==="home"?!1:o.value.aside!=null?!!o.value.aside:t.value.aside!==!1),P=g(()=>h.value&&s.value),y=g(()=>h.value?mt(u.value):[]);function L(){n.value=!0}function I(){n.value=!1}function A(){n.value?I():L()}return{isOpen:n,sidebar:u,sidebarGroups:y,hasSidebar:h,hasAside:b,leftAside:p,isSidebarEnabled:P,open:L,close:I,toggle:A}}function bt(o,e){let t;x(()=>{t=o.value?document.activeElement:void 0}),z(()=>{window.addEventListener("keyup",s)}),he(()=>{window.removeEventListener("keyup",s)});function s(n){n.key==="Escape"&&o.value&&(e(),t==null||t.focus())}}function $t(o){const{page:e}=V(),t=T(!1),s=g(()=>o.value.collapsed!=null),n=g(()=>!!o.value.link),r=T(!1),u=()=>{r.value=j(e.value.relativePath,o.value.link)};q([e,o,_e],u),z(u);const h=g(()=>r.value?!0:o.value.items?ue(e.value.relativePath,o.value.items):!1),p=g(()=>!!(o.value.items&&o.value.items.length));x(()=>{t.value=!!(s.value&&o.value.collapsed)}),Pe(()=>{(r.value||h.value)&&(t.value=!1)});function b(){s.value&&(t.value=!t.value)}return{collapsed:t,collapsible:s,isLink:n,isActiveLink:r,hasActiveLink:h,hasChildren:p,toggle:b}}function gt(){const{hasSidebar:o}=O(),e=ie("(min-width: 960px)"),t=ie("(min-width: 1280px)");return{isAsideEnabled:g(()=>!t.value&&!e.value?!1:o.value?t.value:e.value)}}const de=[];function Me(o){return typeof o.outline=="object"&&!Array.isArray(o.outline)&&o.outline.label||o.outlineTitle||"On this page"}function me(o){const e=[...document.querySelectorAll(".VPDoc :where(h1,h2,h3,h4,h5,h6)")].filter(t=>t.id&&t.hasChildNodes()).map(t=>{const s=Number(t.tagName[1]);return{element:t,title:yt(t),link:"#"+t.id,level:s}});return Pt(e,o)}function yt(o){let e="";for(const t of o.childNodes)if(t.nodeType===1){if(t.classList.contains("VPBadge")||t.classList.contains("header-anchor")||t.classList.contains("ignore-header"))continue;e+=t.textContent}else t.nodeType===3&&(e+=t.textContent);return e.trim()}function Pt(o,e){if(e===!1)return[];const t=(typeof e=="object"&&!Array.isArray(e)?e.level:e)||2,[s,n]=typeof t=="number"?[t,t]:t==="deep"?[2,6]:t;o=o.filter(u=>u.level>=s&&u.level<=n),de.length=0;for(const{element:u,link:h}of o)de.push({element:u,link:h});const r=[];e:for(let u=0;u=0;p--){const b=o[p];if(b.level{requestAnimationFrame(r),window.addEventListener("scroll",s)}),ze(()=>{u(location.hash)}),he(()=>{window.removeEventListener("scroll",s)});function r(){if(!t.value)return;const h=window.scrollY,p=window.innerHeight,b=document.body.offsetHeight,P=Math.abs(h+p-b)<1,y=de.map(({element:I,link:A})=>({link:A,top:Lt(I)})).filter(({top:I})=>!Number.isNaN(I)).sort((I,A)=>I.top-A.top);if(!y.length){u(null);return}if(h<1){u(null);return}if(P){u(y[y.length-1].link);return}let L=null;for(const{link:I,top:A}of y){if(A>h+qe()+4)break;L=I}u(L)}function u(h){n&&n.classList.remove("active"),h==null?n=null:n=o.value.querySelector(`a[href="${decodeURIComponent(h)}"]`);const p=n;p?(p.classList.add("active"),e.value.style.top=p.offsetTop+39+"px",e.value.style.opacity="1"):(e.value.style.top="33px",e.value.style.opacity="0")}}function Lt(o){let e=0;for(;o!==document.body;){if(o===null)return NaN;e+=o.offsetTop,o=o.offsetParent}return e}const St=["href","title"],wt=_({__name:"VPDocOutlineItem",props:{headers:{},root:{type:Boolean}},setup(o){function e({target:t}){const s=t.href.split("#")[1],n=document.getElementById(decodeURIComponent(s));n==null||n.focus({preventScroll:!0})}return(t,s)=>{const n=K("VPDocOutlineItem",!0);return a(),c("ul",{class:N(["VPDocOutlineItem",t.root?"root":"nested"])},[(a(!0),c(M,null,E(t.headers,({children:r,link:u,title:h})=>(a(),c("li",null,[v("a",{class:"outline-link",href:u,onClick:e,title:h},w(h),9,St),r!=null&&r.length?(a(),$(n,{key:0,headers:r},null,8,["headers"])):f("",!0)]))),256))],2)}}}),Ae=k(wt,[["__scopeId","data-v-53c99d69"]]),It=o=>(B("data-v-6b52fe58"),o=o(),H(),o),Tt={class:"content"},Nt={class:"outline-title",role:"heading","aria-level":"2"},Mt={"aria-labelledby":"doc-outline-aria-label"},At=It(()=>v("span",{class:"visually-hidden",id:"doc-outline-aria-label"}," Table of Contents for current page ",-1)),Ct=_({__name:"VPDocAsideOutline",setup(o){const{frontmatter:e,theme:t}=V(),s=Ve([]);ee(()=>{s.value=me(e.value.outline??t.value.outline)});const n=T(),r=T();return Vt(n,r),(u,h)=>(a(),c("div",{class:N(["VPDocAsideOutline",{"has-outline":s.value.length>0}]),ref_key:"container",ref:n,role:"navigation"},[v("div",Tt,[v("div",{class:"outline-marker",ref_key:"marker",ref:r},null,512),v("div",Nt,w(i(Me)(i(t))),1),v("nav",Mt,[At,m(Ae,{headers:s.value,root:!0},null,8,["headers"])])])],2))}}),Bt=k(Ct,[["__scopeId","data-v-6b52fe58"]]),Ht={class:"VPDocAsideCarbonAds"},Et=_({__name:"VPDocAsideCarbonAds",props:{carbonAds:{}},setup(o){const e=()=>null;return(t,s)=>(a(),c("div",Ht,[m(i(e),{"carbon-ads":t.carbonAds},null,8,["carbon-ads"])]))}}),Ft=o=>(B("data-v-cb998dce"),o=o(),H(),o),Dt={class:"VPDocAside"},Ot=Ft(()=>v("div",{class:"spacer"},null,-1)),Ut=_({__name:"VPDocAside",setup(o){const{theme:e}=V();return(t,s)=>(a(),c("div",Dt,[l(t.$slots,"aside-top",{},void 0,!0),l(t.$slots,"aside-outline-before",{},void 0,!0),m(Bt),l(t.$slots,"aside-outline-after",{},void 0,!0),Ot,l(t.$slots,"aside-ads-before",{},void 0,!0),i(e).carbonAds?(a(),$(Et,{key:0,"carbon-ads":i(e).carbonAds},null,8,["carbon-ads"])):f("",!0),l(t.$slots,"aside-ads-after",{},void 0,!0),l(t.$slots,"aside-bottom",{},void 0,!0)]))}}),Gt=k(Ut,[["__scopeId","data-v-cb998dce"]]);function jt(){const{theme:o,page:e}=V();return g(()=>{const{text:t="Edit this page",pattern:s=""}=o.value.editLink||{};let n;return typeof s=="function"?n=s(e.value):n=s.replace(/:path/g,e.value.filePath),{url:n,text:t}})}function zt(){const{page:o,theme:e,frontmatter:t}=V();return g(()=>{var b,P,y,L,I,A,C,S;const s=Ne(e.value.sidebar,o.value.relativePath),n=kt(s),r=qt(n,U=>U.link.replace(/[?#].*$/,"")),u=r.findIndex(U=>j(o.value.relativePath,U.link)),h=((b=e.value.docFooter)==null?void 0:b.prev)===!1&&!t.value.prev||t.value.prev===!1,p=((P=e.value.docFooter)==null?void 0:P.next)===!1&&!t.value.next||t.value.next===!1;return{prev:h?void 0:{text:(typeof t.value.prev=="string"?t.value.prev:typeof t.value.prev=="object"?t.value.prev.text:void 0)??((y=r[u-1])==null?void 0:y.docFooterText)??((L=r[u-1])==null?void 0:L.text),link:(typeof t.value.prev=="object"?t.value.prev.link:void 0)??((I=r[u-1])==null?void 0:I.link)},next:p?void 0:{text:(typeof t.value.next=="string"?t.value.next:typeof t.value.next=="object"?t.value.next.text:void 0)??((A=r[u+1])==null?void 0:A.docFooterText)??((C=r[u+1])==null?void 0:C.text),link:(typeof t.value.next=="object"?t.value.next.link:void 0)??((S=r[u+1])==null?void 0:S.link)}}})}function qt(o,e){const t=new Set;return o.filter(s=>{const n=e(s);return t.has(n)?!1:t.add(n)})}const D=_({__name:"VPLink",props:{tag:{},href:{},noIcon:{type:Boolean},target:{},rel:{}},setup(o){const e=o,t=g(()=>e.tag??(e.href?"a":"span")),s=g(()=>e.href&&Le.test(e.href));return(n,r)=>(a(),$(R(t.value),{class:N(["VPLink",{link:n.href,"vp-external-link-icon":s.value,"no-icon":n.noIcon}]),href:n.href?i(fe)(n.href):void 0,target:n.target??(s.value?"_blank":void 0),rel:n.rel??(s.value?"noreferrer":void 0)},{default:d(()=>[l(n.$slots,"default")]),_:3},8,["class","href","target","rel"]))}}),Kt={class:"VPLastUpdated"},Wt=["datetime"],Rt=_({__name:"VPDocFooterLastUpdated",setup(o){const{theme:e,page:t,frontmatter:s,lang:n}=V(),r=g(()=>new Date(s.value.lastUpdated??t.value.lastUpdated)),u=g(()=>r.value.toISOString()),h=T("");return z(()=>{x(()=>{var p,b,P;h.value=new Intl.DateTimeFormat((b=(p=e.value.lastUpdated)==null?void 0:p.formatOptions)!=null&&b.forceLocale?n.value:void 0,((P=e.value.lastUpdated)==null?void 0:P.formatOptions)??{dateStyle:"short",timeStyle:"short"}).format(r.value)})}),(p,b)=>{var P;return a(),c("p",Kt,[F(w(((P=i(e).lastUpdated)==null?void 0:P.text)||i(e).lastUpdatedText||"Last updated")+": ",1),v("time",{datetime:u.value},w(h.value),9,Wt)])}}}),Jt=k(Rt,[["__scopeId","data-v-19a7ae4e"]]),Yt=o=>(B("data-v-b77f9094"),o=o(),H(),o),Qt={key:0,class:"VPDocFooter"},Xt={key:0,class:"edit-info"},Zt={key:0,class:"edit-link"},xt=Yt(()=>v("span",{class:"vpi-square-pen edit-link-icon"},null,-1)),eo={key:1,class:"last-updated"},to={key:1,class:"prev-next"},oo={class:"pager"},so=["innerHTML"],no=["innerHTML"],ao={class:"pager"},ro=["innerHTML"],io=["innerHTML"],lo=_({__name:"VPDocFooter",setup(o){const{theme:e,page:t,frontmatter:s}=V(),n=jt(),r=zt(),u=g(()=>e.value.editLink&&s.value.editLink!==!1),h=g(()=>t.value.lastUpdated&&s.value.lastUpdated!==!1),p=g(()=>u.value||h.value||r.value.prev||r.value.next);return(b,P)=>{var y,L,I,A;return p.value?(a(),c("footer",Qt,[l(b.$slots,"doc-footer-before",{},void 0,!0),u.value||h.value?(a(),c("div",Xt,[u.value?(a(),c("div",Zt,[m(D,{class:"edit-link-button",href:i(n).url,"no-icon":!0},{default:d(()=>[xt,F(" "+w(i(n).text),1)]),_:1},8,["href"])])):f("",!0),h.value?(a(),c("div",eo,[m(Jt)])):f("",!0)])):f("",!0),(y=i(r).prev)!=null&&y.link||(L=i(r).next)!=null&&L.link?(a(),c("nav",to,[v("div",oo,[(I=i(r).prev)!=null&&I.link?(a(),$(D,{key:0,class:"pager-link prev",href:i(r).prev.link},{default:d(()=>{var C;return[v("span",{class:"desc",innerHTML:((C=i(e).docFooter)==null?void 0:C.prev)||"Previous page"},null,8,so),v("span",{class:"title",innerHTML:i(r).prev.text},null,8,no)]}),_:1},8,["href"])):f("",!0)]),v("div",ao,[(A=i(r).next)!=null&&A.link?(a(),$(D,{key:0,class:"pager-link next",href:i(r).next.link},{default:d(()=>{var C;return[v("span",{class:"desc",innerHTML:((C=i(e).docFooter)==null?void 0:C.next)||"Next page"},null,8,ro),v("span",{class:"title",innerHTML:i(r).next.text},null,8,io)]}),_:1},8,["href"])):f("",!0)])])):f("",!0)])):f("",!0)}}}),co=k(lo,[["__scopeId","data-v-b77f9094"]]),uo=o=>(B("data-v-e6f2a212"),o=o(),H(),o),vo={class:"container"},po=uo(()=>v("div",{class:"aside-curtain"},null,-1)),ho={class:"aside-container"},fo={class:"aside-content"},_o={class:"content"},mo={class:"content-container"},ko={class:"main"},bo=_({__name:"VPDoc",setup(o){const{theme:e}=V(),t=te(),{hasSidebar:s,hasAside:n,leftAside:r}=O(),u=g(()=>t.path.replace(/[./]+/g,"_").replace(/_html$/,""));return(h,p)=>{const b=K("Content");return a(),c("div",{class:N(["VPDoc",{"has-sidebar":i(s),"has-aside":i(n)}])},[l(h.$slots,"doc-top",{},void 0,!0),v("div",vo,[i(n)?(a(),c("div",{key:0,class:N(["aside",{"left-aside":i(r)}])},[po,v("div",ho,[v("div",fo,[m(Gt,null,{"aside-top":d(()=>[l(h.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":d(()=>[l(h.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":d(()=>[l(h.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":d(()=>[l(h.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":d(()=>[l(h.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":d(()=>[l(h.$slots,"aside-ads-after",{},void 0,!0)]),_:3})])])],2)):f("",!0),v("div",_o,[v("div",mo,[l(h.$slots,"doc-before",{},void 0,!0),v("main",ko,[m(b,{class:N(["vp-doc",[u.value,i(e).externalLinkIcon&&"external-link-icon-enabled"]])},null,8,["class"])]),m(co,null,{"doc-footer-before":d(()=>[l(h.$slots,"doc-footer-before",{},void 0,!0)]),_:3}),l(h.$slots,"doc-after",{},void 0,!0)])])]),l(h.$slots,"doc-bottom",{},void 0,!0)],2)}}}),$o=k(bo,[["__scopeId","data-v-e6f2a212"]]),go=_({__name:"VPButton",props:{tag:{},size:{default:"medium"},theme:{default:"brand"},text:{},href:{},target:{},rel:{}},setup(o){const e=o,t=g(()=>e.href&&Le.test(e.href)),s=g(()=>e.tag||e.href?"a":"button");return(n,r)=>(a(),$(R(s.value),{class:N(["VPButton",[n.size,n.theme]]),href:n.href?i(fe)(n.href):void 0,target:e.target??(t.value?"_blank":void 0),rel:e.rel??(t.value?"noreferrer":void 0)},{default:d(()=>[F(w(n.text),1)]),_:1},8,["class","href","target","rel"]))}}),yo=k(go,[["__scopeId","data-v-c9cf0e3c"]]),Po=["src","alt"],Vo=_({inheritAttrs:!1,__name:"VPImage",props:{image:{},alt:{}},setup(o){return(e,t)=>{const s=K("VPImage",!0);return e.image?(a(),c(M,{key:0},[typeof e.image=="string"||"src"in e.image?(a(),c("img",Q({key:0,class:"VPImage"},typeof e.image=="string"?e.$attrs:{...e.image,...e.$attrs},{src:i(pe)(typeof e.image=="string"?e.image:e.image.src),alt:e.alt??(typeof e.image=="string"?"":e.image.alt||"")}),null,16,Po)):(a(),c(M,{key:1},[m(s,Q({class:"dark",image:e.image.dark,alt:e.image.alt},e.$attrs),null,16,["image","alt"]),m(s,Q({class:"light",image:e.image.light,alt:e.image.alt},e.$attrs),null,16,["image","alt"])],64))],64)):f("",!0)}}}),Z=k(Vo,[["__scopeId","data-v-ab19afbb"]]),Lo=o=>(B("data-v-b10c5094"),o=o(),H(),o),So={class:"container"},wo={class:"main"},Io={key:0,class:"name"},To=["innerHTML"],No=["innerHTML"],Mo=["innerHTML"],Ao={key:0,class:"actions"},Co={key:0,class:"image"},Bo={class:"image-container"},Ho=Lo(()=>v("div",{class:"image-bg"},null,-1)),Eo=_({__name:"VPHero",props:{name:{},text:{},tagline:{},image:{},actions:{}},setup(o){const e=oe("hero-image-slot-exists");return(t,s)=>(a(),c("div",{class:N(["VPHero",{"has-image":t.image||i(e)}])},[v("div",So,[v("div",wo,[l(t.$slots,"home-hero-info-before",{},void 0,!0),l(t.$slots,"home-hero-info",{},()=>[t.name?(a(),c("h1",Io,[v("span",{innerHTML:t.name,class:"clip"},null,8,To)])):f("",!0),t.text?(a(),c("p",{key:1,innerHTML:t.text,class:"text"},null,8,No)):f("",!0),t.tagline?(a(),c("p",{key:2,innerHTML:t.tagline,class:"tagline"},null,8,Mo)):f("",!0)],!0),l(t.$slots,"home-hero-info-after",{},void 0,!0),t.actions?(a(),c("div",Ao,[(a(!0),c(M,null,E(t.actions,n=>(a(),c("div",{key:n.link,class:"action"},[m(yo,{tag:"a",size:"medium",theme:n.theme,text:n.text,href:n.link,target:n.target,rel:n.rel},null,8,["theme","text","href","target","rel"])]))),128))])):f("",!0),l(t.$slots,"home-hero-actions-after",{},void 0,!0)]),t.image||i(e)?(a(),c("div",Co,[v("div",Bo,[Ho,l(t.$slots,"home-hero-image",{},()=>[t.image?(a(),$(Z,{key:0,class:"image-src",image:t.image},null,8,["image"])):f("",!0)],!0)])])):f("",!0)])],2))}}),Fo=k(Eo,[["__scopeId","data-v-b10c5094"]]),Do=_({__name:"VPHomeHero",setup(o){const{frontmatter:e}=V();return(t,s)=>i(e).hero?(a(),$(Fo,{key:0,class:"VPHomeHero",name:i(e).hero.name,text:i(e).hero.text,tagline:i(e).hero.tagline,image:i(e).hero.image,actions:i(e).hero.actions},{"home-hero-info-before":d(()=>[l(t.$slots,"home-hero-info-before")]),"home-hero-info":d(()=>[l(t.$slots,"home-hero-info")]),"home-hero-info-after":d(()=>[l(t.$slots,"home-hero-info-after")]),"home-hero-actions-after":d(()=>[l(t.$slots,"home-hero-actions-after")]),"home-hero-image":d(()=>[l(t.$slots,"home-hero-image")]),_:3},8,["name","text","tagline","image","actions"])):f("",!0)}}),Oo=o=>(B("data-v-bd37d1a2"),o=o(),H(),o),Uo={class:"box"},Go={key:0,class:"icon"},jo=["innerHTML"],zo=["innerHTML"],qo=["innerHTML"],Ko={key:4,class:"link-text"},Wo={class:"link-text-value"},Ro=Oo(()=>v("span",{class:"vpi-arrow-right link-text-icon"},null,-1)),Jo=_({__name:"VPFeature",props:{icon:{},title:{},details:{},link:{},linkText:{},rel:{},target:{}},setup(o){return(e,t)=>(a(),$(D,{class:"VPFeature",href:e.link,rel:e.rel,target:e.target,"no-icon":!0,tag:e.link?"a":"div"},{default:d(()=>[v("article",Uo,[typeof e.icon=="object"&&e.icon.wrap?(a(),c("div",Go,[m(Z,{image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])])):typeof e.icon=="object"?(a(),$(Z,{key:1,image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])):e.icon?(a(),c("div",{key:2,class:"icon",innerHTML:e.icon},null,8,jo)):f("",!0),v("h2",{class:"title",innerHTML:e.title},null,8,zo),e.details?(a(),c("p",{key:3,class:"details",innerHTML:e.details},null,8,qo)):f("",!0),e.linkText?(a(),c("div",Ko,[v("p",Wo,[F(w(e.linkText)+" ",1),Ro])])):f("",!0)])]),_:1},8,["href","rel","target","tag"]))}}),Yo=k(Jo,[["__scopeId","data-v-bd37d1a2"]]),Qo={key:0,class:"VPFeatures"},Xo={class:"container"},Zo={class:"items"},xo=_({__name:"VPFeatures",props:{features:{}},setup(o){const e=o,t=g(()=>{const s=e.features.length;if(s){if(s===2)return"grid-2";if(s===3)return"grid-3";if(s%3===0)return"grid-6";if(s>3)return"grid-4"}else return});return(s,n)=>s.features?(a(),c("div",Qo,[v("div",Xo,[v("div",Zo,[(a(!0),c(M,null,E(s.features,r=>(a(),c("div",{key:r.title,class:N(["item",[t.value]])},[m(Yo,{icon:r.icon,title:r.title,details:r.details,link:r.link,"link-text":r.linkText,rel:r.rel,target:r.target},null,8,["icon","title","details","link","link-text","rel","target"])],2))),128))])])])):f("",!0)}}),es=k(xo,[["__scopeId","data-v-b1eea84a"]]),ts=_({__name:"VPHomeFeatures",setup(o){const{frontmatter:e}=V();return(t,s)=>i(e).features?(a(),$(es,{key:0,class:"VPHomeFeatures",features:i(e).features},null,8,["features"])):f("",!0)}}),os=_({__name:"VPHomeContent",setup(o){const{width:e}=Ke({includeScrollbar:!1});return(t,s)=>(a(),c("div",{class:"vp-doc container",style:Se(i(e)?{"--vp-offset":`calc(50% - ${i(e)/2}px)`}:{})},[l(t.$slots,"default",{},void 0,!0)],4))}}),ss=k(os,[["__scopeId","data-v-d59ac166"]]),ns={class:"VPHome"},as=_({__name:"VPHome",setup(o){const{frontmatter:e}=V();return(t,s)=>{const n=K("Content");return a(),c("div",ns,[l(t.$slots,"home-hero-before",{},void 0,!0),m(Do,null,{"home-hero-info-before":d(()=>[l(t.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":d(()=>[l(t.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":d(()=>[l(t.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":d(()=>[l(t.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":d(()=>[l(t.$slots,"home-hero-image",{},void 0,!0)]),_:3}),l(t.$slots,"home-hero-after",{},void 0,!0),l(t.$slots,"home-features-before",{},void 0,!0),m(ts),l(t.$slots,"home-features-after",{},void 0,!0),i(e).markdownStyles!==!1?(a(),$(ss,{key:0},{default:d(()=>[m(n)]),_:1})):(a(),$(n,{key:1}))])}}}),rs=k(as,[["__scopeId","data-v-07b1ad08"]]),is={},ls={class:"VPPage"};function cs(o,e){const t=K("Content");return a(),c("div",ls,[l(o.$slots,"page-top"),m(t),l(o.$slots,"page-bottom")])}const us=k(is,[["render",cs]]),ds=_({__name:"VPContent",setup(o){const{page:e,frontmatter:t}=V(),{hasSidebar:s}=O();return(n,r)=>(a(),c("div",{class:N(["VPContent",{"has-sidebar":i(s),"is-home":i(t).layout==="home"}]),id:"VPContent"},[i(e).isNotFound?l(n.$slots,"not-found",{key:0},()=>[m(_t)],!0):i(t).layout==="page"?(a(),$(us,{key:1},{"page-top":d(()=>[l(n.$slots,"page-top",{},void 0,!0)]),"page-bottom":d(()=>[l(n.$slots,"page-bottom",{},void 0,!0)]),_:3})):i(t).layout==="home"?(a(),$(rs,{key:2},{"home-hero-before":d(()=>[l(n.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":d(()=>[l(n.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":d(()=>[l(n.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":d(()=>[l(n.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":d(()=>[l(n.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":d(()=>[l(n.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":d(()=>[l(n.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":d(()=>[l(n.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":d(()=>[l(n.$slots,"home-features-after",{},void 0,!0)]),_:3})):i(t).layout&&i(t).layout!=="doc"?(a(),$(R(i(t).layout),{key:3})):(a(),$($o,{key:4},{"doc-top":d(()=>[l(n.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":d(()=>[l(n.$slots,"doc-bottom",{},void 0,!0)]),"doc-footer-before":d(()=>[l(n.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":d(()=>[l(n.$slots,"doc-before",{},void 0,!0)]),"doc-after":d(()=>[l(n.$slots,"doc-after",{},void 0,!0)]),"aside-top":d(()=>[l(n.$slots,"aside-top",{},void 0,!0)]),"aside-outline-before":d(()=>[l(n.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":d(()=>[l(n.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":d(()=>[l(n.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":d(()=>[l(n.$slots,"aside-ads-after",{},void 0,!0)]),"aside-bottom":d(()=>[l(n.$slots,"aside-bottom",{},void 0,!0)]),_:3}))],2))}}),vs=k(ds,[["__scopeId","data-v-9a6c75ad"]]),ps={class:"container"},hs=["innerHTML"],fs=["innerHTML"],_s=_({__name:"VPFooter",setup(o){const{theme:e,frontmatter:t}=V(),{hasSidebar:s}=O();return(n,r)=>i(e).footer&&i(t).footer!==!1?(a(),c("footer",{key:0,class:N(["VPFooter",{"has-sidebar":i(s)}])},[v("div",ps,[i(e).footer.message?(a(),c("p",{key:0,class:"message",innerHTML:i(e).footer.message},null,8,hs)):f("",!0),i(e).footer.copyright?(a(),c("p",{key:1,class:"copyright",innerHTML:i(e).footer.copyright},null,8,fs)):f("",!0)])],2)):f("",!0)}}),ms=k(_s,[["__scopeId","data-v-566314d4"]]);function ks(){const{theme:o,frontmatter:e}=V(),t=Ve([]),s=g(()=>t.value.length>0);return ee(()=>{t.value=me(e.value.outline??o.value.outline)}),{headers:t,hasLocalNav:s}}const bs=o=>(B("data-v-0b5c97a1"),o=o(),H(),o),$s=bs(()=>v("span",{class:"vpi-chevron-right icon"},null,-1)),gs={class:"header"},ys={class:"outline"},Ps=_({__name:"VPLocalNavOutlineDropdown",props:{headers:{},navHeight:{}},setup(o){const e=o,{theme:t}=V(),s=T(!1),n=T(0),r=T(),u=T();We(r,()=>{s.value=!1}),le("Escape",()=>{s.value=!1}),ee(()=>{s.value=!1});function h(){s.value=!s.value,n.value=window.innerHeight+Math.min(window.scrollY-e.navHeight,0)}function p(P){P.target.classList.contains("outline-link")&&(u.value&&(u.value.style.transition="none"),Re(()=>{s.value=!1}))}function b(){s.value=!1,window.scrollTo({top:0,left:0,behavior:"smooth"})}return(P,y)=>(a(),c("div",{class:"VPLocalNavOutlineDropdown",style:Se({"--vp-vh":n.value+"px"}),ref_key:"main",ref:r},[P.headers.length>0?(a(),c("button",{key:0,onClick:h,class:N({open:s.value})},[F(w(i(Me)(i(t)))+" ",1),$s],2)):(a(),c("button",{key:1,onClick:b},w(i(t).returnToTopLabel||"Return to top"),1)),m(ve,{name:"flyout"},{default:d(()=>[s.value?(a(),c("div",{key:0,ref_key:"items",ref:u,class:"items",onClick:p},[v("div",gs,[v("a",{class:"top-link",href:"#",onClick:b},w(i(t).returnToTopLabel||"Return to top"),1)]),v("div",ys,[m(Ae,{headers:P.headers},null,8,["headers"])])],512)):f("",!0)]),_:1})],4))}}),Vs=k(Ps,[["__scopeId","data-v-0b5c97a1"]]),Ls=o=>(B("data-v-2488c25a"),o=o(),H(),o),Ss={class:"container"},ws=["aria-expanded"],Is=Ls(()=>v("span",{class:"vpi-align-left menu-icon"},null,-1)),Ts={class:"menu-text"},Ns=_({__name:"VPLocalNav",props:{open:{type:Boolean}},emits:["open-menu"],setup(o){const{theme:e,frontmatter:t}=V(),{hasSidebar:s}=O(),{headers:n}=ks(),{y:r}=we(),u=T(0);z(()=>{u.value=parseInt(getComputedStyle(document.documentElement).getPropertyValue("--vp-nav-height"))}),ee(()=>{n.value=me(t.value.outline??e.value.outline)});const h=g(()=>n.value.length===0),p=g(()=>h.value&&!s.value),b=g(()=>({VPLocalNav:!0,"has-sidebar":s.value,empty:h.value,fixed:p.value}));return(P,y)=>i(t).layout!=="home"&&(!p.value||i(r)>=u.value)?(a(),c("div",{key:0,class:N(b.value)},[v("div",Ss,[i(s)?(a(),c("button",{key:0,class:"menu","aria-expanded":P.open,"aria-controls":"VPSidebarNav",onClick:y[0]||(y[0]=L=>P.$emit("open-menu"))},[Is,v("span",Ts,w(i(e).sidebarMenuLabel||"Menu"),1)],8,ws)):f("",!0),m(Vs,{headers:i(n),navHeight:u.value},null,8,["headers","navHeight"])])],2)):f("",!0)}}),Ms=k(Ns,[["__scopeId","data-v-2488c25a"]]);function As(){const o=T(!1);function e(){o.value=!0,window.addEventListener("resize",n)}function t(){o.value=!1,window.removeEventListener("resize",n)}function s(){o.value?t():e()}function n(){window.outerWidth>=768&&t()}const r=te();return q(()=>r.path,t),{isScreenOpen:o,openScreen:e,closeScreen:t,toggleScreen:s}}const Cs={},Bs={class:"VPSwitch",type:"button",role:"switch"},Hs={class:"check"},Es={key:0,class:"icon"};function Fs(o,e){return a(),c("button",Bs,[v("span",Hs,[o.$slots.default?(a(),c("span",Es,[l(o.$slots,"default",{},void 0,!0)])):f("",!0)])])}const Ds=k(Cs,[["render",Fs],["__scopeId","data-v-b4ccac88"]]),Ce=o=>(B("data-v-7df97737"),o=o(),H(),o),Os=Ce(()=>v("span",{class:"vpi-sun sun"},null,-1)),Us=Ce(()=>v("span",{class:"vpi-moon moon"},null,-1)),Gs=_({__name:"VPSwitchAppearance",setup(o){const{isDark:e,theme:t}=V(),s=oe("toggle-appearance",()=>{e.value=!e.value}),n=g(()=>e.value?t.value.lightModeSwitchTitle||"Switch to light theme":t.value.darkModeSwitchTitle||"Switch to dark theme");return(r,u)=>(a(),$(Ds,{title:n.value,class:"VPSwitchAppearance","aria-checked":i(e),onClick:i(s)},{default:d(()=>[Os,Us]),_:1},8,["title","aria-checked","onClick"]))}}),ke=k(Gs,[["__scopeId","data-v-7df97737"]]),js={key:0,class:"VPNavBarAppearance"},zs=_({__name:"VPNavBarAppearance",setup(o){const{site:e}=V();return(t,s)=>i(e).appearance&&i(e).appearance!=="force-dark"?(a(),c("div",js,[m(ke)])):f("",!0)}}),qs=k(zs,[["__scopeId","data-v-283b26e9"]]),be=T();let Be=!1,re=0;function Ks(o){const e=T(!1);if(J){!Be&&Ws(),re++;const t=q(be,s=>{var n,r,u;s===o.el.value||(n=o.el.value)!=null&&n.contains(s)?(e.value=!0,(r=o.onFocus)==null||r.call(o)):(e.value=!1,(u=o.onBlur)==null||u.call(o))});he(()=>{t(),re--,re||Rs()})}return Je(e)}function Ws(){document.addEventListener("focusin",He),Be=!0,be.value=document.activeElement}function Rs(){document.removeEventListener("focusin",He)}function He(){be.value=document.activeElement}const Js={class:"VPMenuLink"},Ys=_({__name:"VPMenuLink",props:{item:{}},setup(o){const{page:e}=V();return(t,s)=>(a(),c("div",Js,[m(D,{class:N({active:i(j)(i(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,target:t.item.target,rel:t.item.rel},{default:d(()=>[F(w(t.item.text),1)]),_:1},8,["class","href","target","rel"])]))}}),se=k(Ys,[["__scopeId","data-v-f51f088d"]]),Qs={class:"VPMenuGroup"},Xs={key:0,class:"title"},Zs=_({__name:"VPMenuGroup",props:{text:{},items:{}},setup(o){return(e,t)=>(a(),c("div",Qs,[e.text?(a(),c("p",Xs,w(e.text),1)):f("",!0),(a(!0),c(M,null,E(e.items,s=>(a(),c(M,null,["link"in s?(a(),$(se,{key:0,item:s},null,8,["item"])):f("",!0)],64))),256))]))}}),xs=k(Zs,[["__scopeId","data-v-a6b0397c"]]),en={class:"VPMenu"},tn={key:0,class:"items"},on=_({__name:"VPMenu",props:{items:{}},setup(o){return(e,t)=>(a(),c("div",en,[e.items?(a(),c("div",tn,[(a(!0),c(M,null,E(e.items,s=>(a(),c(M,{key:s.text},["link"in s?(a(),$(se,{key:0,item:s},null,8,["item"])):(a(),$(xs,{key:1,text:s.text,items:s.items},null,8,["text","items"]))],64))),128))])):f("",!0),l(e.$slots,"default",{},void 0,!0)]))}}),sn=k(on,[["__scopeId","data-v-e42ed9b3"]]),nn=o=>(B("data-v-af5898d3"),o=o(),H(),o),an=["aria-expanded","aria-label"],rn={key:0,class:"text"},ln=["innerHTML"],cn=nn(()=>v("span",{class:"vpi-chevron-down text-icon"},null,-1)),un={key:1,class:"vpi-more-horizontal icon"},dn={class:"menu"},vn=_({__name:"VPFlyout",props:{icon:{},button:{},label:{},items:{}},setup(o){const e=T(!1),t=T();Ks({el:t,onBlur:s});function s(){e.value=!1}return(n,r)=>(a(),c("div",{class:"VPFlyout",ref_key:"el",ref:t,onMouseenter:r[1]||(r[1]=u=>e.value=!0),onMouseleave:r[2]||(r[2]=u=>e.value=!1)},[v("button",{type:"button",class:"button","aria-haspopup":"true","aria-expanded":e.value,"aria-label":n.label,onClick:r[0]||(r[0]=u=>e.value=!e.value)},[n.button||n.icon?(a(),c("span",rn,[n.icon?(a(),c("span",{key:0,class:N([n.icon,"option-icon"])},null,2)):f("",!0),n.button?(a(),c("span",{key:1,innerHTML:n.button},null,8,ln)):f("",!0),cn])):(a(),c("span",un))],8,an),v("div",dn,[m(sn,{items:n.items},{default:d(()=>[l(n.$slots,"default",{},void 0,!0)]),_:3},8,["items"])])],544))}}),$e=k(vn,[["__scopeId","data-v-af5898d3"]]),pn=["href","aria-label","innerHTML"],hn=_({__name:"VPSocialLink",props:{icon:{},link:{},ariaLabel:{}},setup(o){const e=o,t=g(()=>typeof e.icon=="object"?e.icon.svg:``);return(s,n)=>(a(),c("a",{class:"VPSocialLink no-icon",href:s.link,"aria-label":s.ariaLabel??(typeof s.icon=="string"?s.icon:""),target:"_blank",rel:"noopener",innerHTML:t.value},null,8,pn))}}),fn=k(hn,[["__scopeId","data-v-358b6670"]]),_n={class:"VPSocialLinks"},mn=_({__name:"VPSocialLinks",props:{links:{}},setup(o){return(e,t)=>(a(),c("div",_n,[(a(!0),c(M,null,E(e.links,({link:s,icon:n,ariaLabel:r})=>(a(),$(fn,{key:s,icon:n,link:s,ariaLabel:r},null,8,["icon","link","ariaLabel"]))),128))]))}}),ge=k(mn,[["__scopeId","data-v-e71e869c"]]),kn={key:0,class:"group translations"},bn={class:"trans-title"},$n={key:1,class:"group"},gn={class:"item appearance"},yn={class:"label"},Pn={class:"appearance-action"},Vn={key:2,class:"group"},Ln={class:"item social-links"},Sn=_({__name:"VPNavBarExtra",setup(o){const{site:e,theme:t}=V(),{localeLinks:s,currentLang:n}=Y({correspondingLink:!0}),r=g(()=>s.value.length&&n.value.label||e.value.appearance||t.value.socialLinks);return(u,h)=>r.value?(a(),$($e,{key:0,class:"VPNavBarExtra",label:"extra navigation"},{default:d(()=>[i(s).length&&i(n).label?(a(),c("div",kn,[v("p",bn,w(i(n).label),1),(a(!0),c(M,null,E(i(s),p=>(a(),$(se,{key:p.link,item:p},null,8,["item"]))),128))])):f("",!0),i(e).appearance&&i(e).appearance!=="force-dark"?(a(),c("div",$n,[v("div",gn,[v("p",yn,w(i(t).darkModeSwitchLabel||"Appearance"),1),v("div",Pn,[m(ke)])])])):f("",!0),i(t).socialLinks?(a(),c("div",Vn,[v("div",Ln,[m(ge,{class:"social-links-list",links:i(t).socialLinks},null,8,["links"])])])):f("",!0)]),_:1})):f("",!0)}}),wn=k(Sn,[["__scopeId","data-v-8e87c032"]]),In=o=>(B("data-v-6bee1efd"),o=o(),H(),o),Tn=["aria-expanded"],Nn=In(()=>v("span",{class:"container"},[v("span",{class:"top"}),v("span",{class:"middle"}),v("span",{class:"bottom"})],-1)),Mn=[Nn],An=_({__name:"VPNavBarHamburger",props:{active:{type:Boolean}},emits:["click"],setup(o){return(e,t)=>(a(),c("button",{type:"button",class:N(["VPNavBarHamburger",{active:e.active}]),"aria-label":"mobile navigation","aria-expanded":e.active,"aria-controls":"VPNavScreen",onClick:t[0]||(t[0]=s=>e.$emit("click"))},Mn,10,Tn))}}),Cn=k(An,[["__scopeId","data-v-6bee1efd"]]),Bn=["innerHTML"],Hn=_({__name:"VPNavBarMenuLink",props:{item:{}},setup(o){const{page:e}=V();return(t,s)=>(a(),$(D,{class:N({VPNavBarMenuLink:!0,active:i(j)(i(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,noIcon:t.item.noIcon,target:t.item.target,rel:t.item.rel,tabindex:"0"},{default:d(()=>[v("span",{innerHTML:t.item.text},null,8,Bn)]),_:1},8,["class","href","noIcon","target","rel"]))}}),En=k(Hn,[["__scopeId","data-v-08fbf4b6"]]),Fn=_({__name:"VPNavBarMenuGroup",props:{item:{}},setup(o){const e=o,{page:t}=V(),s=r=>"link"in r?j(t.value.relativePath,r.link,!!e.item.activeMatch):r.items.some(s),n=g(()=>s(e.item));return(r,u)=>(a(),$($e,{class:N({VPNavBarMenuGroup:!0,active:i(j)(i(t).relativePath,r.item.activeMatch,!!r.item.activeMatch)||n.value}),button:r.item.text,items:r.item.items},null,8,["class","button","items"]))}}),Dn=o=>(B("data-v-f732b5d0"),o=o(),H(),o),On={key:0,"aria-labelledby":"main-nav-aria-label",class:"VPNavBarMenu"},Un=Dn(()=>v("span",{id:"main-nav-aria-label",class:"visually-hidden"},"Main Navigation",-1)),Gn=_({__name:"VPNavBarMenu",setup(o){const{theme:e}=V();return(t,s)=>i(e).nav?(a(),c("nav",On,[Un,(a(!0),c(M,null,E(i(e).nav,n=>(a(),c(M,{key:n.text},["link"in n?(a(),$(En,{key:0,item:n},null,8,["item"])):(a(),$(Fn,{key:1,item:n},null,8,["item"]))],64))),128))])):f("",!0)}}),jn=k(Gn,[["__scopeId","data-v-f732b5d0"]]);function zn(o){const{localeIndex:e,theme:t}=V();function s(n){var A,C,S;const r=n.split("."),u=(A=t.value.search)==null?void 0:A.options,h=u&&typeof u=="object",p=h&&((S=(C=u.locales)==null?void 0:C[e.value])==null?void 0:S.translations)||null,b=h&&u.translations||null;let P=p,y=b,L=o;const I=r.pop();for(const U of r){let G=null;const W=L==null?void 0:L[U];W&&(G=L=W);const ne=y==null?void 0:y[U];ne&&(G=y=ne);const ae=P==null?void 0:P[U];ae&&(G=P=ae),W||(L=G),ne||(y=G),ae||(P=G)}return(P==null?void 0:P[I])??(y==null?void 0:y[I])??(L==null?void 0:L[I])??""}return s}const qn=["aria-label"],Kn={class:"DocSearch-Button-Container"},Wn=v("span",{class:"vp-icon DocSearch-Search-Icon"},null,-1),Rn={class:"DocSearch-Button-Placeholder"},Jn=v("span",{class:"DocSearch-Button-Keys"},[v("kbd",{class:"DocSearch-Button-Key"}),v("kbd",{class:"DocSearch-Button-Key"},"K")],-1),ye=_({__name:"VPNavBarSearchButton",setup(o){const t=zn({button:{buttonText:"Search",buttonAriaLabel:"Search"}});return(s,n)=>(a(),c("button",{type:"button",class:"DocSearch DocSearch-Button","aria-label":i(t)("button.buttonAriaLabel")},[v("span",Kn,[Wn,v("span",Rn,w(i(t)("button.buttonText")),1)]),Jn],8,qn))}}),Yn={class:"VPNavBarSearch"},Qn={id:"local-search"},Xn={key:1,id:"docsearch"},Zn=_({__name:"VPNavBarSearch",setup(o){const e=Ye(()=>Qe(()=>import("./VPLocalSearchBox.De8VqG1H.js"),__vite__mapDeps([0,1]))),t=()=>null,{theme:s}=V(),n=T(!1),r=T(!1);z(()=>{});function u(){n.value||(n.value=!0,setTimeout(h,16))}function h(){const y=new Event("keydown");y.key="k",y.metaKey=!0,window.dispatchEvent(y),setTimeout(()=>{document.querySelector(".DocSearch-Modal")||h()},16)}function p(y){const L=y.target,I=L.tagName;return L.isContentEditable||I==="INPUT"||I==="SELECT"||I==="TEXTAREA"}const b=T(!1);le("k",y=>{(y.ctrlKey||y.metaKey)&&(y.preventDefault(),b.value=!0)}),le("/",y=>{p(y)||(y.preventDefault(),b.value=!0)});const P="local";return(y,L)=>{var I;return a(),c("div",Yn,[i(P)==="local"?(a(),c(M,{key:0},[b.value?(a(),$(i(e),{key:0,onClose:L[0]||(L[0]=A=>b.value=!1)})):f("",!0),v("div",Qn,[m(ye,{onClick:L[1]||(L[1]=A=>b.value=!0)})])],64)):i(P)==="algolia"?(a(),c(M,{key:1},[n.value?(a(),$(i(t),{key:0,algolia:((I=i(s).search)==null?void 0:I.options)??i(s).algolia,onVnodeBeforeMount:L[2]||(L[2]=A=>r.value=!0)},null,8,["algolia"])):f("",!0),r.value?f("",!0):(a(),c("div",Xn,[m(ye,{onClick:u})]))],64)):f("",!0)])}}}),xn=_({__name:"VPNavBarSocialLinks",setup(o){const{theme:e}=V();return(t,s)=>i(e).socialLinks?(a(),$(ge,{key:0,class:"VPNavBarSocialLinks",links:i(e).socialLinks},null,8,["links"])):f("",!0)}}),ea=k(xn,[["__scopeId","data-v-ef6192dc"]]),ta=["href","rel","target"],oa={key:1},sa={key:2},na=_({__name:"VPNavBarTitle",setup(o){const{site:e,theme:t}=V(),{hasSidebar:s}=O(),{currentLang:n}=Y(),r=g(()=>{var p;return typeof t.value.logoLink=="string"?t.value.logoLink:(p=t.value.logoLink)==null?void 0:p.link}),u=g(()=>{var p;return typeof t.value.logoLink=="string"||(p=t.value.logoLink)==null?void 0:p.rel}),h=g(()=>{var p;return typeof t.value.logoLink=="string"||(p=t.value.logoLink)==null?void 0:p.target});return(p,b)=>(a(),c("div",{class:N(["VPNavBarTitle",{"has-sidebar":i(s)}])},[v("a",{class:"title",href:r.value??i(fe)(i(n).link),rel:u.value,target:h.value},[l(p.$slots,"nav-bar-title-before",{},void 0,!0),i(t).logo?(a(),$(Z,{key:0,class:"logo",image:i(t).logo},null,8,["image"])):f("",!0),i(t).siteTitle?(a(),c("span",oa,w(i(t).siteTitle),1)):i(t).siteTitle===void 0?(a(),c("span",sa,w(i(e).title),1)):f("",!0),l(p.$slots,"nav-bar-title-after",{},void 0,!0)],8,ta)],2))}}),aa=k(na,[["__scopeId","data-v-0ad69264"]]),ra={class:"items"},ia={class:"title"},la=_({__name:"VPNavBarTranslations",setup(o){const{theme:e}=V(),{localeLinks:t,currentLang:s}=Y({correspondingLink:!0});return(n,r)=>i(t).length&&i(s).label?(a(),$($e,{key:0,class:"VPNavBarTranslations",icon:"vpi-languages",label:i(e).langMenuLabel||"Change language"},{default:d(()=>[v("div",ra,[v("p",ia,w(i(s).label),1),(a(!0),c(M,null,E(i(t),u=>(a(),$(se,{key:u.link,item:u},null,8,["item"]))),128))])]),_:1},8,["label"])):f("",!0)}}),ca=k(la,[["__scopeId","data-v-acee064b"]]),ua=o=>(B("data-v-844edcde"),o=o(),H(),o),da={class:"wrapper"},va={class:"container"},pa={class:"title"},ha={class:"content"},fa={class:"content-body"},_a=ua(()=>v("div",{class:"divider"},[v("div",{class:"divider-line"})],-1)),ma=_({__name:"VPNavBar",props:{isScreenOpen:{type:Boolean}},emits:["toggle-screen"],setup(o){const{y:e}=we(),{hasSidebar:t}=O(),{frontmatter:s}=V(),n=T({});return Pe(()=>{n.value={"has-sidebar":t.value,home:s.value.layout==="home",top:e.value===0}}),(r,u)=>(a(),c("div",{class:N(["VPNavBar",n.value])},[v("div",da,[v("div",va,[v("div",pa,[m(aa,null,{"nav-bar-title-before":d(()=>[l(r.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":d(()=>[l(r.$slots,"nav-bar-title-after",{},void 0,!0)]),_:3})]),v("div",ha,[v("div",fa,[l(r.$slots,"nav-bar-content-before",{},void 0,!0),m(Zn,{class:"search"}),m(jn,{class:"menu"}),m(ca,{class:"translations"}),m(qs,{class:"appearance"}),m(ea,{class:"social-links"}),m(wn,{class:"extra"}),l(r.$slots,"nav-bar-content-after",{},void 0,!0),m(Cn,{class:"hamburger",active:r.isScreenOpen,onClick:u[0]||(u[0]=h=>r.$emit("toggle-screen"))},null,8,["active"])])])])]),_a],2))}}),ka=k(ma,[["__scopeId","data-v-844edcde"]]),ba={key:0,class:"VPNavScreenAppearance"},$a={class:"text"},ga=_({__name:"VPNavScreenAppearance",setup(o){const{site:e,theme:t}=V();return(s,n)=>i(e).appearance&&i(e).appearance!=="force-dark"?(a(),c("div",ba,[v("p",$a,w(i(t).darkModeSwitchLabel||"Appearance"),1),m(ke)])):f("",!0)}}),ya=k(ga,[["__scopeId","data-v-338d9b48"]]),Pa=_({__name:"VPNavScreenMenuLink",props:{item:{}},setup(o){const e=oe("close-screen");return(t,s)=>(a(),$(D,{class:"VPNavScreenMenuLink",href:t.item.link,target:t.item.target,rel:t.item.rel,onClick:i(e)},{default:d(()=>[F(w(t.item.text),1)]),_:1},8,["href","target","rel","onClick"]))}}),Va=k(Pa,[["__scopeId","data-v-fe523e3d"]]),La=_({__name:"VPNavScreenMenuGroupLink",props:{item:{}},setup(o){const e=oe("close-screen");return(t,s)=>(a(),$(D,{class:"VPNavScreenMenuGroupLink",href:t.item.link,target:t.item.target,rel:t.item.rel,onClick:i(e)},{default:d(()=>[F(w(t.item.text),1)]),_:1},8,["href","target","rel","onClick"]))}}),Ee=k(La,[["__scopeId","data-v-aea78dd1"]]),Sa={class:"VPNavScreenMenuGroupSection"},wa={key:0,class:"title"},Ia=_({__name:"VPNavScreenMenuGroupSection",props:{text:{},items:{}},setup(o){return(e,t)=>(a(),c("div",Sa,[e.text?(a(),c("p",wa,w(e.text),1)):f("",!0),(a(!0),c(M,null,E(e.items,s=>(a(),$(Ee,{key:s.text,item:s},null,8,["item"]))),128))]))}}),Ta=k(Ia,[["__scopeId","data-v-f60dbfa7"]]),Na=o=>(B("data-v-d2212c70"),o=o(),H(),o),Ma=["aria-controls","aria-expanded"],Aa=["innerHTML"],Ca=Na(()=>v("span",{class:"vpi-plus button-icon"},null,-1)),Ba=["id"],Ha={key:1,class:"group"},Ea=_({__name:"VPNavScreenMenuGroup",props:{text:{},items:{}},setup(o){const e=o,t=T(!1),s=g(()=>`NavScreenGroup-${e.text.replace(" ","-").toLowerCase()}`);function n(){t.value=!t.value}return(r,u)=>(a(),c("div",{class:N(["VPNavScreenMenuGroup",{open:t.value}])},[v("button",{class:"button","aria-controls":s.value,"aria-expanded":t.value,onClick:n},[v("span",{class:"button-text",innerHTML:r.text},null,8,Aa),Ca],8,Ma),v("div",{id:s.value,class:"items"},[(a(!0),c(M,null,E(r.items,h=>(a(),c(M,{key:h.text},["link"in h?(a(),c("div",{key:h.text,class:"item"},[m(Ee,{item:h},null,8,["item"])])):(a(),c("div",Ha,[m(Ta,{text:h.text,items:h.items},null,8,["text","items"])]))],64))),128))],8,Ba)],2))}}),Fa=k(Ea,[["__scopeId","data-v-d2212c70"]]),Da={key:0,class:"VPNavScreenMenu"},Oa=_({__name:"VPNavScreenMenu",setup(o){const{theme:e}=V();return(t,s)=>i(e).nav?(a(),c("nav",Da,[(a(!0),c(M,null,E(i(e).nav,n=>(a(),c(M,{key:n.text},["link"in n?(a(),$(Va,{key:0,item:n},null,8,["item"])):(a(),$(Fa,{key:1,text:n.text||"",items:n.items},null,8,["text","items"]))],64))),128))])):f("",!0)}}),Ua=_({__name:"VPNavScreenSocialLinks",setup(o){const{theme:e}=V();return(t,s)=>i(e).socialLinks?(a(),$(ge,{key:0,class:"VPNavScreenSocialLinks",links:i(e).socialLinks},null,8,["links"])):f("",!0)}}),Fe=o=>(B("data-v-516e4bc3"),o=o(),H(),o),Ga=Fe(()=>v("span",{class:"vpi-languages icon lang"},null,-1)),ja=Fe(()=>v("span",{class:"vpi-chevron-down icon chevron"},null,-1)),za={class:"list"},qa=_({__name:"VPNavScreenTranslations",setup(o){const{localeLinks:e,currentLang:t}=Y({correspondingLink:!0}),s=T(!1);function n(){s.value=!s.value}return(r,u)=>i(e).length&&i(t).label?(a(),c("div",{key:0,class:N(["VPNavScreenTranslations",{open:s.value}])},[v("button",{class:"title",onClick:n},[Ga,F(" "+w(i(t).label)+" ",1),ja]),v("ul",za,[(a(!0),c(M,null,E(i(e),h=>(a(),c("li",{key:h.link,class:"item"},[m(D,{class:"link",href:h.link},{default:d(()=>[F(w(h.text),1)]),_:2},1032,["href"])]))),128))])],2)):f("",!0)}}),Ka=k(qa,[["__scopeId","data-v-516e4bc3"]]),Wa={class:"container"},Ra=_({__name:"VPNavScreen",props:{open:{type:Boolean}},setup(o){const e=T(null),t=Ie(J?document.body:null);return(s,n)=>(a(),$(ve,{name:"fade",onEnter:n[0]||(n[0]=r=>t.value=!0),onAfterLeave:n[1]||(n[1]=r=>t.value=!1)},{default:d(()=>[s.open?(a(),c("div",{key:0,class:"VPNavScreen",ref_key:"screen",ref:e,id:"VPNavScreen"},[v("div",Wa,[l(s.$slots,"nav-screen-content-before",{},void 0,!0),m(Oa,{class:"menu"}),m(Ka,{class:"translations"}),m(ya,{class:"appearance"}),m(Ua,{class:"social-links"}),l(s.$slots,"nav-screen-content-after",{},void 0,!0)])],512)):f("",!0)]),_:3}))}}),Ja=k(Ra,[["__scopeId","data-v-57cce842"]]),Ya={key:0,class:"VPNav"},Qa=_({__name:"VPNav",setup(o){const{isScreenOpen:e,closeScreen:t,toggleScreen:s}=As(),{frontmatter:n}=V(),r=g(()=>n.value.navbar!==!1);return Te("close-screen",t),x(()=>{J&&document.documentElement.classList.toggle("hide-nav",!r.value)}),(u,h)=>r.value?(a(),c("header",Ya,[m(ka,{"is-screen-open":i(e),onToggleScreen:i(s)},{"nav-bar-title-before":d(()=>[l(u.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":d(()=>[l(u.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":d(()=>[l(u.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":d(()=>[l(u.$slots,"nav-bar-content-after",{},void 0,!0)]),_:3},8,["is-screen-open","onToggleScreen"]),m(Ja,{open:i(e)},{"nav-screen-content-before":d(()=>[l(u.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":d(()=>[l(u.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3},8,["open"])])):f("",!0)}}),Xa=k(Qa,[["__scopeId","data-v-7ad780c2"]]),De=o=>(B("data-v-c24f735a"),o=o(),H(),o),Za=["role","tabindex"],xa=De(()=>v("div",{class:"indicator"},null,-1)),er=De(()=>v("span",{class:"vpi-chevron-right caret-icon"},null,-1)),tr=[er],or={key:1,class:"items"},sr=_({__name:"VPSidebarItem",props:{item:{},depth:{}},setup(o){const e=o,{collapsed:t,collapsible:s,isLink:n,isActiveLink:r,hasActiveLink:u,hasChildren:h,toggle:p}=$t(g(()=>e.item)),b=g(()=>h.value?"section":"div"),P=g(()=>n.value?"a":"div"),y=g(()=>h.value?e.depth+2===7?"p":`h${e.depth+2}`:"p"),L=g(()=>n.value?void 0:"button"),I=g(()=>[[`level-${e.depth}`],{collapsible:s.value},{collapsed:t.value},{"is-link":n.value},{"is-active":r.value},{"has-active":u.value}]);function A(S){"key"in S&&S.key!=="Enter"||!e.item.link&&p()}function C(){e.item.link&&p()}return(S,U)=>{const G=K("VPSidebarItem",!0);return a(),$(R(b.value),{class:N(["VPSidebarItem",I.value])},{default:d(()=>[S.item.text?(a(),c("div",Q({key:0,class:"item",role:L.value},Ze(S.item.items?{click:A,keydown:A}:{},!0),{tabindex:S.item.items&&0}),[xa,S.item.link?(a(),$(D,{key:0,tag:P.value,class:"link",href:S.item.link,rel:S.item.rel,target:S.item.target},{default:d(()=>[(a(),$(R(y.value),{class:"text",innerHTML:S.item.text},null,8,["innerHTML"]))]),_:1},8,["tag","href","rel","target"])):(a(),$(R(y.value),{key:1,class:"text",innerHTML:S.item.text},null,8,["innerHTML"])),S.item.collapsed!=null&&S.item.items&&S.item.items.length?(a(),c("div",{key:2,class:"caret",role:"button","aria-label":"toggle section",onClick:C,onKeydown:Xe(C,["enter"]),tabindex:"0"},tr,32)):f("",!0)],16,Za)):f("",!0),S.item.items&&S.item.items.length?(a(),c("div",or,[S.depth<5?(a(!0),c(M,{key:0},E(S.item.items,W=>(a(),$(G,{key:W.text,item:W,depth:S.depth+1},null,8,["item","depth"]))),128)):f("",!0)])):f("",!0)]),_:1},8,["class"])}}}),nr=k(sr,[["__scopeId","data-v-c24f735a"]]),Oe=o=>(B("data-v-4871f9f5"),o=o(),H(),o),ar=Oe(()=>v("div",{class:"curtain"},null,-1)),rr={class:"nav",id:"VPSidebarNav","aria-labelledby":"sidebar-aria-label",tabindex:"-1"},ir=Oe(()=>v("span",{class:"visually-hidden",id:"sidebar-aria-label"}," Sidebar Navigation ",-1)),lr=_({__name:"VPSidebar",props:{open:{type:Boolean}},setup(o){const{sidebarGroups:e,hasSidebar:t}=O(),s=o,n=T(null),r=Ie(J?document.body:null);return q([s,n],()=>{var u;s.open?(r.value=!0,(u=n.value)==null||u.focus()):r.value=!1},{immediate:!0,flush:"post"}),(u,h)=>i(t)?(a(),c("aside",{key:0,class:N(["VPSidebar",{open:u.open}]),ref_key:"navEl",ref:n,onClick:h[0]||(h[0]=xe(()=>{},["stop"]))},[ar,v("nav",rr,[ir,l(u.$slots,"sidebar-nav-before",{},void 0,!0),(a(!0),c(M,null,E(i(e),p=>(a(),c("div",{key:p.text,class:"group"},[m(nr,{item:p,depth:0},null,8,["item"])]))),128)),l(u.$slots,"sidebar-nav-after",{},void 0,!0)])],2)):f("",!0)}}),cr=k(lr,[["__scopeId","data-v-4871f9f5"]]),ur=_({__name:"VPSkipLink",setup(o){const e=te(),t=T();q(()=>e.path,()=>t.value.focus());function s({target:n}){const r=document.getElementById(decodeURIComponent(n.hash).slice(1));if(r){const u=()=>{r.removeAttribute("tabindex"),r.removeEventListener("blur",u)};r.setAttribute("tabindex","-1"),r.addEventListener("blur",u),r.focus(),window.scrollTo(0,0)}}return(n,r)=>(a(),c(M,null,[v("span",{ref_key:"backToTop",ref:t,tabindex:"-1"},null,512),v("a",{href:"#VPContent",class:"VPSkipLink visually-hidden",onClick:s}," Skip to content ")],64))}}),dr=k(ur,[["__scopeId","data-v-c8291ffa"]]),vr=_({__name:"Layout",setup(o){const{isOpen:e,open:t,close:s}=O(),n=te();q(()=>n.path,s),bt(e,s);const{frontmatter:r}=V(),u=et(),h=g(()=>!!u["home-hero-image"]);return Te("hero-image-slot-exists",h),(p,b)=>{const P=K("Content");return i(r).layout!==!1?(a(),c("div",{key:0,class:N(["Layout",i(r).pageClass])},[l(p.$slots,"layout-top",{},void 0,!0),m(dr),m(nt,{class:"backdrop",show:i(e),onClick:i(s)},null,8,["show","onClick"]),m(Xa,null,{"nav-bar-title-before":d(()=>[l(p.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":d(()=>[l(p.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":d(()=>[l(p.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":d(()=>[l(p.$slots,"nav-bar-content-after",{},void 0,!0)]),"nav-screen-content-before":d(()=>[l(p.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":d(()=>[l(p.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3}),m(Ms,{open:i(e),onOpenMenu:i(t)},null,8,["open","onOpenMenu"]),m(cr,{open:i(e)},{"sidebar-nav-before":d(()=>[l(p.$slots,"sidebar-nav-before",{},void 0,!0)]),"sidebar-nav-after":d(()=>[l(p.$slots,"sidebar-nav-after",{},void 0,!0)]),_:3},8,["open"]),m(vs,null,{"page-top":d(()=>[l(p.$slots,"page-top",{},void 0,!0)]),"page-bottom":d(()=>[l(p.$slots,"page-bottom",{},void 0,!0)]),"not-found":d(()=>[l(p.$slots,"not-found",{},void 0,!0)]),"home-hero-before":d(()=>[l(p.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":d(()=>[l(p.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":d(()=>[l(p.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":d(()=>[l(p.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":d(()=>[l(p.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":d(()=>[l(p.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":d(()=>[l(p.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":d(()=>[l(p.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":d(()=>[l(p.$slots,"home-features-after",{},void 0,!0)]),"doc-footer-before":d(()=>[l(p.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":d(()=>[l(p.$slots,"doc-before",{},void 0,!0)]),"doc-after":d(()=>[l(p.$slots,"doc-after",{},void 0,!0)]),"doc-top":d(()=>[l(p.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":d(()=>[l(p.$slots,"doc-bottom",{},void 0,!0)]),"aside-top":d(()=>[l(p.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":d(()=>[l(p.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":d(()=>[l(p.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":d(()=>[l(p.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":d(()=>[l(p.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":d(()=>[l(p.$slots,"aside-ads-after",{},void 0,!0)]),_:3}),m(ms),l(p.$slots,"layout-bottom",{},void 0,!0)],2)):(a(),$(P,{key:1}))}}}),pr=k(vr,[["__scopeId","data-v-d8b57b2d"]]),fr={Layout:pr,enhanceApp:({app:o})=>{o.component("Badge",tt)}};export{zn as c,fr as t,V as u}; +import{d as _,o as a,c,r as l,n as N,a as F,t as w,b as $,w as d,T as ve,e as f,_ as k,u as Ue,i as Ge,f as je,g as pe,h as T,j as J,k as g,l as z,m as v,p as i,q as B,s as H,v as j,x as ie,y as q,z as x,A as he,B as Pe,C as ze,D as qe,E as K,F as M,G as E,H as Ve,I as ee,J as m,K as R,L as Le,M as te,N as Q,O as oe,P as Ke,Q as Se,R as We,S as le,U as Re,V as we,W as Je,X as Ye,Y as Qe,Z as Ie,$ as Te,a0 as Xe,a1 as Ze,a2 as xe,a3 as et}from"./framework.DZjeu1b3.js";const tt=_({__name:"VPBadge",props:{text:{},type:{default:"tip"}},setup(o){return(e,t)=>(a(),c("span",{class:N(["VPBadge",e.type])},[l(e.$slots,"default",{},()=>[F(w(e.text),1)])],2))}}),ot={key:0,class:"VPBackdrop"},st=_({__name:"VPBackdrop",props:{show:{type:Boolean}},setup(o){return(e,t)=>(a(),$(ve,{name:"fade"},{default:d(()=>[e.show?(a(),c("div",ot)):f("",!0)]),_:1}))}}),nt=k(st,[["__scopeId","data-v-54a304ca"]]),V=Ue;function at(o,e){let t,s=!1;return()=>{t&&clearTimeout(t),s?t=setTimeout(o,e):(o(),(s=!0)&&setTimeout(()=>s=!1,e))}}function ce(o){return/^\//.test(o)?o:`/${o}`}function fe(o){const{pathname:e,search:t,hash:s,protocol:n}=new URL(o,"http://a.com");if(Ge(o)||o.startsWith("#")||!n.startsWith("http")||!je(e))return o;const{site:r}=V(),u=e.endsWith("/")||e.endsWith(".html")?o:o.replace(/(?:(^\.+)\/)?.*$/,`$1${e.replace(/(\.md)?$/,r.value.cleanUrls?"":".html")}${t}${s}`);return pe(u)}const _e=T(J?location.hash:"");J&&window.addEventListener("hashchange",()=>{_e.value=location.hash});function Y({removeCurrent:o=!0,correspondingLink:e=!1}={}){const{site:t,localeIndex:s,page:n,theme:r}=V(),u=g(()=>{var p,b;return{label:(p=t.value.locales[s.value])==null?void 0:p.label,link:((b=t.value.locales[s.value])==null?void 0:b.link)||(s.value==="root"?"/":`/${s.value}/`)}});return{localeLinks:g(()=>Object.entries(t.value.locales).flatMap(([p,b])=>o&&u.value.label===b.label?[]:{text:b.label,link:rt(b.link||(p==="root"?"/":`/${p}/`),r.value.i18nRouting!==!1&&e,n.value.relativePath.slice(u.value.link.length-1),!t.value.cleanUrls)+_e.value})),currentLang:u}}function rt(o,e,t,s){return e?o.replace(/\/$/,"")+ce(t.replace(/(^|\/)index\.md$/,"$1").replace(/\.md$/,s?".html":"")):o}const it=o=>(B("data-v-b9c0c15a"),o=o(),H(),o),lt={class:"NotFound"},ct={class:"code"},ut={class:"title"},dt=it(()=>v("div",{class:"divider"},null,-1)),vt={class:"quote"},pt={class:"action"},ht=["href","aria-label"],ft=_({__name:"NotFound",setup(o){const{site:e,theme:t}=V(),{localeLinks:s}=Y({removeCurrent:!1}),n=T("/");return z(()=>{var u;const r=window.location.pathname.replace(e.value.base,"").replace(/(^.*?\/).*$/,"/$1");s.value.length&&(n.value=((u=s.value.find(({link:h})=>h.startsWith(r)))==null?void 0:u.link)||s.value[0].link)}),(r,u)=>{var h,p,b,P,y;return a(),c("div",lt,[v("p",ct,w(((h=i(t).notFound)==null?void 0:h.code)??"404"),1),v("h1",ut,w(((p=i(t).notFound)==null?void 0:p.title)??"PAGE NOT FOUND"),1),dt,v("blockquote",vt,w(((b=i(t).notFound)==null?void 0:b.quote)??"But if you don't change your direction, and if you keep looking, you may end up where you are heading."),1),v("div",pt,[v("a",{class:"link",href:i(pe)(n.value),"aria-label":((P=i(t).notFound)==null?void 0:P.linkLabel)??"go to home"},w(((y=i(t).notFound)==null?void 0:y.linkText)??"Take me home"),9,ht)])])}}}),_t=k(ft,[["__scopeId","data-v-b9c0c15a"]]);function Ne(o,e){if(Array.isArray(o))return X(o);if(o==null)return[];e=ce(e);const t=Object.keys(o).sort((n,r)=>r.split("/").length-n.split("/").length).find(n=>e.startsWith(ce(n))),s=t?o[t]:[];return Array.isArray(s)?X(s):X(s.items,s.base)}function mt(o){const e=[];let t=0;for(const s in o){const n=o[s];if(n.items){t=e.push(n);continue}e[t]||e.push({items:[]}),e[t].items.push(n)}return e}function kt(o){const e=[];function t(s){for(const n of s)n.text&&n.link&&e.push({text:n.text,link:n.link,docFooterText:n.docFooterText}),n.items&&t(n.items)}return t(o),e}function ue(o,e){return Array.isArray(e)?e.some(t=>ue(o,t)):j(o,e.link)?!0:e.items?ue(o,e.items):!1}function X(o,e){return[...o].map(t=>{const s={...t},n=s.base||e;return n&&s.link&&(s.link=n+s.link),s.items&&(s.items=X(s.items,n)),s})}function O(){const{frontmatter:o,page:e,theme:t}=V(),s=ie("(min-width: 960px)"),n=T(!1),r=g(()=>{const C=t.value.sidebar,S=e.value.relativePath;return C?Ne(C,S):[]}),u=T(r.value);q(r,(C,S)=>{JSON.stringify(C)!==JSON.stringify(S)&&(u.value=r.value)});const h=g(()=>o.value.sidebar!==!1&&u.value.length>0&&o.value.layout!=="home"),p=g(()=>b?o.value.aside==null?t.value.aside==="left":o.value.aside==="left":!1),b=g(()=>o.value.layout==="home"?!1:o.value.aside!=null?!!o.value.aside:t.value.aside!==!1),P=g(()=>h.value&&s.value),y=g(()=>h.value?mt(u.value):[]);function L(){n.value=!0}function I(){n.value=!1}function A(){n.value?I():L()}return{isOpen:n,sidebar:u,sidebarGroups:y,hasSidebar:h,hasAside:b,leftAside:p,isSidebarEnabled:P,open:L,close:I,toggle:A}}function bt(o,e){let t;x(()=>{t=o.value?document.activeElement:void 0}),z(()=>{window.addEventListener("keyup",s)}),he(()=>{window.removeEventListener("keyup",s)});function s(n){n.key==="Escape"&&o.value&&(e(),t==null||t.focus())}}function $t(o){const{page:e}=V(),t=T(!1),s=g(()=>o.value.collapsed!=null),n=g(()=>!!o.value.link),r=T(!1),u=()=>{r.value=j(e.value.relativePath,o.value.link)};q([e,o,_e],u),z(u);const h=g(()=>r.value?!0:o.value.items?ue(e.value.relativePath,o.value.items):!1),p=g(()=>!!(o.value.items&&o.value.items.length));x(()=>{t.value=!!(s.value&&o.value.collapsed)}),Pe(()=>{(r.value||h.value)&&(t.value=!1)});function b(){s.value&&(t.value=!t.value)}return{collapsed:t,collapsible:s,isLink:n,isActiveLink:r,hasActiveLink:h,hasChildren:p,toggle:b}}function gt(){const{hasSidebar:o}=O(),e=ie("(min-width: 960px)"),t=ie("(min-width: 1280px)");return{isAsideEnabled:g(()=>!t.value&&!e.value?!1:o.value?t.value:e.value)}}const de=[];function Me(o){return typeof o.outline=="object"&&!Array.isArray(o.outline)&&o.outline.label||o.outlineTitle||"On this page"}function me(o){const e=[...document.querySelectorAll(".VPDoc :where(h1,h2,h3,h4,h5,h6)")].filter(t=>t.id&&t.hasChildNodes()).map(t=>{const s=Number(t.tagName[1]);return{element:t,title:yt(t),link:"#"+t.id,level:s}});return Pt(e,o)}function yt(o){let e="";for(const t of o.childNodes)if(t.nodeType===1){if(t.classList.contains("VPBadge")||t.classList.contains("header-anchor")||t.classList.contains("ignore-header"))continue;e+=t.textContent}else t.nodeType===3&&(e+=t.textContent);return e.trim()}function Pt(o,e){if(e===!1)return[];const t=(typeof e=="object"&&!Array.isArray(e)?e.level:e)||2,[s,n]=typeof t=="number"?[t,t]:t==="deep"?[2,6]:t;o=o.filter(u=>u.level>=s&&u.level<=n),de.length=0;for(const{element:u,link:h}of o)de.push({element:u,link:h});const r=[];e:for(let u=0;u=0;p--){const b=o[p];if(b.level{requestAnimationFrame(r),window.addEventListener("scroll",s)}),ze(()=>{u(location.hash)}),he(()=>{window.removeEventListener("scroll",s)});function r(){if(!t.value)return;const h=window.scrollY,p=window.innerHeight,b=document.body.offsetHeight,P=Math.abs(h+p-b)<1,y=de.map(({element:I,link:A})=>({link:A,top:Lt(I)})).filter(({top:I})=>!Number.isNaN(I)).sort((I,A)=>I.top-A.top);if(!y.length){u(null);return}if(h<1){u(null);return}if(P){u(y[y.length-1].link);return}let L=null;for(const{link:I,top:A}of y){if(A>h+qe()+4)break;L=I}u(L)}function u(h){n&&n.classList.remove("active"),h==null?n=null:n=o.value.querySelector(`a[href="${decodeURIComponent(h)}"]`);const p=n;p?(p.classList.add("active"),e.value.style.top=p.offsetTop+39+"px",e.value.style.opacity="1"):(e.value.style.top="33px",e.value.style.opacity="0")}}function Lt(o){let e=0;for(;o!==document.body;){if(o===null)return NaN;e+=o.offsetTop,o=o.offsetParent}return e}const St=["href","title"],wt=_({__name:"VPDocOutlineItem",props:{headers:{},root:{type:Boolean}},setup(o){function e({target:t}){const s=t.href.split("#")[1],n=document.getElementById(decodeURIComponent(s));n==null||n.focus({preventScroll:!0})}return(t,s)=>{const n=K("VPDocOutlineItem",!0);return a(),c("ul",{class:N(["VPDocOutlineItem",t.root?"root":"nested"])},[(a(!0),c(M,null,E(t.headers,({children:r,link:u,title:h})=>(a(),c("li",null,[v("a",{class:"outline-link",href:u,onClick:e,title:h},w(h),9,St),r!=null&&r.length?(a(),$(n,{key:0,headers:r},null,8,["headers"])):f("",!0)]))),256))],2)}}}),Ae=k(wt,[["__scopeId","data-v-53c99d69"]]),It=o=>(B("data-v-6b52fe58"),o=o(),H(),o),Tt={class:"content"},Nt={class:"outline-title",role:"heading","aria-level":"2"},Mt={"aria-labelledby":"doc-outline-aria-label"},At=It(()=>v("span",{class:"visually-hidden",id:"doc-outline-aria-label"}," Table of Contents for current page ",-1)),Ct=_({__name:"VPDocAsideOutline",setup(o){const{frontmatter:e,theme:t}=V(),s=Ve([]);ee(()=>{s.value=me(e.value.outline??t.value.outline)});const n=T(),r=T();return Vt(n,r),(u,h)=>(a(),c("div",{class:N(["VPDocAsideOutline",{"has-outline":s.value.length>0}]),ref_key:"container",ref:n,role:"navigation"},[v("div",Tt,[v("div",{class:"outline-marker",ref_key:"marker",ref:r},null,512),v("div",Nt,w(i(Me)(i(t))),1),v("nav",Mt,[At,m(Ae,{headers:s.value,root:!0},null,8,["headers"])])])],2))}}),Bt=k(Ct,[["__scopeId","data-v-6b52fe58"]]),Ht={class:"VPDocAsideCarbonAds"},Et=_({__name:"VPDocAsideCarbonAds",props:{carbonAds:{}},setup(o){const e=()=>null;return(t,s)=>(a(),c("div",Ht,[m(i(e),{"carbon-ads":t.carbonAds},null,8,["carbon-ads"])]))}}),Ft=o=>(B("data-v-cb998dce"),o=o(),H(),o),Dt={class:"VPDocAside"},Ot=Ft(()=>v("div",{class:"spacer"},null,-1)),Ut=_({__name:"VPDocAside",setup(o){const{theme:e}=V();return(t,s)=>(a(),c("div",Dt,[l(t.$slots,"aside-top",{},void 0,!0),l(t.$slots,"aside-outline-before",{},void 0,!0),m(Bt),l(t.$slots,"aside-outline-after",{},void 0,!0),Ot,l(t.$slots,"aside-ads-before",{},void 0,!0),i(e).carbonAds?(a(),$(Et,{key:0,"carbon-ads":i(e).carbonAds},null,8,["carbon-ads"])):f("",!0),l(t.$slots,"aside-ads-after",{},void 0,!0),l(t.$slots,"aside-bottom",{},void 0,!0)]))}}),Gt=k(Ut,[["__scopeId","data-v-cb998dce"]]);function jt(){const{theme:o,page:e}=V();return g(()=>{const{text:t="Edit this page",pattern:s=""}=o.value.editLink||{};let n;return typeof s=="function"?n=s(e.value):n=s.replace(/:path/g,e.value.filePath),{url:n,text:t}})}function zt(){const{page:o,theme:e,frontmatter:t}=V();return g(()=>{var b,P,y,L,I,A,C,S;const s=Ne(e.value.sidebar,o.value.relativePath),n=kt(s),r=qt(n,U=>U.link.replace(/[?#].*$/,"")),u=r.findIndex(U=>j(o.value.relativePath,U.link)),h=((b=e.value.docFooter)==null?void 0:b.prev)===!1&&!t.value.prev||t.value.prev===!1,p=((P=e.value.docFooter)==null?void 0:P.next)===!1&&!t.value.next||t.value.next===!1;return{prev:h?void 0:{text:(typeof t.value.prev=="string"?t.value.prev:typeof t.value.prev=="object"?t.value.prev.text:void 0)??((y=r[u-1])==null?void 0:y.docFooterText)??((L=r[u-1])==null?void 0:L.text),link:(typeof t.value.prev=="object"?t.value.prev.link:void 0)??((I=r[u-1])==null?void 0:I.link)},next:p?void 0:{text:(typeof t.value.next=="string"?t.value.next:typeof t.value.next=="object"?t.value.next.text:void 0)??((A=r[u+1])==null?void 0:A.docFooterText)??((C=r[u+1])==null?void 0:C.text),link:(typeof t.value.next=="object"?t.value.next.link:void 0)??((S=r[u+1])==null?void 0:S.link)}}})}function qt(o,e){const t=new Set;return o.filter(s=>{const n=e(s);return t.has(n)?!1:t.add(n)})}const D=_({__name:"VPLink",props:{tag:{},href:{},noIcon:{type:Boolean},target:{},rel:{}},setup(o){const e=o,t=g(()=>e.tag??(e.href?"a":"span")),s=g(()=>e.href&&Le.test(e.href));return(n,r)=>(a(),$(R(t.value),{class:N(["VPLink",{link:n.href,"vp-external-link-icon":s.value,"no-icon":n.noIcon}]),href:n.href?i(fe)(n.href):void 0,target:n.target??(s.value?"_blank":void 0),rel:n.rel??(s.value?"noreferrer":void 0)},{default:d(()=>[l(n.$slots,"default")]),_:3},8,["class","href","target","rel"]))}}),Kt={class:"VPLastUpdated"},Wt=["datetime"],Rt=_({__name:"VPDocFooterLastUpdated",setup(o){const{theme:e,page:t,frontmatter:s,lang:n}=V(),r=g(()=>new Date(s.value.lastUpdated??t.value.lastUpdated)),u=g(()=>r.value.toISOString()),h=T("");return z(()=>{x(()=>{var p,b,P;h.value=new Intl.DateTimeFormat((b=(p=e.value.lastUpdated)==null?void 0:p.formatOptions)!=null&&b.forceLocale?n.value:void 0,((P=e.value.lastUpdated)==null?void 0:P.formatOptions)??{dateStyle:"short",timeStyle:"short"}).format(r.value)})}),(p,b)=>{var P;return a(),c("p",Kt,[F(w(((P=i(e).lastUpdated)==null?void 0:P.text)||i(e).lastUpdatedText||"Last updated")+": ",1),v("time",{datetime:u.value},w(h.value),9,Wt)])}}}),Jt=k(Rt,[["__scopeId","data-v-19a7ae4e"]]),Yt=o=>(B("data-v-b77f9094"),o=o(),H(),o),Qt={key:0,class:"VPDocFooter"},Xt={key:0,class:"edit-info"},Zt={key:0,class:"edit-link"},xt=Yt(()=>v("span",{class:"vpi-square-pen edit-link-icon"},null,-1)),eo={key:1,class:"last-updated"},to={key:1,class:"prev-next"},oo={class:"pager"},so=["innerHTML"],no=["innerHTML"],ao={class:"pager"},ro=["innerHTML"],io=["innerHTML"],lo=_({__name:"VPDocFooter",setup(o){const{theme:e,page:t,frontmatter:s}=V(),n=jt(),r=zt(),u=g(()=>e.value.editLink&&s.value.editLink!==!1),h=g(()=>t.value.lastUpdated&&s.value.lastUpdated!==!1),p=g(()=>u.value||h.value||r.value.prev||r.value.next);return(b,P)=>{var y,L,I,A;return p.value?(a(),c("footer",Qt,[l(b.$slots,"doc-footer-before",{},void 0,!0),u.value||h.value?(a(),c("div",Xt,[u.value?(a(),c("div",Zt,[m(D,{class:"edit-link-button",href:i(n).url,"no-icon":!0},{default:d(()=>[xt,F(" "+w(i(n).text),1)]),_:1},8,["href"])])):f("",!0),h.value?(a(),c("div",eo,[m(Jt)])):f("",!0)])):f("",!0),(y=i(r).prev)!=null&&y.link||(L=i(r).next)!=null&&L.link?(a(),c("nav",to,[v("div",oo,[(I=i(r).prev)!=null&&I.link?(a(),$(D,{key:0,class:"pager-link prev",href:i(r).prev.link},{default:d(()=>{var C;return[v("span",{class:"desc",innerHTML:((C=i(e).docFooter)==null?void 0:C.prev)||"Previous page"},null,8,so),v("span",{class:"title",innerHTML:i(r).prev.text},null,8,no)]}),_:1},8,["href"])):f("",!0)]),v("div",ao,[(A=i(r).next)!=null&&A.link?(a(),$(D,{key:0,class:"pager-link next",href:i(r).next.link},{default:d(()=>{var C;return[v("span",{class:"desc",innerHTML:((C=i(e).docFooter)==null?void 0:C.next)||"Next page"},null,8,ro),v("span",{class:"title",innerHTML:i(r).next.text},null,8,io)]}),_:1},8,["href"])):f("",!0)])])):f("",!0)])):f("",!0)}}}),co=k(lo,[["__scopeId","data-v-b77f9094"]]),uo=o=>(B("data-v-e6f2a212"),o=o(),H(),o),vo={class:"container"},po=uo(()=>v("div",{class:"aside-curtain"},null,-1)),ho={class:"aside-container"},fo={class:"aside-content"},_o={class:"content"},mo={class:"content-container"},ko={class:"main"},bo=_({__name:"VPDoc",setup(o){const{theme:e}=V(),t=te(),{hasSidebar:s,hasAside:n,leftAside:r}=O(),u=g(()=>t.path.replace(/[./]+/g,"_").replace(/_html$/,""));return(h,p)=>{const b=K("Content");return a(),c("div",{class:N(["VPDoc",{"has-sidebar":i(s),"has-aside":i(n)}])},[l(h.$slots,"doc-top",{},void 0,!0),v("div",vo,[i(n)?(a(),c("div",{key:0,class:N(["aside",{"left-aside":i(r)}])},[po,v("div",ho,[v("div",fo,[m(Gt,null,{"aside-top":d(()=>[l(h.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":d(()=>[l(h.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":d(()=>[l(h.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":d(()=>[l(h.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":d(()=>[l(h.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":d(()=>[l(h.$slots,"aside-ads-after",{},void 0,!0)]),_:3})])])],2)):f("",!0),v("div",_o,[v("div",mo,[l(h.$slots,"doc-before",{},void 0,!0),v("main",ko,[m(b,{class:N(["vp-doc",[u.value,i(e).externalLinkIcon&&"external-link-icon-enabled"]])},null,8,["class"])]),m(co,null,{"doc-footer-before":d(()=>[l(h.$slots,"doc-footer-before",{},void 0,!0)]),_:3}),l(h.$slots,"doc-after",{},void 0,!0)])])]),l(h.$slots,"doc-bottom",{},void 0,!0)],2)}}}),$o=k(bo,[["__scopeId","data-v-e6f2a212"]]),go=_({__name:"VPButton",props:{tag:{},size:{default:"medium"},theme:{default:"brand"},text:{},href:{},target:{},rel:{}},setup(o){const e=o,t=g(()=>e.href&&Le.test(e.href)),s=g(()=>e.tag||e.href?"a":"button");return(n,r)=>(a(),$(R(s.value),{class:N(["VPButton",[n.size,n.theme]]),href:n.href?i(fe)(n.href):void 0,target:e.target??(t.value?"_blank":void 0),rel:e.rel??(t.value?"noreferrer":void 0)},{default:d(()=>[F(w(n.text),1)]),_:1},8,["class","href","target","rel"]))}}),yo=k(go,[["__scopeId","data-v-c9cf0e3c"]]),Po=["src","alt"],Vo=_({inheritAttrs:!1,__name:"VPImage",props:{image:{},alt:{}},setup(o){return(e,t)=>{const s=K("VPImage",!0);return e.image?(a(),c(M,{key:0},[typeof e.image=="string"||"src"in e.image?(a(),c("img",Q({key:0,class:"VPImage"},typeof e.image=="string"?e.$attrs:{...e.image,...e.$attrs},{src:i(pe)(typeof e.image=="string"?e.image:e.image.src),alt:e.alt??(typeof e.image=="string"?"":e.image.alt||"")}),null,16,Po)):(a(),c(M,{key:1},[m(s,Q({class:"dark",image:e.image.dark,alt:e.image.alt},e.$attrs),null,16,["image","alt"]),m(s,Q({class:"light",image:e.image.light,alt:e.image.alt},e.$attrs),null,16,["image","alt"])],64))],64)):f("",!0)}}}),Z=k(Vo,[["__scopeId","data-v-ab19afbb"]]),Lo=o=>(B("data-v-b10c5094"),o=o(),H(),o),So={class:"container"},wo={class:"main"},Io={key:0,class:"name"},To=["innerHTML"],No=["innerHTML"],Mo=["innerHTML"],Ao={key:0,class:"actions"},Co={key:0,class:"image"},Bo={class:"image-container"},Ho=Lo(()=>v("div",{class:"image-bg"},null,-1)),Eo=_({__name:"VPHero",props:{name:{},text:{},tagline:{},image:{},actions:{}},setup(o){const e=oe("hero-image-slot-exists");return(t,s)=>(a(),c("div",{class:N(["VPHero",{"has-image":t.image||i(e)}])},[v("div",So,[v("div",wo,[l(t.$slots,"home-hero-info-before",{},void 0,!0),l(t.$slots,"home-hero-info",{},()=>[t.name?(a(),c("h1",Io,[v("span",{innerHTML:t.name,class:"clip"},null,8,To)])):f("",!0),t.text?(a(),c("p",{key:1,innerHTML:t.text,class:"text"},null,8,No)):f("",!0),t.tagline?(a(),c("p",{key:2,innerHTML:t.tagline,class:"tagline"},null,8,Mo)):f("",!0)],!0),l(t.$slots,"home-hero-info-after",{},void 0,!0),t.actions?(a(),c("div",Ao,[(a(!0),c(M,null,E(t.actions,n=>(a(),c("div",{key:n.link,class:"action"},[m(yo,{tag:"a",size:"medium",theme:n.theme,text:n.text,href:n.link,target:n.target,rel:n.rel},null,8,["theme","text","href","target","rel"])]))),128))])):f("",!0),l(t.$slots,"home-hero-actions-after",{},void 0,!0)]),t.image||i(e)?(a(),c("div",Co,[v("div",Bo,[Ho,l(t.$slots,"home-hero-image",{},()=>[t.image?(a(),$(Z,{key:0,class:"image-src",image:t.image},null,8,["image"])):f("",!0)],!0)])])):f("",!0)])],2))}}),Fo=k(Eo,[["__scopeId","data-v-b10c5094"]]),Do=_({__name:"VPHomeHero",setup(o){const{frontmatter:e}=V();return(t,s)=>i(e).hero?(a(),$(Fo,{key:0,class:"VPHomeHero",name:i(e).hero.name,text:i(e).hero.text,tagline:i(e).hero.tagline,image:i(e).hero.image,actions:i(e).hero.actions},{"home-hero-info-before":d(()=>[l(t.$slots,"home-hero-info-before")]),"home-hero-info":d(()=>[l(t.$slots,"home-hero-info")]),"home-hero-info-after":d(()=>[l(t.$slots,"home-hero-info-after")]),"home-hero-actions-after":d(()=>[l(t.$slots,"home-hero-actions-after")]),"home-hero-image":d(()=>[l(t.$slots,"home-hero-image")]),_:3},8,["name","text","tagline","image","actions"])):f("",!0)}}),Oo=o=>(B("data-v-bd37d1a2"),o=o(),H(),o),Uo={class:"box"},Go={key:0,class:"icon"},jo=["innerHTML"],zo=["innerHTML"],qo=["innerHTML"],Ko={key:4,class:"link-text"},Wo={class:"link-text-value"},Ro=Oo(()=>v("span",{class:"vpi-arrow-right link-text-icon"},null,-1)),Jo=_({__name:"VPFeature",props:{icon:{},title:{},details:{},link:{},linkText:{},rel:{},target:{}},setup(o){return(e,t)=>(a(),$(D,{class:"VPFeature",href:e.link,rel:e.rel,target:e.target,"no-icon":!0,tag:e.link?"a":"div"},{default:d(()=>[v("article",Uo,[typeof e.icon=="object"&&e.icon.wrap?(a(),c("div",Go,[m(Z,{image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])])):typeof e.icon=="object"?(a(),$(Z,{key:1,image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])):e.icon?(a(),c("div",{key:2,class:"icon",innerHTML:e.icon},null,8,jo)):f("",!0),v("h2",{class:"title",innerHTML:e.title},null,8,zo),e.details?(a(),c("p",{key:3,class:"details",innerHTML:e.details},null,8,qo)):f("",!0),e.linkText?(a(),c("div",Ko,[v("p",Wo,[F(w(e.linkText)+" ",1),Ro])])):f("",!0)])]),_:1},8,["href","rel","target","tag"]))}}),Yo=k(Jo,[["__scopeId","data-v-bd37d1a2"]]),Qo={key:0,class:"VPFeatures"},Xo={class:"container"},Zo={class:"items"},xo=_({__name:"VPFeatures",props:{features:{}},setup(o){const e=o,t=g(()=>{const s=e.features.length;if(s){if(s===2)return"grid-2";if(s===3)return"grid-3";if(s%3===0)return"grid-6";if(s>3)return"grid-4"}else return});return(s,n)=>s.features?(a(),c("div",Qo,[v("div",Xo,[v("div",Zo,[(a(!0),c(M,null,E(s.features,r=>(a(),c("div",{key:r.title,class:N(["item",[t.value]])},[m(Yo,{icon:r.icon,title:r.title,details:r.details,link:r.link,"link-text":r.linkText,rel:r.rel,target:r.target},null,8,["icon","title","details","link","link-text","rel","target"])],2))),128))])])])):f("",!0)}}),es=k(xo,[["__scopeId","data-v-b1eea84a"]]),ts=_({__name:"VPHomeFeatures",setup(o){const{frontmatter:e}=V();return(t,s)=>i(e).features?(a(),$(es,{key:0,class:"VPHomeFeatures",features:i(e).features},null,8,["features"])):f("",!0)}}),os=_({__name:"VPHomeContent",setup(o){const{width:e}=Ke({includeScrollbar:!1});return(t,s)=>(a(),c("div",{class:"vp-doc container",style:Se(i(e)?{"--vp-offset":`calc(50% - ${i(e)/2}px)`}:{})},[l(t.$slots,"default",{},void 0,!0)],4))}}),ss=k(os,[["__scopeId","data-v-d59ac166"]]),ns={class:"VPHome"},as=_({__name:"VPHome",setup(o){const{frontmatter:e}=V();return(t,s)=>{const n=K("Content");return a(),c("div",ns,[l(t.$slots,"home-hero-before",{},void 0,!0),m(Do,null,{"home-hero-info-before":d(()=>[l(t.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":d(()=>[l(t.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":d(()=>[l(t.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":d(()=>[l(t.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":d(()=>[l(t.$slots,"home-hero-image",{},void 0,!0)]),_:3}),l(t.$slots,"home-hero-after",{},void 0,!0),l(t.$slots,"home-features-before",{},void 0,!0),m(ts),l(t.$slots,"home-features-after",{},void 0,!0),i(e).markdownStyles!==!1?(a(),$(ss,{key:0},{default:d(()=>[m(n)]),_:1})):(a(),$(n,{key:1}))])}}}),rs=k(as,[["__scopeId","data-v-07b1ad08"]]),is={},ls={class:"VPPage"};function cs(o,e){const t=K("Content");return a(),c("div",ls,[l(o.$slots,"page-top"),m(t),l(o.$slots,"page-bottom")])}const us=k(is,[["render",cs]]),ds=_({__name:"VPContent",setup(o){const{page:e,frontmatter:t}=V(),{hasSidebar:s}=O();return(n,r)=>(a(),c("div",{class:N(["VPContent",{"has-sidebar":i(s),"is-home":i(t).layout==="home"}]),id:"VPContent"},[i(e).isNotFound?l(n.$slots,"not-found",{key:0},()=>[m(_t)],!0):i(t).layout==="page"?(a(),$(us,{key:1},{"page-top":d(()=>[l(n.$slots,"page-top",{},void 0,!0)]),"page-bottom":d(()=>[l(n.$slots,"page-bottom",{},void 0,!0)]),_:3})):i(t).layout==="home"?(a(),$(rs,{key:2},{"home-hero-before":d(()=>[l(n.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":d(()=>[l(n.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":d(()=>[l(n.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":d(()=>[l(n.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":d(()=>[l(n.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":d(()=>[l(n.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":d(()=>[l(n.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":d(()=>[l(n.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":d(()=>[l(n.$slots,"home-features-after",{},void 0,!0)]),_:3})):i(t).layout&&i(t).layout!=="doc"?(a(),$(R(i(t).layout),{key:3})):(a(),$($o,{key:4},{"doc-top":d(()=>[l(n.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":d(()=>[l(n.$slots,"doc-bottom",{},void 0,!0)]),"doc-footer-before":d(()=>[l(n.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":d(()=>[l(n.$slots,"doc-before",{},void 0,!0)]),"doc-after":d(()=>[l(n.$slots,"doc-after",{},void 0,!0)]),"aside-top":d(()=>[l(n.$slots,"aside-top",{},void 0,!0)]),"aside-outline-before":d(()=>[l(n.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":d(()=>[l(n.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":d(()=>[l(n.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":d(()=>[l(n.$slots,"aside-ads-after",{},void 0,!0)]),"aside-bottom":d(()=>[l(n.$slots,"aside-bottom",{},void 0,!0)]),_:3}))],2))}}),vs=k(ds,[["__scopeId","data-v-9a6c75ad"]]),ps={class:"container"},hs=["innerHTML"],fs=["innerHTML"],_s=_({__name:"VPFooter",setup(o){const{theme:e,frontmatter:t}=V(),{hasSidebar:s}=O();return(n,r)=>i(e).footer&&i(t).footer!==!1?(a(),c("footer",{key:0,class:N(["VPFooter",{"has-sidebar":i(s)}])},[v("div",ps,[i(e).footer.message?(a(),c("p",{key:0,class:"message",innerHTML:i(e).footer.message},null,8,hs)):f("",!0),i(e).footer.copyright?(a(),c("p",{key:1,class:"copyright",innerHTML:i(e).footer.copyright},null,8,fs)):f("",!0)])],2)):f("",!0)}}),ms=k(_s,[["__scopeId","data-v-566314d4"]]);function ks(){const{theme:o,frontmatter:e}=V(),t=Ve([]),s=g(()=>t.value.length>0);return ee(()=>{t.value=me(e.value.outline??o.value.outline)}),{headers:t,hasLocalNav:s}}const bs=o=>(B("data-v-0b5c97a1"),o=o(),H(),o),$s=bs(()=>v("span",{class:"vpi-chevron-right icon"},null,-1)),gs={class:"header"},ys={class:"outline"},Ps=_({__name:"VPLocalNavOutlineDropdown",props:{headers:{},navHeight:{}},setup(o){const e=o,{theme:t}=V(),s=T(!1),n=T(0),r=T(),u=T();We(r,()=>{s.value=!1}),le("Escape",()=>{s.value=!1}),ee(()=>{s.value=!1});function h(){s.value=!s.value,n.value=window.innerHeight+Math.min(window.scrollY-e.navHeight,0)}function p(P){P.target.classList.contains("outline-link")&&(u.value&&(u.value.style.transition="none"),Re(()=>{s.value=!1}))}function b(){s.value=!1,window.scrollTo({top:0,left:0,behavior:"smooth"})}return(P,y)=>(a(),c("div",{class:"VPLocalNavOutlineDropdown",style:Se({"--vp-vh":n.value+"px"}),ref_key:"main",ref:r},[P.headers.length>0?(a(),c("button",{key:0,onClick:h,class:N({open:s.value})},[F(w(i(Me)(i(t)))+" ",1),$s],2)):(a(),c("button",{key:1,onClick:b},w(i(t).returnToTopLabel||"Return to top"),1)),m(ve,{name:"flyout"},{default:d(()=>[s.value?(a(),c("div",{key:0,ref_key:"items",ref:u,class:"items",onClick:p},[v("div",gs,[v("a",{class:"top-link",href:"#",onClick:b},w(i(t).returnToTopLabel||"Return to top"),1)]),v("div",ys,[m(Ae,{headers:P.headers},null,8,["headers"])])],512)):f("",!0)]),_:1})],4))}}),Vs=k(Ps,[["__scopeId","data-v-0b5c97a1"]]),Ls=o=>(B("data-v-2488c25a"),o=o(),H(),o),Ss={class:"container"},ws=["aria-expanded"],Is=Ls(()=>v("span",{class:"vpi-align-left menu-icon"},null,-1)),Ts={class:"menu-text"},Ns=_({__name:"VPLocalNav",props:{open:{type:Boolean}},emits:["open-menu"],setup(o){const{theme:e,frontmatter:t}=V(),{hasSidebar:s}=O(),{headers:n}=ks(),{y:r}=we(),u=T(0);z(()=>{u.value=parseInt(getComputedStyle(document.documentElement).getPropertyValue("--vp-nav-height"))}),ee(()=>{n.value=me(t.value.outline??e.value.outline)});const h=g(()=>n.value.length===0),p=g(()=>h.value&&!s.value),b=g(()=>({VPLocalNav:!0,"has-sidebar":s.value,empty:h.value,fixed:p.value}));return(P,y)=>i(t).layout!=="home"&&(!p.value||i(r)>=u.value)?(a(),c("div",{key:0,class:N(b.value)},[v("div",Ss,[i(s)?(a(),c("button",{key:0,class:"menu","aria-expanded":P.open,"aria-controls":"VPSidebarNav",onClick:y[0]||(y[0]=L=>P.$emit("open-menu"))},[Is,v("span",Ts,w(i(e).sidebarMenuLabel||"Menu"),1)],8,ws)):f("",!0),m(Vs,{headers:i(n),navHeight:u.value},null,8,["headers","navHeight"])])],2)):f("",!0)}}),Ms=k(Ns,[["__scopeId","data-v-2488c25a"]]);function As(){const o=T(!1);function e(){o.value=!0,window.addEventListener("resize",n)}function t(){o.value=!1,window.removeEventListener("resize",n)}function s(){o.value?t():e()}function n(){window.outerWidth>=768&&t()}const r=te();return q(()=>r.path,t),{isScreenOpen:o,openScreen:e,closeScreen:t,toggleScreen:s}}const Cs={},Bs={class:"VPSwitch",type:"button",role:"switch"},Hs={class:"check"},Es={key:0,class:"icon"};function Fs(o,e){return a(),c("button",Bs,[v("span",Hs,[o.$slots.default?(a(),c("span",Es,[l(o.$slots,"default",{},void 0,!0)])):f("",!0)])])}const Ds=k(Cs,[["render",Fs],["__scopeId","data-v-b4ccac88"]]),Ce=o=>(B("data-v-7df97737"),o=o(),H(),o),Os=Ce(()=>v("span",{class:"vpi-sun sun"},null,-1)),Us=Ce(()=>v("span",{class:"vpi-moon moon"},null,-1)),Gs=_({__name:"VPSwitchAppearance",setup(o){const{isDark:e,theme:t}=V(),s=oe("toggle-appearance",()=>{e.value=!e.value}),n=g(()=>e.value?t.value.lightModeSwitchTitle||"Switch to light theme":t.value.darkModeSwitchTitle||"Switch to dark theme");return(r,u)=>(a(),$(Ds,{title:n.value,class:"VPSwitchAppearance","aria-checked":i(e),onClick:i(s)},{default:d(()=>[Os,Us]),_:1},8,["title","aria-checked","onClick"]))}}),ke=k(Gs,[["__scopeId","data-v-7df97737"]]),js={key:0,class:"VPNavBarAppearance"},zs=_({__name:"VPNavBarAppearance",setup(o){const{site:e}=V();return(t,s)=>i(e).appearance&&i(e).appearance!=="force-dark"?(a(),c("div",js,[m(ke)])):f("",!0)}}),qs=k(zs,[["__scopeId","data-v-283b26e9"]]),be=T();let Be=!1,re=0;function Ks(o){const e=T(!1);if(J){!Be&&Ws(),re++;const t=q(be,s=>{var n,r,u;s===o.el.value||(n=o.el.value)!=null&&n.contains(s)?(e.value=!0,(r=o.onFocus)==null||r.call(o)):(e.value=!1,(u=o.onBlur)==null||u.call(o))});he(()=>{t(),re--,re||Rs()})}return Je(e)}function Ws(){document.addEventListener("focusin",He),Be=!0,be.value=document.activeElement}function Rs(){document.removeEventListener("focusin",He)}function He(){be.value=document.activeElement}const Js={class:"VPMenuLink"},Ys=_({__name:"VPMenuLink",props:{item:{}},setup(o){const{page:e}=V();return(t,s)=>(a(),c("div",Js,[m(D,{class:N({active:i(j)(i(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,target:t.item.target,rel:t.item.rel},{default:d(()=>[F(w(t.item.text),1)]),_:1},8,["class","href","target","rel"])]))}}),se=k(Ys,[["__scopeId","data-v-f51f088d"]]),Qs={class:"VPMenuGroup"},Xs={key:0,class:"title"},Zs=_({__name:"VPMenuGroup",props:{text:{},items:{}},setup(o){return(e,t)=>(a(),c("div",Qs,[e.text?(a(),c("p",Xs,w(e.text),1)):f("",!0),(a(!0),c(M,null,E(e.items,s=>(a(),c(M,null,["link"in s?(a(),$(se,{key:0,item:s},null,8,["item"])):f("",!0)],64))),256))]))}}),xs=k(Zs,[["__scopeId","data-v-a6b0397c"]]),en={class:"VPMenu"},tn={key:0,class:"items"},on=_({__name:"VPMenu",props:{items:{}},setup(o){return(e,t)=>(a(),c("div",en,[e.items?(a(),c("div",tn,[(a(!0),c(M,null,E(e.items,s=>(a(),c(M,{key:s.text},["link"in s?(a(),$(se,{key:0,item:s},null,8,["item"])):(a(),$(xs,{key:1,text:s.text,items:s.items},null,8,["text","items"]))],64))),128))])):f("",!0),l(e.$slots,"default",{},void 0,!0)]))}}),sn=k(on,[["__scopeId","data-v-e42ed9b3"]]),nn=o=>(B("data-v-af5898d3"),o=o(),H(),o),an=["aria-expanded","aria-label"],rn={key:0,class:"text"},ln=["innerHTML"],cn=nn(()=>v("span",{class:"vpi-chevron-down text-icon"},null,-1)),un={key:1,class:"vpi-more-horizontal icon"},dn={class:"menu"},vn=_({__name:"VPFlyout",props:{icon:{},button:{},label:{},items:{}},setup(o){const e=T(!1),t=T();Ks({el:t,onBlur:s});function s(){e.value=!1}return(n,r)=>(a(),c("div",{class:"VPFlyout",ref_key:"el",ref:t,onMouseenter:r[1]||(r[1]=u=>e.value=!0),onMouseleave:r[2]||(r[2]=u=>e.value=!1)},[v("button",{type:"button",class:"button","aria-haspopup":"true","aria-expanded":e.value,"aria-label":n.label,onClick:r[0]||(r[0]=u=>e.value=!e.value)},[n.button||n.icon?(a(),c("span",rn,[n.icon?(a(),c("span",{key:0,class:N([n.icon,"option-icon"])},null,2)):f("",!0),n.button?(a(),c("span",{key:1,innerHTML:n.button},null,8,ln)):f("",!0),cn])):(a(),c("span",un))],8,an),v("div",dn,[m(sn,{items:n.items},{default:d(()=>[l(n.$slots,"default",{},void 0,!0)]),_:3},8,["items"])])],544))}}),$e=k(vn,[["__scopeId","data-v-af5898d3"]]),pn=["href","aria-label","innerHTML"],hn=_({__name:"VPSocialLink",props:{icon:{},link:{},ariaLabel:{}},setup(o){const e=o,t=g(()=>typeof e.icon=="object"?e.icon.svg:``);return(s,n)=>(a(),c("a",{class:"VPSocialLink no-icon",href:s.link,"aria-label":s.ariaLabel??(typeof s.icon=="string"?s.icon:""),target:"_blank",rel:"noopener",innerHTML:t.value},null,8,pn))}}),fn=k(hn,[["__scopeId","data-v-358b6670"]]),_n={class:"VPSocialLinks"},mn=_({__name:"VPSocialLinks",props:{links:{}},setup(o){return(e,t)=>(a(),c("div",_n,[(a(!0),c(M,null,E(e.links,({link:s,icon:n,ariaLabel:r})=>(a(),$(fn,{key:s,icon:n,link:s,ariaLabel:r},null,8,["icon","link","ariaLabel"]))),128))]))}}),ge=k(mn,[["__scopeId","data-v-e71e869c"]]),kn={key:0,class:"group translations"},bn={class:"trans-title"},$n={key:1,class:"group"},gn={class:"item appearance"},yn={class:"label"},Pn={class:"appearance-action"},Vn={key:2,class:"group"},Ln={class:"item social-links"},Sn=_({__name:"VPNavBarExtra",setup(o){const{site:e,theme:t}=V(),{localeLinks:s,currentLang:n}=Y({correspondingLink:!0}),r=g(()=>s.value.length&&n.value.label||e.value.appearance||t.value.socialLinks);return(u,h)=>r.value?(a(),$($e,{key:0,class:"VPNavBarExtra",label:"extra navigation"},{default:d(()=>[i(s).length&&i(n).label?(a(),c("div",kn,[v("p",bn,w(i(n).label),1),(a(!0),c(M,null,E(i(s),p=>(a(),$(se,{key:p.link,item:p},null,8,["item"]))),128))])):f("",!0),i(e).appearance&&i(e).appearance!=="force-dark"?(a(),c("div",$n,[v("div",gn,[v("p",yn,w(i(t).darkModeSwitchLabel||"Appearance"),1),v("div",Pn,[m(ke)])])])):f("",!0),i(t).socialLinks?(a(),c("div",Vn,[v("div",Ln,[m(ge,{class:"social-links-list",links:i(t).socialLinks},null,8,["links"])])])):f("",!0)]),_:1})):f("",!0)}}),wn=k(Sn,[["__scopeId","data-v-8e87c032"]]),In=o=>(B("data-v-6bee1efd"),o=o(),H(),o),Tn=["aria-expanded"],Nn=In(()=>v("span",{class:"container"},[v("span",{class:"top"}),v("span",{class:"middle"}),v("span",{class:"bottom"})],-1)),Mn=[Nn],An=_({__name:"VPNavBarHamburger",props:{active:{type:Boolean}},emits:["click"],setup(o){return(e,t)=>(a(),c("button",{type:"button",class:N(["VPNavBarHamburger",{active:e.active}]),"aria-label":"mobile navigation","aria-expanded":e.active,"aria-controls":"VPNavScreen",onClick:t[0]||(t[0]=s=>e.$emit("click"))},Mn,10,Tn))}}),Cn=k(An,[["__scopeId","data-v-6bee1efd"]]),Bn=["innerHTML"],Hn=_({__name:"VPNavBarMenuLink",props:{item:{}},setup(o){const{page:e}=V();return(t,s)=>(a(),$(D,{class:N({VPNavBarMenuLink:!0,active:i(j)(i(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,noIcon:t.item.noIcon,target:t.item.target,rel:t.item.rel,tabindex:"0"},{default:d(()=>[v("span",{innerHTML:t.item.text},null,8,Bn)]),_:1},8,["class","href","noIcon","target","rel"]))}}),En=k(Hn,[["__scopeId","data-v-08fbf4b6"]]),Fn=_({__name:"VPNavBarMenuGroup",props:{item:{}},setup(o){const e=o,{page:t}=V(),s=r=>"link"in r?j(t.value.relativePath,r.link,!!e.item.activeMatch):r.items.some(s),n=g(()=>s(e.item));return(r,u)=>(a(),$($e,{class:N({VPNavBarMenuGroup:!0,active:i(j)(i(t).relativePath,r.item.activeMatch,!!r.item.activeMatch)||n.value}),button:r.item.text,items:r.item.items},null,8,["class","button","items"]))}}),Dn=o=>(B("data-v-f732b5d0"),o=o(),H(),o),On={key:0,"aria-labelledby":"main-nav-aria-label",class:"VPNavBarMenu"},Un=Dn(()=>v("span",{id:"main-nav-aria-label",class:"visually-hidden"},"Main Navigation",-1)),Gn=_({__name:"VPNavBarMenu",setup(o){const{theme:e}=V();return(t,s)=>i(e).nav?(a(),c("nav",On,[Un,(a(!0),c(M,null,E(i(e).nav,n=>(a(),c(M,{key:n.text},["link"in n?(a(),$(En,{key:0,item:n},null,8,["item"])):(a(),$(Fn,{key:1,item:n},null,8,["item"]))],64))),128))])):f("",!0)}}),jn=k(Gn,[["__scopeId","data-v-f732b5d0"]]);function zn(o){const{localeIndex:e,theme:t}=V();function s(n){var A,C,S;const r=n.split("."),u=(A=t.value.search)==null?void 0:A.options,h=u&&typeof u=="object",p=h&&((S=(C=u.locales)==null?void 0:C[e.value])==null?void 0:S.translations)||null,b=h&&u.translations||null;let P=p,y=b,L=o;const I=r.pop();for(const U of r){let G=null;const W=L==null?void 0:L[U];W&&(G=L=W);const ne=y==null?void 0:y[U];ne&&(G=y=ne);const ae=P==null?void 0:P[U];ae&&(G=P=ae),W||(L=G),ne||(y=G),ae||(P=G)}return(P==null?void 0:P[I])??(y==null?void 0:y[I])??(L==null?void 0:L[I])??""}return s}const qn=["aria-label"],Kn={class:"DocSearch-Button-Container"},Wn=v("span",{class:"vp-icon DocSearch-Search-Icon"},null,-1),Rn={class:"DocSearch-Button-Placeholder"},Jn=v("span",{class:"DocSearch-Button-Keys"},[v("kbd",{class:"DocSearch-Button-Key"}),v("kbd",{class:"DocSearch-Button-Key"},"K")],-1),ye=_({__name:"VPNavBarSearchButton",setup(o){const t=zn({button:{buttonText:"Search",buttonAriaLabel:"Search"}});return(s,n)=>(a(),c("button",{type:"button",class:"DocSearch DocSearch-Button","aria-label":i(t)("button.buttonAriaLabel")},[v("span",Kn,[Wn,v("span",Rn,w(i(t)("button.buttonText")),1)]),Jn],8,qn))}}),Yn={class:"VPNavBarSearch"},Qn={id:"local-search"},Xn={key:1,id:"docsearch"},Zn=_({__name:"VPNavBarSearch",setup(o){const e=Ye(()=>Qe(()=>import("./VPLocalSearchBox.Bp9Nb2eD.js"),__vite__mapDeps([0,1]))),t=()=>null,{theme:s}=V(),n=T(!1),r=T(!1);z(()=>{});function u(){n.value||(n.value=!0,setTimeout(h,16))}function h(){const y=new Event("keydown");y.key="k",y.metaKey=!0,window.dispatchEvent(y),setTimeout(()=>{document.querySelector(".DocSearch-Modal")||h()},16)}function p(y){const L=y.target,I=L.tagName;return L.isContentEditable||I==="INPUT"||I==="SELECT"||I==="TEXTAREA"}const b=T(!1);le("k",y=>{(y.ctrlKey||y.metaKey)&&(y.preventDefault(),b.value=!0)}),le("/",y=>{p(y)||(y.preventDefault(),b.value=!0)});const P="local";return(y,L)=>{var I;return a(),c("div",Yn,[i(P)==="local"?(a(),c(M,{key:0},[b.value?(a(),$(i(e),{key:0,onClose:L[0]||(L[0]=A=>b.value=!1)})):f("",!0),v("div",Qn,[m(ye,{onClick:L[1]||(L[1]=A=>b.value=!0)})])],64)):i(P)==="algolia"?(a(),c(M,{key:1},[n.value?(a(),$(i(t),{key:0,algolia:((I=i(s).search)==null?void 0:I.options)??i(s).algolia,onVnodeBeforeMount:L[2]||(L[2]=A=>r.value=!0)},null,8,["algolia"])):f("",!0),r.value?f("",!0):(a(),c("div",Xn,[m(ye,{onClick:u})]))],64)):f("",!0)])}}}),xn=_({__name:"VPNavBarSocialLinks",setup(o){const{theme:e}=V();return(t,s)=>i(e).socialLinks?(a(),$(ge,{key:0,class:"VPNavBarSocialLinks",links:i(e).socialLinks},null,8,["links"])):f("",!0)}}),ea=k(xn,[["__scopeId","data-v-ef6192dc"]]),ta=["href","rel","target"],oa={key:1},sa={key:2},na=_({__name:"VPNavBarTitle",setup(o){const{site:e,theme:t}=V(),{hasSidebar:s}=O(),{currentLang:n}=Y(),r=g(()=>{var p;return typeof t.value.logoLink=="string"?t.value.logoLink:(p=t.value.logoLink)==null?void 0:p.link}),u=g(()=>{var p;return typeof t.value.logoLink=="string"||(p=t.value.logoLink)==null?void 0:p.rel}),h=g(()=>{var p;return typeof t.value.logoLink=="string"||(p=t.value.logoLink)==null?void 0:p.target});return(p,b)=>(a(),c("div",{class:N(["VPNavBarTitle",{"has-sidebar":i(s)}])},[v("a",{class:"title",href:r.value??i(fe)(i(n).link),rel:u.value,target:h.value},[l(p.$slots,"nav-bar-title-before",{},void 0,!0),i(t).logo?(a(),$(Z,{key:0,class:"logo",image:i(t).logo},null,8,["image"])):f("",!0),i(t).siteTitle?(a(),c("span",oa,w(i(t).siteTitle),1)):i(t).siteTitle===void 0?(a(),c("span",sa,w(i(e).title),1)):f("",!0),l(p.$slots,"nav-bar-title-after",{},void 0,!0)],8,ta)],2))}}),aa=k(na,[["__scopeId","data-v-0ad69264"]]),ra={class:"items"},ia={class:"title"},la=_({__name:"VPNavBarTranslations",setup(o){const{theme:e}=V(),{localeLinks:t,currentLang:s}=Y({correspondingLink:!0});return(n,r)=>i(t).length&&i(s).label?(a(),$($e,{key:0,class:"VPNavBarTranslations",icon:"vpi-languages",label:i(e).langMenuLabel||"Change language"},{default:d(()=>[v("div",ra,[v("p",ia,w(i(s).label),1),(a(!0),c(M,null,E(i(t),u=>(a(),$(se,{key:u.link,item:u},null,8,["item"]))),128))])]),_:1},8,["label"])):f("",!0)}}),ca=k(la,[["__scopeId","data-v-acee064b"]]),ua=o=>(B("data-v-844edcde"),o=o(),H(),o),da={class:"wrapper"},va={class:"container"},pa={class:"title"},ha={class:"content"},fa={class:"content-body"},_a=ua(()=>v("div",{class:"divider"},[v("div",{class:"divider-line"})],-1)),ma=_({__name:"VPNavBar",props:{isScreenOpen:{type:Boolean}},emits:["toggle-screen"],setup(o){const{y:e}=we(),{hasSidebar:t}=O(),{frontmatter:s}=V(),n=T({});return Pe(()=>{n.value={"has-sidebar":t.value,home:s.value.layout==="home",top:e.value===0}}),(r,u)=>(a(),c("div",{class:N(["VPNavBar",n.value])},[v("div",da,[v("div",va,[v("div",pa,[m(aa,null,{"nav-bar-title-before":d(()=>[l(r.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":d(()=>[l(r.$slots,"nav-bar-title-after",{},void 0,!0)]),_:3})]),v("div",ha,[v("div",fa,[l(r.$slots,"nav-bar-content-before",{},void 0,!0),m(Zn,{class:"search"}),m(jn,{class:"menu"}),m(ca,{class:"translations"}),m(qs,{class:"appearance"}),m(ea,{class:"social-links"}),m(wn,{class:"extra"}),l(r.$slots,"nav-bar-content-after",{},void 0,!0),m(Cn,{class:"hamburger",active:r.isScreenOpen,onClick:u[0]||(u[0]=h=>r.$emit("toggle-screen"))},null,8,["active"])])])])]),_a],2))}}),ka=k(ma,[["__scopeId","data-v-844edcde"]]),ba={key:0,class:"VPNavScreenAppearance"},$a={class:"text"},ga=_({__name:"VPNavScreenAppearance",setup(o){const{site:e,theme:t}=V();return(s,n)=>i(e).appearance&&i(e).appearance!=="force-dark"?(a(),c("div",ba,[v("p",$a,w(i(t).darkModeSwitchLabel||"Appearance"),1),m(ke)])):f("",!0)}}),ya=k(ga,[["__scopeId","data-v-338d9b48"]]),Pa=_({__name:"VPNavScreenMenuLink",props:{item:{}},setup(o){const e=oe("close-screen");return(t,s)=>(a(),$(D,{class:"VPNavScreenMenuLink",href:t.item.link,target:t.item.target,rel:t.item.rel,onClick:i(e)},{default:d(()=>[F(w(t.item.text),1)]),_:1},8,["href","target","rel","onClick"]))}}),Va=k(Pa,[["__scopeId","data-v-fe523e3d"]]),La=_({__name:"VPNavScreenMenuGroupLink",props:{item:{}},setup(o){const e=oe("close-screen");return(t,s)=>(a(),$(D,{class:"VPNavScreenMenuGroupLink",href:t.item.link,target:t.item.target,rel:t.item.rel,onClick:i(e)},{default:d(()=>[F(w(t.item.text),1)]),_:1},8,["href","target","rel","onClick"]))}}),Ee=k(La,[["__scopeId","data-v-aea78dd1"]]),Sa={class:"VPNavScreenMenuGroupSection"},wa={key:0,class:"title"},Ia=_({__name:"VPNavScreenMenuGroupSection",props:{text:{},items:{}},setup(o){return(e,t)=>(a(),c("div",Sa,[e.text?(a(),c("p",wa,w(e.text),1)):f("",!0),(a(!0),c(M,null,E(e.items,s=>(a(),$(Ee,{key:s.text,item:s},null,8,["item"]))),128))]))}}),Ta=k(Ia,[["__scopeId","data-v-f60dbfa7"]]),Na=o=>(B("data-v-d2212c70"),o=o(),H(),o),Ma=["aria-controls","aria-expanded"],Aa=["innerHTML"],Ca=Na(()=>v("span",{class:"vpi-plus button-icon"},null,-1)),Ba=["id"],Ha={key:1,class:"group"},Ea=_({__name:"VPNavScreenMenuGroup",props:{text:{},items:{}},setup(o){const e=o,t=T(!1),s=g(()=>`NavScreenGroup-${e.text.replace(" ","-").toLowerCase()}`);function n(){t.value=!t.value}return(r,u)=>(a(),c("div",{class:N(["VPNavScreenMenuGroup",{open:t.value}])},[v("button",{class:"button","aria-controls":s.value,"aria-expanded":t.value,onClick:n},[v("span",{class:"button-text",innerHTML:r.text},null,8,Aa),Ca],8,Ma),v("div",{id:s.value,class:"items"},[(a(!0),c(M,null,E(r.items,h=>(a(),c(M,{key:h.text},["link"in h?(a(),c("div",{key:h.text,class:"item"},[m(Ee,{item:h},null,8,["item"])])):(a(),c("div",Ha,[m(Ta,{text:h.text,items:h.items},null,8,["text","items"])]))],64))),128))],8,Ba)],2))}}),Fa=k(Ea,[["__scopeId","data-v-d2212c70"]]),Da={key:0,class:"VPNavScreenMenu"},Oa=_({__name:"VPNavScreenMenu",setup(o){const{theme:e}=V();return(t,s)=>i(e).nav?(a(),c("nav",Da,[(a(!0),c(M,null,E(i(e).nav,n=>(a(),c(M,{key:n.text},["link"in n?(a(),$(Va,{key:0,item:n},null,8,["item"])):(a(),$(Fa,{key:1,text:n.text||"",items:n.items},null,8,["text","items"]))],64))),128))])):f("",!0)}}),Ua=_({__name:"VPNavScreenSocialLinks",setup(o){const{theme:e}=V();return(t,s)=>i(e).socialLinks?(a(),$(ge,{key:0,class:"VPNavScreenSocialLinks",links:i(e).socialLinks},null,8,["links"])):f("",!0)}}),Fe=o=>(B("data-v-516e4bc3"),o=o(),H(),o),Ga=Fe(()=>v("span",{class:"vpi-languages icon lang"},null,-1)),ja=Fe(()=>v("span",{class:"vpi-chevron-down icon chevron"},null,-1)),za={class:"list"},qa=_({__name:"VPNavScreenTranslations",setup(o){const{localeLinks:e,currentLang:t}=Y({correspondingLink:!0}),s=T(!1);function n(){s.value=!s.value}return(r,u)=>i(e).length&&i(t).label?(a(),c("div",{key:0,class:N(["VPNavScreenTranslations",{open:s.value}])},[v("button",{class:"title",onClick:n},[Ga,F(" "+w(i(t).label)+" ",1),ja]),v("ul",za,[(a(!0),c(M,null,E(i(e),h=>(a(),c("li",{key:h.link,class:"item"},[m(D,{class:"link",href:h.link},{default:d(()=>[F(w(h.text),1)]),_:2},1032,["href"])]))),128))])],2)):f("",!0)}}),Ka=k(qa,[["__scopeId","data-v-516e4bc3"]]),Wa={class:"container"},Ra=_({__name:"VPNavScreen",props:{open:{type:Boolean}},setup(o){const e=T(null),t=Ie(J?document.body:null);return(s,n)=>(a(),$(ve,{name:"fade",onEnter:n[0]||(n[0]=r=>t.value=!0),onAfterLeave:n[1]||(n[1]=r=>t.value=!1)},{default:d(()=>[s.open?(a(),c("div",{key:0,class:"VPNavScreen",ref_key:"screen",ref:e,id:"VPNavScreen"},[v("div",Wa,[l(s.$slots,"nav-screen-content-before",{},void 0,!0),m(Oa,{class:"menu"}),m(Ka,{class:"translations"}),m(ya,{class:"appearance"}),m(Ua,{class:"social-links"}),l(s.$slots,"nav-screen-content-after",{},void 0,!0)])],512)):f("",!0)]),_:3}))}}),Ja=k(Ra,[["__scopeId","data-v-57cce842"]]),Ya={key:0,class:"VPNav"},Qa=_({__name:"VPNav",setup(o){const{isScreenOpen:e,closeScreen:t,toggleScreen:s}=As(),{frontmatter:n}=V(),r=g(()=>n.value.navbar!==!1);return Te("close-screen",t),x(()=>{J&&document.documentElement.classList.toggle("hide-nav",!r.value)}),(u,h)=>r.value?(a(),c("header",Ya,[m(ka,{"is-screen-open":i(e),onToggleScreen:i(s)},{"nav-bar-title-before":d(()=>[l(u.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":d(()=>[l(u.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":d(()=>[l(u.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":d(()=>[l(u.$slots,"nav-bar-content-after",{},void 0,!0)]),_:3},8,["is-screen-open","onToggleScreen"]),m(Ja,{open:i(e)},{"nav-screen-content-before":d(()=>[l(u.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":d(()=>[l(u.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3},8,["open"])])):f("",!0)}}),Xa=k(Qa,[["__scopeId","data-v-7ad780c2"]]),De=o=>(B("data-v-c24f735a"),o=o(),H(),o),Za=["role","tabindex"],xa=De(()=>v("div",{class:"indicator"},null,-1)),er=De(()=>v("span",{class:"vpi-chevron-right caret-icon"},null,-1)),tr=[er],or={key:1,class:"items"},sr=_({__name:"VPSidebarItem",props:{item:{},depth:{}},setup(o){const e=o,{collapsed:t,collapsible:s,isLink:n,isActiveLink:r,hasActiveLink:u,hasChildren:h,toggle:p}=$t(g(()=>e.item)),b=g(()=>h.value?"section":"div"),P=g(()=>n.value?"a":"div"),y=g(()=>h.value?e.depth+2===7?"p":`h${e.depth+2}`:"p"),L=g(()=>n.value?void 0:"button"),I=g(()=>[[`level-${e.depth}`],{collapsible:s.value},{collapsed:t.value},{"is-link":n.value},{"is-active":r.value},{"has-active":u.value}]);function A(S){"key"in S&&S.key!=="Enter"||!e.item.link&&p()}function C(){e.item.link&&p()}return(S,U)=>{const G=K("VPSidebarItem",!0);return a(),$(R(b.value),{class:N(["VPSidebarItem",I.value])},{default:d(()=>[S.item.text?(a(),c("div",Q({key:0,class:"item",role:L.value},Ze(S.item.items?{click:A,keydown:A}:{},!0),{tabindex:S.item.items&&0}),[xa,S.item.link?(a(),$(D,{key:0,tag:P.value,class:"link",href:S.item.link,rel:S.item.rel,target:S.item.target},{default:d(()=>[(a(),$(R(y.value),{class:"text",innerHTML:S.item.text},null,8,["innerHTML"]))]),_:1},8,["tag","href","rel","target"])):(a(),$(R(y.value),{key:1,class:"text",innerHTML:S.item.text},null,8,["innerHTML"])),S.item.collapsed!=null&&S.item.items&&S.item.items.length?(a(),c("div",{key:2,class:"caret",role:"button","aria-label":"toggle section",onClick:C,onKeydown:Xe(C,["enter"]),tabindex:"0"},tr,32)):f("",!0)],16,Za)):f("",!0),S.item.items&&S.item.items.length?(a(),c("div",or,[S.depth<5?(a(!0),c(M,{key:0},E(S.item.items,W=>(a(),$(G,{key:W.text,item:W,depth:S.depth+1},null,8,["item","depth"]))),128)):f("",!0)])):f("",!0)]),_:1},8,["class"])}}}),nr=k(sr,[["__scopeId","data-v-c24f735a"]]),Oe=o=>(B("data-v-4871f9f5"),o=o(),H(),o),ar=Oe(()=>v("div",{class:"curtain"},null,-1)),rr={class:"nav",id:"VPSidebarNav","aria-labelledby":"sidebar-aria-label",tabindex:"-1"},ir=Oe(()=>v("span",{class:"visually-hidden",id:"sidebar-aria-label"}," Sidebar Navigation ",-1)),lr=_({__name:"VPSidebar",props:{open:{type:Boolean}},setup(o){const{sidebarGroups:e,hasSidebar:t}=O(),s=o,n=T(null),r=Ie(J?document.body:null);return q([s,n],()=>{var u;s.open?(r.value=!0,(u=n.value)==null||u.focus()):r.value=!1},{immediate:!0,flush:"post"}),(u,h)=>i(t)?(a(),c("aside",{key:0,class:N(["VPSidebar",{open:u.open}]),ref_key:"navEl",ref:n,onClick:h[0]||(h[0]=xe(()=>{},["stop"]))},[ar,v("nav",rr,[ir,l(u.$slots,"sidebar-nav-before",{},void 0,!0),(a(!0),c(M,null,E(i(e),p=>(a(),c("div",{key:p.text,class:"group"},[m(nr,{item:p,depth:0},null,8,["item"])]))),128)),l(u.$slots,"sidebar-nav-after",{},void 0,!0)])],2)):f("",!0)}}),cr=k(lr,[["__scopeId","data-v-4871f9f5"]]),ur=_({__name:"VPSkipLink",setup(o){const e=te(),t=T();q(()=>e.path,()=>t.value.focus());function s({target:n}){const r=document.getElementById(decodeURIComponent(n.hash).slice(1));if(r){const u=()=>{r.removeAttribute("tabindex"),r.removeEventListener("blur",u)};r.setAttribute("tabindex","-1"),r.addEventListener("blur",u),r.focus(),window.scrollTo(0,0)}}return(n,r)=>(a(),c(M,null,[v("span",{ref_key:"backToTop",ref:t,tabindex:"-1"},null,512),v("a",{href:"#VPContent",class:"VPSkipLink visually-hidden",onClick:s}," Skip to content ")],64))}}),dr=k(ur,[["__scopeId","data-v-c8291ffa"]]),vr=_({__name:"Layout",setup(o){const{isOpen:e,open:t,close:s}=O(),n=te();q(()=>n.path,s),bt(e,s);const{frontmatter:r}=V(),u=et(),h=g(()=>!!u["home-hero-image"]);return Te("hero-image-slot-exists",h),(p,b)=>{const P=K("Content");return i(r).layout!==!1?(a(),c("div",{key:0,class:N(["Layout",i(r).pageClass])},[l(p.$slots,"layout-top",{},void 0,!0),m(dr),m(nt,{class:"backdrop",show:i(e),onClick:i(s)},null,8,["show","onClick"]),m(Xa,null,{"nav-bar-title-before":d(()=>[l(p.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":d(()=>[l(p.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":d(()=>[l(p.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":d(()=>[l(p.$slots,"nav-bar-content-after",{},void 0,!0)]),"nav-screen-content-before":d(()=>[l(p.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":d(()=>[l(p.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3}),m(Ms,{open:i(e),onOpenMenu:i(t)},null,8,["open","onOpenMenu"]),m(cr,{open:i(e)},{"sidebar-nav-before":d(()=>[l(p.$slots,"sidebar-nav-before",{},void 0,!0)]),"sidebar-nav-after":d(()=>[l(p.$slots,"sidebar-nav-after",{},void 0,!0)]),_:3},8,["open"]),m(vs,null,{"page-top":d(()=>[l(p.$slots,"page-top",{},void 0,!0)]),"page-bottom":d(()=>[l(p.$slots,"page-bottom",{},void 0,!0)]),"not-found":d(()=>[l(p.$slots,"not-found",{},void 0,!0)]),"home-hero-before":d(()=>[l(p.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":d(()=>[l(p.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":d(()=>[l(p.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":d(()=>[l(p.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":d(()=>[l(p.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":d(()=>[l(p.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":d(()=>[l(p.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":d(()=>[l(p.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":d(()=>[l(p.$slots,"home-features-after",{},void 0,!0)]),"doc-footer-before":d(()=>[l(p.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":d(()=>[l(p.$slots,"doc-before",{},void 0,!0)]),"doc-after":d(()=>[l(p.$slots,"doc-after",{},void 0,!0)]),"doc-top":d(()=>[l(p.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":d(()=>[l(p.$slots,"doc-bottom",{},void 0,!0)]),"aside-top":d(()=>[l(p.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":d(()=>[l(p.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":d(()=>[l(p.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":d(()=>[l(p.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":d(()=>[l(p.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":d(()=>[l(p.$slots,"aside-ads-after",{},void 0,!0)]),_:3}),m(ms),l(p.$slots,"layout-bottom",{},void 0,!0)],2)):(a(),$(P,{key:1}))}}}),pr=k(vr,[["__scopeId","data-v-d8b57b2d"]]),fr={Layout:pr,enhanceApp:({app:o})=>{o.component("Badge",tt)}};export{zn as c,fr as t,V as u}; diff --git a/docs/assets/cli.md.S0KmBxg6.js b/docs/assets/cli.md.C_7YL7i5.js similarity index 90% rename from docs/assets/cli.md.S0KmBxg6.js rename to docs/assets/cli.md.C_7YL7i5.js index f4572d3..bbf2f0a 100644 --- a/docs/assets/cli.md.S0KmBxg6.js +++ b/docs/assets/cli.md.C_7YL7i5.js @@ -1 +1 @@ -import{_ as a,c as s,o as e,a4 as i}from"./chunks/framework.DZjeu1b3.js";const k=JSON.parse('{"title":"nunu命令行工具","description":"","frontmatter":{},"headers":[],"relativePath":"cli.md","filePath":"cli.md","lastUpdated":1711899770000}'),t={name:"cli.md"},n=i('

nunu命令行工具

nunu 命令行工具是一个为了协助快速开发 Golang 项目而创建的项目,通过 nunu 命令行工具, 您可以很容易的进行 Golang 项目的创建、热编译、开发、测试、和部署。

创建项目

nunu new [projectName]

启动项目

nunu run

TIP

通常情况下,nunu run 命令仅用于本地开发环境快速热编译运行使用。如果是生产环境,请使用 go build之后部署。

创建组件

nunu create [type] [handler-name]

详细命令:

bash
nunu create handler [handler-name]
bash
nunu create service [service-name]
bash
nunu create  repository [repository-name]
bash
nunu create  model [model-name]

如果你觉得每种组件单独创建太麻烦,你可以使用 nunu create all 创建所有组件。

nunu create all [name]

编译wire

nunu wire all

TIP

如果你的项目存在多个wire.go文件,而你只想编译指定的wire.go文件,你可以使用 nunu wire,然后自己选择对应的文件编译。

版本升级

nunu upgrade
',18),l=[n];function p(o,c,d,h,r,u){return e(),s("div",null,l)}const b=a(t,[["render",p]]);export{k as __pageData,b as default}; +import{_ as a,c as s,o as e,a4 as i}from"./chunks/framework.DZjeu1b3.js";const g=JSON.parse('{"title":"nunu命令行工具","description":"","frontmatter":{},"headers":[],"relativePath":"cli.md","filePath":"cli.md","lastUpdated":1711899770000}'),t={name:"cli.md"},n=i('

nunu命令行工具

nunu 命令行工具是一个为了协助快速开发 Golang 项目而创建的项目,通过 nunu 命令行工具, 您可以很容易的进行 Golang 项目的创建、热编译、开发、测试、和部署。

创建项目

nunu new [projectName]

启动项目

nunu run

TIP

通常情况下,nunu run 命令仅用于本地开发环境快速热编译运行使用。如果是生产环境,请使用 go build之后部署。

创建组件

nunu create [type] [handler-name]

详细命令:

bash
nunu create handler [handler-name]
bash
nunu create service [service-name]
bash
nunu create  repository [repository-name]
bash
nunu create  model [model-name]

如果你觉得每种组件单独创建太麻烦,你可以使用 nunu create all 创建所有组件。

nunu create all [name]

编译wire

nunu wire all

TIP

如果你的项目存在多个wire.go文件,而你只想编译指定的wire.go文件,你可以使用 nunu wire,然后自己选择对应的文件编译。

版本升级

nunu upgrade
',18),l=[n];function p(o,d,c,h,r,u){return e(),s("div",null,l)}const b=a(t,[["render",p]]);export{g as __pageData,b as default}; diff --git a/docs/assets/cli.md.S0KmBxg6.lean.js b/docs/assets/cli.md.C_7YL7i5.lean.js similarity index 51% rename from docs/assets/cli.md.S0KmBxg6.lean.js rename to docs/assets/cli.md.C_7YL7i5.lean.js index 962e710..cbb6ac5 100644 --- a/docs/assets/cli.md.S0KmBxg6.lean.js +++ b/docs/assets/cli.md.C_7YL7i5.lean.js @@ -1 +1 @@ -import{_ as a,c as s,o as e,a4 as i}from"./chunks/framework.DZjeu1b3.js";const k=JSON.parse('{"title":"nunu命令行工具","description":"","frontmatter":{},"headers":[],"relativePath":"cli.md","filePath":"cli.md","lastUpdated":1711899770000}'),t={name:"cli.md"},n=i("",18),l=[n];function p(o,c,d,h,r,u){return e(),s("div",null,l)}const b=a(t,[["render",p]]);export{k as __pageData,b as default}; +import{_ as a,c as s,o as e,a4 as i}from"./chunks/framework.DZjeu1b3.js";const g=JSON.parse('{"title":"nunu命令行工具","description":"","frontmatter":{},"headers":[],"relativePath":"cli.md","filePath":"cli.md","lastUpdated":1711899770000}'),t={name:"cli.md"},n=i("",18),l=[n];function p(o,d,c,h,r,u){return e(),s("div",null,l)}const b=a(t,[["render",p]]);export{g as __pageData,b as default}; diff --git a/docs/assets/getting-started.md.Rp5FCLxj.js b/docs/assets/getting-started.md.Be3tXPfD.js similarity index 95% rename from docs/assets/getting-started.md.Rp5FCLxj.js rename to docs/assets/getting-started.md.Be3tXPfD.js index 8421dc0..457cc5e 100644 --- a/docs/assets/getting-started.md.Rp5FCLxj.js +++ b/docs/assets/getting-started.md.Be3tXPfD.js @@ -1,2 +1,2 @@ -import{_ as e,c as t,o as n,a4 as a,m as s,a as i}from"./chunks/framework.DZjeu1b3.js";const C=JSON.parse('{"title":"快速开始","description":"","frontmatter":{},"headers":[],"relativePath":"getting-started.md","filePath":"getting-started.md","lastUpdated":1711899770000}'),l={name:"getting-started.md"},p=a(`

快速开始

安装Nunu

您可以通过以下命令安装 Nunu:

bash
go install github.com/go-nunu/nunu@latest

TIP

国内用户可以使用GOPROXY加速go install

bash
$ go env -w GO111MODULE=on
-$ go env -w GOPROXY=https://goproxy.cn,direct
如果go install成功,却提示找不到nunu命令?

这是因为环境变量没有配置,可以把 GOBIN 目录配置到环境变量中即可,GOBIN的配置方法windows、macOS、Linux各不相同,请自行网络搜索。

`,7),o=s("h2",{new:"",id:"创建新项目",tabindex:"-1"},[i("创建新项目 "),s("a",{class:"header-anchor",href:"#创建新项目","aria-label":'Permalink to "创建新项目{new}"'},"​")],-1),d=a('

在创建项目之前,我们需要了解到Nunu内置了两种类型的Layout:

  • 基础模板(Basic Layout)

    Basic Layout 包含一个非常精简的架构目录结构,适合非常熟悉Nunu项目的开发者使用。

  • 高级模板(Advanced Layout)

    Advanced Layout 包含了很多Nunu的用法示例( dbredisjwtcronmigration等),适合开发者快速学习了解Nunu的架构思想。

您可以使用以下命令创建一个新的 Golang 项目,推荐选择Advanced Layout

bash
nunu new projectName

此命令将创建一个名为 projectName 的目录,并在其中生成一个优雅的 Golang 项目结构。

国内加速源:

nunu new默认拉取github源,你也可以使用国内加速仓库

sh
$ nunu new projectName -r https://gitee.com/go-nunu/nunu-layout-advanced.git
sh
$ nunu new projectName -r https://gitee.com/go-nunu/nunu-layout-basic.git
',7),h=s("h2",{run:"",id:"启动服务",tabindex:"-1"},[i("启动服务 "),s("a",{class:"header-anchor",href:"#启动服务","aria-label":'Permalink to "启动服务{run}"'},"​")],-1),c=a('

创建好项目之后,我们进入项目执行nunu run命令即可启动服务。

nunu run cmd/server/main.go

随后打开浏览器访问http://localhost:8080即可看到欢迎页面。

API文档地址: http://127.0.0.1:8000/swagger/index.html

',4),r=[p,o,d,h,c];function k(u,g,F,_,b,v){return n(),t("div",null,r)}const m=e(l,[["render",k]]);export{C as __pageData,m as default}; +import{_ as e,c as t,o as n,a4 as a,m as s,a as i}from"./chunks/framework.DZjeu1b3.js";const m=JSON.parse('{"title":"快速开始","description":"","frontmatter":{},"headers":[],"relativePath":"getting-started.md","filePath":"getting-started.md","lastUpdated":1711899770000}'),l={name:"getting-started.md"},p=a(`

快速开始

安装Nunu

您可以通过以下命令安装 Nunu:

bash
go install github.com/go-nunu/nunu@latest

TIP

国内用户可以使用GOPROXY加速go install

bash
$ go env -w GO111MODULE=on
+$ go env -w GOPROXY=https://goproxy.cn,direct
如果go install成功,却提示找不到nunu命令?

这是因为环境变量没有配置,可以把 GOBIN 目录配置到环境变量中即可,GOBIN的配置方法windows、macOS、Linux各不相同,请自行网络搜索。

`,7),o=s("h2",{new:"",id:"创建新项目",tabindex:"-1"},[i("创建新项目 "),s("a",{class:"header-anchor",href:"#创建新项目","aria-label":'Permalink to "创建新项目{new}"'},"​")],-1),d=a('

在创建项目之前,我们需要了解到Nunu内置了两种类型的Layout:

  • 基础模板(Basic Layout)

    Basic Layout 包含一个非常精简的架构目录结构,适合非常熟悉Nunu项目的开发者使用。

  • 高级模板(Advanced Layout)

    Advanced Layout 包含了很多Nunu的用法示例( dbredisjwtcronmigration等),适合开发者快速学习了解Nunu的架构思想。

您可以使用以下命令创建一个新的 Golang 项目,推荐选择Advanced Layout

bash
nunu new projectName

此命令将创建一个名为 projectName 的目录,并在其中生成一个优雅的 Golang 项目结构。

国内加速源:

nunu new默认拉取github源,你也可以使用国内加速仓库

sh
$ nunu new projectName -r https://gitee.com/go-nunu/nunu-layout-advanced.git
sh
$ nunu new projectName -r https://gitee.com/go-nunu/nunu-layout-basic.git
',7),h=s("h2",{run:"",id:"启动服务",tabindex:"-1"},[i("启动服务 "),s("a",{class:"header-anchor",href:"#启动服务","aria-label":'Permalink to "启动服务{run}"'},"​")],-1),c=a('

创建好项目之后,我们进入项目执行nunu run命令即可启动服务。

nunu run cmd/server/main.go

随后打开浏览器访问http://localhost:8080即可看到欢迎页面。

API文档地址: http://127.0.0.1:8000/swagger/index.html

',4),r=[p,o,d,h,c];function k(u,g,F,_,b,v){return n(),t("div",null,r)}const C=e(l,[["render",k]]);export{m as __pageData,C as default}; diff --git a/docs/assets/getting-started.md.Rp5FCLxj.lean.js b/docs/assets/getting-started.md.Be3tXPfD.lean.js similarity index 84% rename from docs/assets/getting-started.md.Rp5FCLxj.lean.js rename to docs/assets/getting-started.md.Be3tXPfD.lean.js index b191f7b..5e1d667 100644 --- a/docs/assets/getting-started.md.Rp5FCLxj.lean.js +++ b/docs/assets/getting-started.md.Be3tXPfD.lean.js @@ -1 +1 @@ -import{_ as e,c as t,o as n,a4 as a,m as s,a as i}from"./chunks/framework.DZjeu1b3.js";const C=JSON.parse('{"title":"快速开始","description":"","frontmatter":{},"headers":[],"relativePath":"getting-started.md","filePath":"getting-started.md","lastUpdated":1711899770000}'),l={name:"getting-started.md"},p=a("",7),o=s("h2",{new:"",id:"创建新项目",tabindex:"-1"},[i("创建新项目 "),s("a",{class:"header-anchor",href:"#创建新项目","aria-label":'Permalink to "创建新项目{new}"'},"​")],-1),d=a("",7),h=s("h2",{run:"",id:"启动服务",tabindex:"-1"},[i("启动服务 "),s("a",{class:"header-anchor",href:"#启动服务","aria-label":'Permalink to "启动服务{run}"'},"​")],-1),c=a("",4),r=[p,o,d,h,c];function k(u,g,F,_,b,v){return n(),t("div",null,r)}const m=e(l,[["render",k]]);export{C as __pageData,m as default}; +import{_ as e,c as t,o as n,a4 as a,m as s,a as i}from"./chunks/framework.DZjeu1b3.js";const m=JSON.parse('{"title":"快速开始","description":"","frontmatter":{},"headers":[],"relativePath":"getting-started.md","filePath":"getting-started.md","lastUpdated":1711899770000}'),l={name:"getting-started.md"},p=a("",7),o=s("h2",{new:"",id:"创建新项目",tabindex:"-1"},[i("创建新项目 "),s("a",{class:"header-anchor",href:"#创建新项目","aria-label":'Permalink to "创建新项目{new}"'},"​")],-1),d=a("",7),h=s("h2",{run:"",id:"启动服务",tabindex:"-1"},[i("启动服务 "),s("a",{class:"header-anchor",href:"#启动服务","aria-label":'Permalink to "启动服务{run}"'},"​")],-1),c=a("",4),r=[p,o,d,h,c];function k(u,g,F,_,b,v){return n(),t("div",null,r)}const C=e(l,[["render",k]]);export{m as __pageData,C as default}; diff --git a/docs/assets/grpc.md.CeHujcK9.js b/docs/assets/grpc.md.CeHujcK9.js new file mode 100644 index 0000000..3ddd3fc --- /dev/null +++ b/docs/assets/grpc.md.CeHujcK9.js @@ -0,0 +1 @@ +import{_ as t,c as a,o as r,m as e,a as c}from"./chunks/framework.DZjeu1b3.js";const u=JSON.parse('{"title":"GRPC","description":"","frontmatter":{},"headers":[],"relativePath":"grpc.md","filePath":"grpc.md","lastUpdated":null}'),s={name:"grpc.md"},o=e("h1",{id:"grpc",tabindex:"-1"},[c("GRPC "),e("a",{class:"header-anchor",href:"#grpc","aria-label":'Permalink to "GRPC"'},"​")],-1),n=e("p",null,"待更新",-1),d=[o,n];function p(l,i,_,h,m,f){return r(),a("div",null,d)}const P=t(s,[["render",p]]);export{u as __pageData,P as default}; diff --git a/docs/assets/grpc.md.CeHujcK9.lean.js b/docs/assets/grpc.md.CeHujcK9.lean.js new file mode 100644 index 0000000..3ddd3fc --- /dev/null +++ b/docs/assets/grpc.md.CeHujcK9.lean.js @@ -0,0 +1 @@ +import{_ as t,c as a,o as r,m as e,a as c}from"./chunks/framework.DZjeu1b3.js";const u=JSON.parse('{"title":"GRPC","description":"","frontmatter":{},"headers":[],"relativePath":"grpc.md","filePath":"grpc.md","lastUpdated":null}'),s={name:"grpc.md"},o=e("h1",{id:"grpc",tabindex:"-1"},[c("GRPC "),e("a",{class:"header-anchor",href:"#grpc","aria-label":'Permalink to "GRPC"'},"​")],-1),n=e("p",null,"待更新",-1),d=[o,n];function p(l,i,_,h,m,f){return r(),a("div",null,d)}const P=t(s,[["render",p]]);export{u as __pageData,P as default}; diff --git a/docs/assets/http.md.Bm5lEonH.js b/docs/assets/http.md.Bm5lEonH.js new file mode 100644 index 0000000..74d24fb --- /dev/null +++ b/docs/assets/http.md.Bm5lEonH.js @@ -0,0 +1,9 @@ +import{_ as s,c as i,o as a,a4 as e}from"./chunks/framework.DZjeu1b3.js";const g=JSON.parse('{"title":"HTTP","description":"","frontmatter":{},"headers":[],"relativePath":"http.md","filePath":"http.md","lastUpdated":null}'),t={name:"http.md"},n=e(`

HTTP

用途:处理基于HTTP协议的请求和响应。

工作原理:监听指定的HTTP端口,并根据接收到的请求执行相应的操作,然后返回相应的HTTP响应。

示例应用场景:Web应用程序、API服务等。

路由定义

HTTP的路由定义非常简单,大家可以直接参考internal/server/http.go中的NewHTTPServer方法。

NewHTTPServer方法中,我们首先创建了一个gin.Engine对象,然后定义了路由规则,包括GETPOSTPUTDELETE等方法。

需要注意的是在高级Layout示例中,我们为大家定义了三个路由组,noAuthRouternoStrictAuthRouterstrictAuthRouter,他们的具体用法如下:

  1. noAuthRouter:无需认证即可访问,用于一些无需认证的接口,例如登录、注册等。
  2. noStrictAuthRouter:无需严格认证即可访问,用于一些无需严格认证的接口,例如获取用户信息等。
  3. strictAuthRouter:需要严格认证即可访问,用于一些需要严格认证的接口,例如修改用户信息等。

三个路由组是基于不同的中间件实现的,具体中间件的实现可以参考internal/middleware目录下的代码。

依赖注入Handler

HTTP模块的依赖注入非常简单,只需要在NewHTTPServer方法中传入的用到的Handler结构即可。

go
func NewHTTPServer(
+	logger *log.Logger,
+	conf *viper.Viper,
+	jwt *jwt.JWT,
+	userHandler *handler.UserHandler,
+	// 更多handler
+) *http.Server {
+	
+}
`,13),h=[n];function l(p,d,r,k,o,c){return a(),i("div",null,h)}const y=s(t,[["render",l]]);export{g as __pageData,y as default}; diff --git a/docs/assets/http.md.Bm5lEonH.lean.js b/docs/assets/http.md.Bm5lEonH.lean.js new file mode 100644 index 0000000..aef1f5a --- /dev/null +++ b/docs/assets/http.md.Bm5lEonH.lean.js @@ -0,0 +1 @@ +import{_ as s,c as i,o as a,a4 as e}from"./chunks/framework.DZjeu1b3.js";const g=JSON.parse('{"title":"HTTP","description":"","frontmatter":{},"headers":[],"relativePath":"http.md","filePath":"http.md","lastUpdated":null}'),t={name:"http.md"},n=e("",13),h=[n];function l(p,d,r,k,o,c){return a(),i("div",null,h)}const y=s(t,[["render",l]]);export{g as __pageData,y as default}; diff --git a/docs/assets/job.md.CSi1p9px.js b/docs/assets/job.md.CSi1p9px.js new file mode 100644 index 0000000..8fb0d08 --- /dev/null +++ b/docs/assets/job.md.CSi1p9px.js @@ -0,0 +1 @@ +import{_ as o,c as e,o as t,a4 as a}from"./chunks/framework.DZjeu1b3.js";const u=JSON.parse('{"title":"Job","description":"","frontmatter":{},"headers":[],"relativePath":"job.md","filePath":"job.md","lastUpdated":null}'),s={name:"job.md"},c=a('

Job

用途:处理异步任务,通常用于处理消息队列(MQ)中的消息。

工作原理:从消息队列中获取任务并执行,可以是一些需要异步处理的任务,如邮件发送、文件处理等。

示例应用场景:异步任务队列、消息驱动的系统等。

TIP

nunu支持JobHTTP server同时运行,也同样支持独立于HTTP server运行,请参考Task或是Migration的实现。

',5),r=[c];function n(d,_,i,p,l,b){return t(),e("div",null,r)}const T=o(s,[["render",n]]);export{u as __pageData,T as default}; diff --git a/docs/assets/job.md.CSi1p9px.lean.js b/docs/assets/job.md.CSi1p9px.lean.js new file mode 100644 index 0000000..5b41f17 --- /dev/null +++ b/docs/assets/job.md.CSi1p9px.lean.js @@ -0,0 +1 @@ +import{_ as o,c as e,o as t,a4 as a}from"./chunks/framework.DZjeu1b3.js";const u=JSON.parse('{"title":"Job","description":"","frontmatter":{},"headers":[],"relativePath":"job.md","filePath":"job.md","lastUpdated":null}'),s={name:"job.md"},c=a("",5),r=[c];function n(d,_,i,p,l,b){return t(),e("div",null,r)}const T=o(s,[["render",n]]);export{u as __pageData,T as default}; diff --git a/docs/assets/migration.md.BDgzs4ZZ.js b/docs/assets/migration.md.BDgzs4ZZ.js new file mode 100644 index 0000000..968c15b --- /dev/null +++ b/docs/assets/migration.md.BDgzs4ZZ.js @@ -0,0 +1 @@ +import{_ as t,c as a,o,a4 as i}from"./chunks/framework.DZjeu1b3.js";const h=JSON.parse('{"title":"Migration","description":"","frontmatter":{},"headers":[],"relativePath":"migration.md","filePath":"migration.md","lastUpdated":null}'),r={name:"migration.md"},e=i('

Migration

用途:处理数据库迁移和数据迁移任务。

工作原理:Migration服务负责管理数据库结构的变化和数据的迁移,例如在软件升级过程中,需要更新数据库模式或迁移现有数据以适应新的模式。

示例应用场景:迁移数据库表结构,例如添加新的列、删除旧的列、修改列的数据类型等。 迁移数据,例如将旧数据格式转换为新的格式、合并数据、拆分数据等。 管理数据库版本,确保数据库结构与应用程序代码的版本兼容性。

TIP

Migration须谨慎用于生成环境,以免导致数据丢失或破坏。

',5),n=[e];function s(c,_,p,l,d,g){return o(),a("div",null,n)}const u=t(r,[["render",s]]);export{h as __pageData,u as default}; diff --git a/docs/assets/migration.md.BDgzs4ZZ.lean.js b/docs/assets/migration.md.BDgzs4ZZ.lean.js new file mode 100644 index 0000000..0eb54d2 --- /dev/null +++ b/docs/assets/migration.md.BDgzs4ZZ.lean.js @@ -0,0 +1 @@ +import{_ as t,c as a,o,a4 as i}from"./chunks/framework.DZjeu1b3.js";const h=JSON.parse('{"title":"Migration","description":"","frontmatter":{},"headers":[],"relativePath":"migration.md","filePath":"migration.md","lastUpdated":null}'),r={name:"migration.md"},e=i("",5),n=[e];function s(c,_,p,l,d,g){return o(),a("div",null,n)}const u=t(r,[["render",s]]);export{h as __pageData,u as default}; diff --git a/docs/assets/server.md.BzwyYWXt.js b/docs/assets/server.md.BzwyYWXt.js new file mode 100644 index 0000000..359aaef --- /dev/null +++ b/docs/assets/server.md.BzwyYWXt.js @@ -0,0 +1,33 @@ +import{_ as s,c as i,o as a,a4 as n}from"./chunks/framework.DZjeu1b3.js";const c=JSON.parse('{"title":"Server基础概念","description":"","frontmatter":{},"headers":[],"relativePath":"server.md","filePath":"server.md","lastUpdated":1711900697000}'),h={name:"server.md"},p=n(`

Server基础概念

在Nunu中,我们将HTTPGRPCWebSocketTaskJob等服务都抽象为Server

go
type Server interface {
+	Start(context.Context) error
+	Stop(context.Context) error
+}

每个Server都必须实现Server接口中的方法,也就是Start(ctx)Stop(ctx)

服务依赖注册

在Nunu中,如果你想给你的某个服务进程注册相应的启动服务,

你只需要关心cmd/[服务器名称]/wire/wire.go文件即可。

go
var serverSet = wire.NewSet(
+	server.NewHTTPServer,
+	server.NewJob,
+	// 你想注册的其它服务
+)
+
+// build App
+func newApp(
+	httpServer *http.Server, 
+	job *server.Job,
+    // 你想注册的其它服务,需要从参数传入
+	) *app.App {
+	return app.NewApp(
+		app.WithServer(httpServer, job),
+		app.WithName("demo-server"),
+	)
+}
+
+func NewWire(*viper.Viper, *log.Logger) (*app.App, func(), error) {
+
+	panic(wire.Build(
+		repositorySet,
+		serviceSet,
+		handlerSet,
+		serverSet,  // 集中注册服务
+		sid.NewSid,
+		jwt.NewJwt,
+		newApp,
+	))
+}
`,8),t=[p];function e(k,l,r,E,d,g){return a(),i("div",null,t)}const o=s(h,[["render",e]]);export{c as __pageData,o as default}; diff --git a/docs/assets/server.md.BzwyYWXt.lean.js b/docs/assets/server.md.BzwyYWXt.lean.js new file mode 100644 index 0000000..6183090 --- /dev/null +++ b/docs/assets/server.md.BzwyYWXt.lean.js @@ -0,0 +1 @@ +import{_ as s,c as i,o as a,a4 as n}from"./chunks/framework.DZjeu1b3.js";const c=JSON.parse('{"title":"Server基础概念","description":"","frontmatter":{},"headers":[],"relativePath":"server.md","filePath":"server.md","lastUpdated":1711900697000}'),h={name:"server.md"},p=n("",8),t=[p];function e(k,l,r,E,d,g){return a(),i("div",null,t)}const o=s(h,[["render",e]]);export{c as __pageData,o as default}; diff --git a/docs/assets/server.md.yFMvW0F3.js b/docs/assets/server.md.yFMvW0F3.js deleted file mode 100644 index 42b5e38..0000000 --- a/docs/assets/server.md.yFMvW0F3.js +++ /dev/null @@ -1,4 +0,0 @@ -import{_ as s,c as e,o as a,a4 as t}from"./chunks/framework.DZjeu1b3.js";const E=JSON.parse('{"title":"Server基础概念","description":"","frontmatter":{},"headers":[],"relativePath":"server.md","filePath":"server.md","lastUpdated":1711880770000}'),i={name:"server.md"},o=t(`

Server基础概念

在Nunu中,我们将HTTPGRPCWebSocketTaskJob等服务都抽象为Server

go
type Server interface {
-	Start(context.Context) error
-	Stop(context.Context) error
-}

每个Server都必须实现Server接口中的方法,也就是Start(ctx)Stop(ctx)

HTTP

用途:处理基于HTTP协议的请求和响应。

工作原理:监听指定的HTTP端口,并根据接收到的请求执行相应的操作,然后返回相应的HTTP响应。

示例应用场景:Web应用程序、API服务等。

Task

用途:处理定时任务,类似于crontab的功能。

工作原理:定期执行预定义的任务或作业,通常用于周期性地执行一些重复性的任务。

示例应用场景:定时数据备份、定时数据清理、定时报表生成等。

TIP

定时任务建议独立于HTTP server运行,避免影响主应用程序的运行。但同时nunu支持TaskHTTP server同时运行,请参考Job的实现。

Job

用途:处理异步任务,通常用于处理消息队列(MQ)中的消息。

工作原理:从消息队列中获取任务并执行,可以是一些需要异步处理的任务,如邮件发送、文件处理等。

示例应用场景:异步任务队列、消息驱动的系统等。

TIP

nunu支持JobHTTP server同时运行,也同样支持独立于HTTP server运行,请参考Task或是Migration的实现。

Migration

用途:处理数据库迁移和数据迁移任务。

工作原理:Migration服务负责管理数据库结构的变化和数据的迁移,例如在软件升级过程中,需要更新数据库模式或迁移现有数据以适应新的模式。

示例应用场景:迁移数据库表结构,例如添加新的列、删除旧的列、修改列的数据类型等。 迁移数据,例如将旧数据格式转换为新的格式、合并数据、拆分数据等。 管理数据库版本,确保数据库结构与应用程序代码的版本兼容性。

TIP

Migration须谨慎用于生成环境,以免导致数据丢失或破坏。

`,23),r=[o];function n(p,c,d,l,h,k){return a(),e("div",null,r)}const T=s(i,[["render",n]]);export{E as __pageData,T as default}; diff --git a/docs/assets/server.md.yFMvW0F3.lean.js b/docs/assets/server.md.yFMvW0F3.lean.js deleted file mode 100644 index c5e0d3f..0000000 --- a/docs/assets/server.md.yFMvW0F3.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as s,c as e,o as a,a4 as t}from"./chunks/framework.DZjeu1b3.js";const E=JSON.parse('{"title":"Server基础概念","description":"","frontmatter":{},"headers":[],"relativePath":"server.md","filePath":"server.md","lastUpdated":1711880770000}'),i={name:"server.md"},o=t("",23),r=[o];function n(p,c,d,l,h,k){return a(),e("div",null,r)}const T=s(i,[["render",n]]);export{E as __pageData,T as default}; diff --git a/docs/assets/task.md.eQQGFK-A.js b/docs/assets/task.md.eQQGFK-A.js new file mode 100644 index 0000000..266c8eb --- /dev/null +++ b/docs/assets/task.md.eQQGFK-A.js @@ -0,0 +1 @@ +import{_ as t,c as e,o as a,a4 as s}from"./chunks/framework.DZjeu1b3.js";const m=JSON.parse('{"title":"Task","description":"","frontmatter":{},"headers":[],"relativePath":"task.md","filePath":"task.md","lastUpdated":null}'),o={name:"task.md"},c=s('

Task

用途:处理定时任务,类似于crontab的功能。

工作原理:定期执行预定义的任务或作业,通常用于周期性地执行一些重复性的任务。

示例应用场景:定时数据备份、定时数据清理、定时报表生成等。

TIP

定时任务建议独立于HTTP server运行,避免影响主应用程序的运行。但同时nunu支持TaskHTTP server同时运行,请参考Job的实现。

',5),r=[c];function n(d,_,p,i,l,k){return a(),e("div",null,r)}const u=t(o,[["render",n]]);export{m as __pageData,u as default}; diff --git a/docs/assets/task.md.eQQGFK-A.lean.js b/docs/assets/task.md.eQQGFK-A.lean.js new file mode 100644 index 0000000..33d95a4 --- /dev/null +++ b/docs/assets/task.md.eQQGFK-A.lean.js @@ -0,0 +1 @@ +import{_ as t,c as e,o as a,a4 as s}from"./chunks/framework.DZjeu1b3.js";const m=JSON.parse('{"title":"Task","description":"","frontmatter":{},"headers":[],"relativePath":"task.md","filePath":"task.md","lastUpdated":null}'),o={name:"task.md"},c=s("",5),r=[c];function n(d,_,p,i,l,k){return a(),e("div",null,r)}const u=t(o,[["render",n]]);export{m as __pageData,u as default}; diff --git a/docs/assets/websocket.md.BB9hRzFp.js b/docs/assets/websocket.md.BB9hRzFp.js new file mode 100644 index 0000000..df974ea --- /dev/null +++ b/docs/assets/websocket.md.BB9hRzFp.js @@ -0,0 +1 @@ +import{_ as t,c as a,o as s,m as e,a as o}from"./chunks/framework.DZjeu1b3.js";const f=JSON.parse('{"title":"Websocket","description":"","frontmatter":{},"headers":[],"relativePath":"websocket.md","filePath":"websocket.md","lastUpdated":null}'),c={name:"websocket.md"},r=e("h1",{id:"websocket",tabindex:"-1"},[o("Websocket "),e("a",{class:"header-anchor",href:"#websocket","aria-label":'Permalink to "Websocket"'},"​")],-1),n=e("p",null,"待更新",-1),d=[r,n];function l(i,_,p,k,b,h){return s(),a("div",null,d)}const u=t(c,[["render",l]]);export{f as __pageData,u as default}; diff --git a/docs/assets/websocket.md.BB9hRzFp.lean.js b/docs/assets/websocket.md.BB9hRzFp.lean.js new file mode 100644 index 0000000..df974ea --- /dev/null +++ b/docs/assets/websocket.md.BB9hRzFp.lean.js @@ -0,0 +1 @@ +import{_ as t,c as a,o as s,m as e,a as o}from"./chunks/framework.DZjeu1b3.js";const f=JSON.parse('{"title":"Websocket","description":"","frontmatter":{},"headers":[],"relativePath":"websocket.md","filePath":"websocket.md","lastUpdated":null}'),c={name:"websocket.md"},r=e("h1",{id:"websocket",tabindex:"-1"},[o("Websocket "),e("a",{class:"header-anchor",href:"#websocket","aria-label":'Permalink to "Websocket"'},"​")],-1),n=e("p",null,"待更新",-1),d=[r,n];function l(i,_,p,k,b,h){return s(),a("div",null,d)}const u=t(c,[["render",l]]);export{f as __pageData,u as default}; diff --git a/docs/cli.html b/docs/cli.html index 74eadaf..f6653d2 100644 --- a/docs/cli.html +++ b/docs/cli.html @@ -7,12 +7,12 @@ - - + + - - + + @@ -26,7 +26,7 @@ -
Skip to content

nunu命令行工具

nunu 命令行工具是一个为了协助快速开发 Golang 项目而创建的项目,通过 nunu 命令行工具, 您可以很容易的进行 Golang 项目的创建、热编译、开发、测试、和部署。

创建项目

nunu new [projectName]

启动项目

nunu run

TIP

通常情况下,nunu run 命令仅用于本地开发环境快速热编译运行使用。如果是生产环境,请使用 go build之后部署。

创建组件

nunu create [type] [handler-name]

详细命令:

bash
nunu create handler [handler-name]
bash
nunu create service [service-name]
bash
nunu create  repository [repository-name]
bash
nunu create  model [model-name]

如果你觉得每种组件单独创建太麻烦,你可以使用 nunu create all 创建所有组件。

nunu create all [name]

编译wire

nunu wire all

TIP

如果你的项目存在多个wire.go文件,而你只想编译指定的wire.go文件,你可以使用 nunu wire,然后自己选择对应的文件编译。

版本升级

nunu upgrade

基于 MIT 许可发布

+
Skip to content

nunu命令行工具

nunu 命令行工具是一个为了协助快速开发 Golang 项目而创建的项目,通过 nunu 命令行工具, 您可以很容易的进行 Golang 项目的创建、热编译、开发、测试、和部署。

创建项目

nunu new [projectName]

启动项目

nunu run

TIP

通常情况下,nunu run 命令仅用于本地开发环境快速热编译运行使用。如果是生产环境,请使用 go build之后部署。

创建组件

nunu create [type] [handler-name]

详细命令:

bash
nunu create handler [handler-name]
bash
nunu create service [service-name]
bash
nunu create  repository [repository-name]
bash
nunu create  model [model-name]

如果你觉得每种组件单独创建太麻烦,你可以使用 nunu create all 创建所有组件。

nunu create all [name]

编译wire

nunu wire all

TIP

如果你的项目存在多个wire.go文件,而你只想编译指定的wire.go文件,你可以使用 nunu wire,然后自己选择对应的文件编译。

版本升级

nunu upgrade

基于 MIT 许可发布

diff --git a/docs/database.html b/docs/database.html index cb119da..9b71d26 100644 --- a/docs/database.html +++ b/docs/database.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

基于 MIT 许可发布

+
Skip to content

基于 MIT 许可发布

diff --git a/docs/docker.html b/docs/docker.html index 2b6f9b4..802e922 100644 --- a/docs/docker.html +++ b/docs/docker.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Docker

镜像构建

容器运行

基于 MIT 许可发布

+
Skip to content

Docker

镜像构建

容器运行

基于 MIT 许可发布

diff --git a/docs/en/architecture.html b/docs/en/architecture.html index 2db2d92..8c4d39f 100644 --- a/docs/en/architecture.html +++ b/docs/en/architecture.html @@ -7,11 +7,11 @@ - - + + - + @@ -56,7 +56,7 @@ ├── web ├── Makefile ├── go.mod -└── go.sum
  • cmd:应用程序的入口,包含了不同的子命令。
  • config:配置文件。
  • deploy:部署相关的文件,如 Dockerfile 、 docker-compose.yml等。
  • internal:应用程序的主要代码,按照分层架构进行组织。
  • pkg:公共的代码,包括配置、日志、HTTP 等。
  • script:脚本文件,用于部署和其他自动化任务。
  • storage:存储文件,如日志文件。
  • test:测试代码。
  • web:前端代码。

internal

  • internal/handler( or controller):处理 HTTP 请求,调用业务逻辑层的服务,返回 HTTP 响应。
  • internal/server(or router):HTTP 服务器,启动 HTTP 服务,监听端口,处理 HTTP 请求。
  • internal/service(or logic):服务,实现具体的业务逻辑,调用数据访问层repository。
  • internal/model(or entity):数据模型,定义了业务逻辑层需要的数据结构。
  • internal/repository(or dao):数据访问对象,封装了数据库操作,提供了对数据的增删改查。

依赖注入

本项目采用了依赖注入框架Wire,实现了模块化和解耦。Wire通过预编译wire.go,自动生成依赖注入的代码wire_gen.go,简化了依赖注入的过程。

  • cmd/job/wire.goWire配置文件,定义了job子命令需要的依赖关系。
  • cmd/migration/wire.goWire配置文件,定义了migration子命令需要的依赖关系。
  • cmd/server/wire.goWire配置文件,定义了server子命令需要的依赖关系。

Wire官方文档:https://github.com/google/wire/blob/main/docs/guide.md

注意:wire_gen.go文件为自动编译生成,禁止手动修改

公共代码

为了实现代码的复用和统一管理,本项目采用了公共代码的方式,将一些通用的代码放在了pkg目录下。

  • pkg/config:配置文件的读取和解析。
  • pkg/helper:一些通用的辅助函数,如 MD5 加密、UUID 生成等。
  • pkg/http:HTTP 相关的代码,如 HTTP 客户端、HTTP 服务器等。
  • pkg/log:日志相关的代码,如日志的初始化、日志的写入等。
  • more...:当然,你可以自由添加扩展更多的pkg。

Released under the MIT License.

+└── go.sum
  • cmd:应用程序的入口,包含了不同的子命令。
  • config:配置文件。
  • deploy:部署相关的文件,如 Dockerfile 、 docker-compose.yml等。
  • internal:应用程序的主要代码,按照分层架构进行组织。
  • pkg:公共的代码,包括配置、日志、HTTP 等。
  • script:脚本文件,用于部署和其他自动化任务。
  • storage:存储文件,如日志文件。
  • test:测试代码。
  • web:前端代码。

internal

  • internal/handler( or controller):处理 HTTP 请求,调用业务逻辑层的服务,返回 HTTP 响应。
  • internal/server(or router):HTTP 服务器,启动 HTTP 服务,监听端口,处理 HTTP 请求。
  • internal/service(or logic):服务,实现具体的业务逻辑,调用数据访问层repository。
  • internal/model(or entity):数据模型,定义了业务逻辑层需要的数据结构。
  • internal/repository(or dao):数据访问对象,封装了数据库操作,提供了对数据的增删改查。

依赖注入

本项目采用了依赖注入框架Wire,实现了模块化和解耦。Wire通过预编译wire.go,自动生成依赖注入的代码wire_gen.go,简化了依赖注入的过程。

  • cmd/job/wire.goWire配置文件,定义了job子命令需要的依赖关系。
  • cmd/migration/wire.goWire配置文件,定义了migration子命令需要的依赖关系。
  • cmd/server/wire.goWire配置文件,定义了server子命令需要的依赖关系。

Wire官方文档:https://github.com/google/wire/blob/main/docs/guide.md

注意:wire_gen.go文件为自动编译生成,禁止手动修改

公共代码

为了实现代码的复用和统一管理,本项目采用了公共代码的方式,将一些通用的代码放在了pkg目录下。

  • pkg/config:配置文件的读取和解析。
  • pkg/helper:一些通用的辅助函数,如 MD5 加密、UUID 生成等。
  • pkg/http:HTTP 相关的代码,如 HTTP 客户端、HTTP 服务器等。
  • pkg/log:日志相关的代码,如日志的初始化、日志的写入等。
  • more...:当然,你可以自由添加扩展更多的pkg。

Released under the MIT License.

diff --git a/docs/en/cli.html b/docs/en/cli.html index 94a1ea9..7f8adb7 100644 --- a/docs/en/cli.html +++ b/docs/en/cli.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

nunu命令行工具

nunu 命令行工具是一个为了协助快速开发 Golang 项目而创建的项目,通过 nunu 命令行工具, 您可以很容易的进行 Golang 项目的创建、热编译、开发、测试、和部署。

创建项目

nunu new [projectName]

启动项目

nunu run

创建组件

nunu create [type] [handler-name]

创建handler

nunu create handler [handler-name]

编译wire

nunu wire all

版本升级

nunu upgrade

Released under the MIT License.

+
Skip to content

nunu命令行工具

nunu 命令行工具是一个为了协助快速开发 Golang 项目而创建的项目,通过 nunu 命令行工具, 您可以很容易的进行 Golang 项目的创建、热编译、开发、测试、和部署。

创建项目

nunu new [projectName]

启动项目

nunu run

创建组件

nunu create [type] [handler-name]

创建handler

nunu create handler [handler-name]

编译wire

nunu wire all

版本升级

nunu upgrade

Released under the MIT License.

diff --git a/docs/en/database.html b/docs/en/database.html index eafe653..2d1689a 100644 --- a/docs/en/database.html +++ b/docs/en/database.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/en/docker.html b/docs/en/docker.html index 15c0531..0cdc864 100644 --- a/docs/en/docker.html +++ b/docs/en/docker.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Docker

镜像构建

容器运行

Released under the MIT License.

+
Skip to content

Docker

镜像构建

容器运行

Released under the MIT License.

diff --git a/docs/en/foo.html b/docs/en/foo.html index 7fb74f6..4fea141 100644 --- a/docs/en/foo.html +++ b/docs/en/foo.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/en/getting-started.html b/docs/en/getting-started.html index 5571f6c..8e78f5c 100644 --- a/docs/en/getting-started.html +++ b/docs/en/getting-started.html @@ -7,11 +7,11 @@ - - + + - + @@ -33,7 +33,7 @@ nunu new projectName -r https://gitee.com/go-nunu/nunu-layout-advanced.git // 使用基础模板 -nunu new projectName -r https://gitee.com/go-nunu/nunu-layout-basic.git

Nunu内置了两种类型的Layout:

  • 基础模板(Basic Layout)

    Basic Layout 包含一个非常精简的架构目录结构,适合非常熟悉Nunu项目的开发者使用。

  • 高级模板(Advanced Layout)

    Advanced Layout 包含了很多Nunu的用法示例( db、redis、 jwt、 cron、 migration等),适合开发者快速学习了解Nunu的架构思想。

    建议:我们推荐新手优先选择使用Advanced Layout。

启动服务

创建好项目之后,我们进入项目执行nunu run命令即可启动服务。

nunu run cmd/server/main.go

随后打开浏览器访问http://localhost:8080即可看到欢迎页面。

API文档地址: http://127.0.0.1:8000/swagger/index.html

Released under the MIT License.

+nunu new projectName -r https://gitee.com/go-nunu/nunu-layout-basic.git

Nunu内置了两种类型的Layout:

  • 基础模板(Basic Layout)

    Basic Layout 包含一个非常精简的架构目录结构,适合非常熟悉Nunu项目的开发者使用。

  • 高级模板(Advanced Layout)

    Advanced Layout 包含了很多Nunu的用法示例( db、redis、 jwt、 cron、 migration等),适合开发者快速学习了解Nunu的架构思想。

    建议:我们推荐新手优先选择使用Advanced Layout。

启动服务

创建好项目之后,我们进入项目执行nunu run命令即可启动服务。

nunu run cmd/server/main.go

随后打开浏览器访问http://localhost:8080即可看到欢迎页面。

API文档地址: http://127.0.0.1:8000/swagger/index.html

Released under the MIT License.

diff --git a/docs/en/guide.html b/docs/en/guide.html index 1bae5d6..e47f612 100644 --- a/docs/en/guide.html +++ b/docs/en/guide.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Nunu 是什么?

Nunu是一个基于Golang的应用脚手架,它的名字来自于英雄联盟中的游戏角色,一个骑在雪怪肩膀上的小男孩。和努努一样,该项目也是站在巨人的肩膀上,它是由Golang生态中各种非常流行的库整合而成的,它们的组合可以帮助你快速构建一个高效、可靠的应用程序。

只是想尝试一下?跳到快速开始

开发体验

Nunu 旨在Golang项目开发时提供出色的开发体验。

  • 超低学习成本和定制:Nunu封装了Gopher最熟悉的一些流行库。您可以轻松定制应用程序以满足特定需求。

  • 模块化和可扩展:Nunu旨在具有模块化和可扩展性。您可以通过使用第三方库或编写自己的模块轻松添加新功能和功能。

  • 文档完善和测试完备:Nunu文档完善,测试完备。它提供了全面的文档和示例,帮助您快速入门。它还包括一套测试套件,确保您的应用程序按预期工作。

性能

  • 高性能Gin

    Gin是一个Go(又称为Golang)语言编写的Web框架,以其轻量级和高性能著称。

  • 无损的依赖注入

    wire不是在运行时通过反射动态地进行依赖注入,而是在编译期通过静态代码生成的方式达成这个目的。

  • 轻度的组件封装

    Nunu没有过度的封装一些常用组件,而是简洁直观的导入第三方包,保证原生组件的性能与稳定性。

Released under the MIT License.

+
Skip to content

Nunu 是什么?

Nunu是一个基于Golang的应用脚手架,它的名字来自于英雄联盟中的游戏角色,一个骑在雪怪肩膀上的小男孩。和努努一样,该项目也是站在巨人的肩膀上,它是由Golang生态中各种非常流行的库整合而成的,它们的组合可以帮助你快速构建一个高效、可靠的应用程序。

只是想尝试一下?跳到快速开始

开发体验

Nunu 旨在Golang项目开发时提供出色的开发体验。

  • 超低学习成本和定制:Nunu封装了Gopher最熟悉的一些流行库。您可以轻松定制应用程序以满足特定需求。

  • 模块化和可扩展:Nunu旨在具有模块化和可扩展性。您可以通过使用第三方库或编写自己的模块轻松添加新功能和功能。

  • 文档完善和测试完备:Nunu文档完善,测试完备。它提供了全面的文档和示例,帮助您快速入门。它还包括一套测试套件,确保您的应用程序按预期工作。

性能

  • 高性能Gin

    Gin是一个Go(又称为Golang)语言编写的Web框架,以其轻量级和高性能著称。

  • 无损的依赖注入

    wire不是在运行时通过反射动态地进行依赖注入,而是在编译期通过静态代码生成的方式达成这个目的。

  • 轻度的组件封装

    Nunu没有过度的封装一些常用组件,而是简洁直观的导入第三方包,保证原生组件的性能与稳定性。

Released under the MIT License.

diff --git a/docs/en/handler.html b/docs/en/handler.html index fa5aac6..db12dd7 100644 --- a/docs/en/handler.html +++ b/docs/en/handler.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/en/index.html b/docs/en/index.html index 3de0af9..ee233d7 100644 --- a/docs/en/index.html +++ b/docs/en/index.html @@ -7,11 +7,11 @@ - - + + - + diff --git a/docs/en/k8s.html b/docs/en/k8s.html index efd4e71..4a8ccbd 100644 --- a/docs/en/k8s.html +++ b/docs/en/k8s.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/en/logger.html b/docs/en/logger.html index 13822ef..166acdf 100644 --- a/docs/en/logger.html +++ b/docs/en/logger.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/en/middleware.html b/docs/en/middleware.html index 08b7eaf..9449b48 100644 --- a/docs/en/middleware.html +++ b/docs/en/middleware.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

HTTP中间件

限流器

日志Trace

签名验证

跨域

Released under the MIT License.

+
Skip to content

HTTP中间件

限流器

日志Trace

签名验证

跨域

Released under the MIT License.

diff --git a/docs/en/model.html b/docs/en/model.html index b45823a..f35a1b2 100644 --- a/docs/en/model.html +++ b/docs/en/model.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/en/nginx.html b/docs/en/nginx.html index 8bf160e..6322630 100644 --- a/docs/en/nginx.html +++ b/docs/en/nginx.html @@ -7,11 +7,11 @@ - - + + - + @@ -60,7 +60,7 @@ proxy_redirect off; proxy_buffering off; } -}

Released under the MIT License.

+}

Released under the MIT License.

diff --git a/docs/en/pkg.html b/docs/en/pkg.html index 58c5ba7..e85695c 100644 --- a/docs/en/pkg.html +++ b/docs/en/pkg.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/en/pr.html b/docs/en/pr.html index 681c656..760691a 100644 --- a/docs/en/pr.html +++ b/docs/en/pr.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/en/redis.html b/docs/en/redis.html index 7c87de8..e8c5a22 100644 --- a/docs/en/redis.html +++ b/docs/en/redis.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/en/repository.html b/docs/en/repository.html index 549c9f4..9f3ef2d 100644 --- a/docs/en/repository.html +++ b/docs/en/repository.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/en/server.html b/docs/en/server.html index 71059a7..789c6d7 100644 --- a/docs/en/server.html +++ b/docs/en/server.html @@ -7,11 +7,11 @@ - - + + - + @@ -29,7 +29,7 @@
Skip to content

Server基础概念

在Nunu中,我们将HTTPGRPCWebSocketTaskJob等服务都抽象为Server

go
type Server interface {
 	Start(context.Context) error
 	Stop(context.Context) error
-}

每个Server都必须实现Server接口中的方法,也就是Start(ctx)Stop(ctx)

HTTP

HTTP服务,我们使用gin作为HTTP框架,ginEngine实现了Server接口,因此,我们只需要将Engine作为Server即可。

Task

Task服务,我们使用cron作为Task框架,cronCron实现了Server接口,因此,我们只需要将Cron作为Server即可。

Job

Job服务,我们使用cron作为Job框架,cronCron实现了Server接口,因此,我们只需要将Cron作为Server即可。

Migration

Migration服务,我们使用migrate作为Migration框架,migrateMigrate实现了Server接口,因此,我们只需要将Migrate作为Server即可。

Released under the MIT License.

+}

每个Server都必须实现Server接口中的方法,也就是Start(ctx)Stop(ctx)

HTTP

HTTP服务,我们使用gin作为HTTP框架,ginEngine实现了Server接口,因此,我们只需要将Engine作为Server即可。

Task

Task服务,我们使用cron作为Task框架,cronCron实现了Server接口,因此,我们只需要将Cron作为Server即可。

Job

Job服务,我们使用cron作为Job框架,cronCron实现了Server接口,因此,我们只需要将Cron作为Server即可。

Migration

Migration服务,我们使用migrate作为Migration框架,migrateMigrate实现了Server接口,因此,我们只需要将Migrate作为Server即可。

Released under the MIT License.

diff --git a/docs/en/service.html b/docs/en/service.html index 9b1c97a..83c0e6a 100644 --- a/docs/en/service.html +++ b/docs/en/service.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/en/swagger.html b/docs/en/swagger.html index bb1dc23..210a245 100644 --- a/docs/en/swagger.html +++ b/docs/en/swagger.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/en/swarm.html b/docs/en/swarm.html index 8392311..41daa2b 100644 --- a/docs/en/swarm.html +++ b/docs/en/swarm.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Docker Swarm集群部署

swarm.yml配置

滚动更新

Released under the MIT License.

+
Skip to content

Docker Swarm集群部署

swarm.yml配置

滚动更新

Released under the MIT License.

diff --git a/docs/en/unit-test.html b/docs/en/unit-test.html index b0a9d84..4fc491d 100644 --- a/docs/en/unit-test.html +++ b/docs/en/unit-test.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/en/wire.html b/docs/en/wire.html index 73e4036..4608654 100644 --- a/docs/en/wire.html +++ b/docs/en/wire.html @@ -7,11 +7,11 @@ - - + + - + @@ -158,7 +158,7 @@ jwt.NewJwt, newApp, )) -}

想学习更多关于Wire知识?前往到Wire官方文档

Released under the MIT License.

+}

想学习更多关于Wire知识?前往到Wire官方文档

Released under the MIT License.

diff --git a/docs/foo.html b/docs/foo.html index 5bf8759..b7f773c 100644 --- a/docs/foo.html +++ b/docs/foo.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

基于 MIT 许可发布

+
Skip to content

基于 MIT 许可发布

diff --git a/docs/getting-started.html b/docs/getting-started.html index 4b896dc..7175143 100644 --- a/docs/getting-started.html +++ b/docs/getting-started.html @@ -7,12 +7,12 @@ - - + + - - + + @@ -26,8 +26,8 @@ -
Skip to content

快速开始

安装Nunu

您可以通过以下命令安装 Nunu:

bash
go install github.com/go-nunu/nunu@latest

TIP

国内用户可以使用GOPROXY加速go install

bash
$ go env -w GO111MODULE=on
-$ go env -w GOPROXY=https://goproxy.cn,direct
如果go install成功,却提示找不到nunu命令?

这是因为环境变量没有配置,可以把 GOBIN 目录配置到环境变量中即可,GOBIN的配置方法windows、macOS、Linux各不相同,请自行网络搜索。

创建新项目

在创建项目之前,我们需要了解到Nunu内置了两种类型的Layout:

  • 基础模板(Basic Layout)

    Basic Layout 包含一个非常精简的架构目录结构,适合非常熟悉Nunu项目的开发者使用。

  • 高级模板(Advanced Layout)

    Advanced Layout 包含了很多Nunu的用法示例( dbredisjwtcronmigration等),适合开发者快速学习了解Nunu的架构思想。

您可以使用以下命令创建一个新的 Golang 项目,推荐选择Advanced Layout

bash
nunu new projectName

此命令将创建一个名为 projectName 的目录,并在其中生成一个优雅的 Golang 项目结构。

国内加速源:

nunu new默认拉取github源,你也可以使用国内加速仓库

sh
$ nunu new projectName -r https://gitee.com/go-nunu/nunu-layout-advanced.git
sh
$ nunu new projectName -r https://gitee.com/go-nunu/nunu-layout-basic.git

启动服务

创建好项目之后,我们进入项目执行nunu run命令即可启动服务。

nunu run cmd/server/main.go

随后打开浏览器访问http://localhost:8080即可看到欢迎页面。

API文档地址: http://127.0.0.1:8000/swagger/index.html

基于 MIT 许可发布

+
Skip to content

快速开始

安装Nunu

您可以通过以下命令安装 Nunu:

bash
go install github.com/go-nunu/nunu@latest

TIP

国内用户可以使用GOPROXY加速go install

bash
$ go env -w GO111MODULE=on
+$ go env -w GOPROXY=https://goproxy.cn,direct
如果go install成功,却提示找不到nunu命令?

这是因为环境变量没有配置,可以把 GOBIN 目录配置到环境变量中即可,GOBIN的配置方法windows、macOS、Linux各不相同,请自行网络搜索。

创建新项目

在创建项目之前,我们需要了解到Nunu内置了两种类型的Layout:

  • 基础模板(Basic Layout)

    Basic Layout 包含一个非常精简的架构目录结构,适合非常熟悉Nunu项目的开发者使用。

  • 高级模板(Advanced Layout)

    Advanced Layout 包含了很多Nunu的用法示例( dbredisjwtcronmigration等),适合开发者快速学习了解Nunu的架构思想。

您可以使用以下命令创建一个新的 Golang 项目,推荐选择Advanced Layout

bash
nunu new projectName

此命令将创建一个名为 projectName 的目录,并在其中生成一个优雅的 Golang 项目结构。

国内加速源:

nunu new默认拉取github源,你也可以使用国内加速仓库

sh
$ nunu new projectName -r https://gitee.com/go-nunu/nunu-layout-advanced.git
sh
$ nunu new projectName -r https://gitee.com/go-nunu/nunu-layout-basic.git

启动服务

创建好项目之后,我们进入项目执行nunu run命令即可启动服务。

nunu run cmd/server/main.go

随后打开浏览器访问http://localhost:8080即可看到欢迎页面。

API文档地址: http://127.0.0.1:8000/swagger/index.html

基于 MIT 许可发布

diff --git a/docs/grpc.html b/docs/grpc.html new file mode 100644 index 0000000..3d6f56a --- /dev/null +++ b/docs/grpc.html @@ -0,0 +1,33 @@ + + + + + + GRPC | Nunu文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/guide.html b/docs/guide.html index c5c486b..330f61a 100644 --- a/docs/guide.html +++ b/docs/guide.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Nunu 是什么?

Nunu是一个基于Golang的应用脚手架,它的名字来自于英雄联盟中的游戏角色,一个骑在雪怪肩膀上的小男孩。和努努一样,该项目也是站在巨人的肩膀上,它是由Golang生态中各种非常流行的库整合而成的,它们的组合可以帮助你快速构建一个高效、可靠的应用程序。

只是想尝试一下?跳到快速开始

开发体验

Nunu 旨在Golang项目开发时提供出色的开发体验。

  • 超低学习成本和定制:Nunu封装了Gopher最熟悉的一些流行库。您可以轻松定制应用程序以满足特定需求。

  • 模块化和可扩展:Nunu旨在具有模块化和可扩展性。您可以通过使用第三方库或编写自己的模块轻松添加新功能和功能。

  • 文档完善和测试完备:Nunu文档完善,测试完备。它提供了全面的文档和示例,帮助您快速入门。它还包括一套测试套件,确保您的应用程序按预期工作。

性能

  • 高性能Gin

    Gin是一个Go(又称为Golang)语言编写的Web框架,以其轻量级和高性能著称。

  • 无损的依赖注入

    wire不是在运行时通过反射动态地进行依赖注入,而是在编译期通过静态代码生成的方式达成这个目的。

  • 轻度的组件封装

    Nunu没有过度的封装一些常用组件,而是简洁直观的导入第三方包,保证原生组件的性能与稳定性。

基于 MIT 许可发布

+
Skip to content

Nunu 是什么?

Nunu是一个基于Golang的应用脚手架,它的名字来自于英雄联盟中的游戏角色,一个骑在雪怪肩膀上的小男孩。和努努一样,该项目也是站在巨人的肩膀上,它是由Golang生态中各种非常流行的库整合而成的,它们的组合可以帮助你快速构建一个高效、可靠的应用程序。

只是想尝试一下?跳到快速开始

开发体验

Nunu 旨在Golang项目开发时提供出色的开发体验。

  • 超低学习成本和定制:Nunu封装了Gopher最熟悉的一些流行库。您可以轻松定制应用程序以满足特定需求。

  • 模块化和可扩展:Nunu旨在具有模块化和可扩展性。您可以通过使用第三方库或编写自己的模块轻松添加新功能和功能。

  • 文档完善和测试完备:Nunu文档完善,测试完备。它提供了全面的文档和示例,帮助您快速入门。它还包括一套测试套件,确保您的应用程序按预期工作。

性能

  • 高性能Gin

    Gin是一个Go(又称为Golang)语言编写的Web框架,以其轻量级和高性能著称。

  • 无损的依赖注入

    wire不是在运行时通过反射动态地进行依赖注入,而是在编译期通过静态代码生成的方式达成这个目的。

  • 轻度的组件封装

    Nunu没有过度的封装一些常用组件,而是简洁直观的导入第三方包,保证原生组件的性能与稳定性。

基于 MIT 许可发布

diff --git a/docs/handler.html b/docs/handler.html index c5a00b7..3699efe 100644 --- a/docs/handler.html +++ b/docs/handler.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

基于 MIT 许可发布

+
Skip to content

基于 MIT 许可发布

diff --git a/docs/hashmap.json b/docs/hashmap.json index 6017f6a..90c0f0f 100644 --- a/docs/hashmap.json +++ b/docs/hashmap.json @@ -1 +1 @@ -{"en_k8s.md":"Bf7IRt2E","en_pr.md":"BUl97Mle","en_nginx.md":"Cdwn9QPG","en_service.md":"B6Xeobs8","en_redis.md":"BPYVtQJ-","en_swagger.md":"DfK3tpcG","en_swarm.md":"B8V6dVOc","en_server.md":"x1HgIoWO","k8s.md":"CKw5c3qk","logger.md":"BjAvD1b-","model.md":"CtEMf_iw","guide.md":"FsIHc0Yq","pkg.md":"XaeMkPOK","getting-started.md":"Rp5FCLxj","handler.md":"DlTcmCMk","middleware.md":"BucLSlWV","repository.md":"BVt8EdIP","swagger.md":"DwcePXpx","server.md":"yFMvW0F3","nginx.md":"CNytBq53","swarm.md":"BoMXP0pg","en_foo.md":"CkNjfvFo","service.md":"B33dDhec","en_getting-started.md":"birFKQxq","unit-test.md":"EIdK7f17","en_architecture.md":"DxTxjdVP","architecture.md":"Do2lxe98","database.md":"B3cyEJAk","docker.md":"23k_eWTm","cli.md":"S0KmBxg6","en_cli.md":"pVdAeU-p","en_logger.md":"BWTEHexG","en_unit-test.md":"DJ01aLkm","en_middleware.md":"D5W_0TF7","en_index.md":"5qRl7FvM","en_docker.md":"B7GrNYhN","en_model.md":"B5_e_RC5","en_guide.md":"CUzigoVU","en_repository.md":"BrJQ6M7L","foo.md":"C1aJzGpm","redis.md":"DfPTQc6m","pr.md":"CuXISoCC","index.md":"DelroEap","en_pkg.md":"Cud4pRCk","en_wire.md":"Tbcn3on1","en_database.md":"Dzwg1sQz","en_handler.md":"BlryHOpn","wire.md":"DAPteEAd"} +{"en_cli.md":"pVdAeU-p","database.md":"B3cyEJAk","docker.md":"23k_eWTm","en_architecture.md":"DxTxjdVP","en_database.md":"Dzwg1sQz","en_docker.md":"B7GrNYhN","en_model.md":"B5_e_RC5","k8s.md":"CKw5c3qk","guide.md":"FsIHc0Yq","logger.md":"BjAvD1b-","en_k8s.md":"Bf7IRt2E","swagger.md":"DwcePXpx","handler.md":"DlTcmCMk","en_index.md":"5qRl7FvM","index.md":"DelroEap","service.md":"B33dDhec","en_handler.md":"BlryHOpn","architecture.md":"Do2lxe98","en_swagger.md":"DfK3tpcG","en_pkg.md":"Cud4pRCk","cli.md":"C_7YL7i5","en_guide.md":"CUzigoVU","en_getting-started.md":"birFKQxq","en_unit-test.md":"DJ01aLkm","en_logger.md":"BWTEHexG","grpc.md":"CeHujcK9","getting-started.md":"Be3tXPfD","en_nginx.md":"Cdwn9QPG","en_foo.md":"CkNjfvFo","server.md":"BzwyYWXt","pkg.md":"XaeMkPOK","task.md":"eQQGFK-A","middleware.md":"BucLSlWV","nginx.md":"CNytBq53","swarm.md":"BoMXP0pg","migration.md":"BDgzs4ZZ","redis.md":"DfPTQc6m","websocket.md":"BB9hRzFp","pr.md":"CuXISoCC","en_swarm.md":"B8V6dVOc","http.md":"Bm5lEonH","en_redis.md":"BPYVtQJ-","job.md":"CSi1p9px","unit-test.md":"EIdK7f17","en_pr.md":"BUl97Mle","model.md":"CtEMf_iw","en_repository.md":"BrJQ6M7L","en_middleware.md":"D5W_0TF7","repository.md":"BVt8EdIP","wire.md":"DAPteEAd","en_service.md":"B6Xeobs8","foo.md":"C1aJzGpm","en_wire.md":"Tbcn3on1","en_server.md":"x1HgIoWO"} diff --git a/docs/http.html b/docs/http.html new file mode 100644 index 0000000..66b6e82 --- /dev/null +++ b/docs/http.html @@ -0,0 +1,41 @@ + + + + + + HTTP | Nunu文档 + + + + + + + + + + + + + + + + + + + + + + +
Skip to content

HTTP

用途:处理基于HTTP协议的请求和响应。

工作原理:监听指定的HTTP端口,并根据接收到的请求执行相应的操作,然后返回相应的HTTP响应。

示例应用场景:Web应用程序、API服务等。

路由定义

HTTP的路由定义非常简单,大家可以直接参考internal/server/http.go中的NewHTTPServer方法。

NewHTTPServer方法中,我们首先创建了一个gin.Engine对象,然后定义了路由规则,包括GETPOSTPUTDELETE等方法。

需要注意的是在高级Layout示例中,我们为大家定义了三个路由组,noAuthRouternoStrictAuthRouterstrictAuthRouter,他们的具体用法如下:

  1. noAuthRouter:无需认证即可访问,用于一些无需认证的接口,例如登录、注册等。
  2. noStrictAuthRouter:无需严格认证即可访问,用于一些无需严格认证的接口,例如获取用户信息等。
  3. strictAuthRouter:需要严格认证即可访问,用于一些需要严格认证的接口,例如修改用户信息等。

三个路由组是基于不同的中间件实现的,具体中间件的实现可以参考internal/middleware目录下的代码。

依赖注入Handler

HTTP模块的依赖注入非常简单,只需要在NewHTTPServer方法中传入的用到的Handler结构即可。

go
func NewHTTPServer(
+	logger *log.Logger,
+	conf *viper.Viper,
+	jwt *jwt.JWT,
+	userHandler *handler.UserHandler,
+	// 更多handler
+) *http.Server {
+	
+}

基于 MIT 许可发布

+ + + + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index bb43352..8965664 100644 --- a/docs/index.html +++ b/docs/index.html @@ -7,11 +7,11 @@ - - + + - + diff --git a/docs/job.html b/docs/job.html new file mode 100644 index 0000000..9dc6a35 --- /dev/null +++ b/docs/job.html @@ -0,0 +1,33 @@ + + + + + + Job | Nunu文档 + + + + + + + + + + + + + + + + + + + + + + +
Skip to content

Job

用途:处理异步任务,通常用于处理消息队列(MQ)中的消息。

工作原理:从消息队列中获取任务并执行,可以是一些需要异步处理的任务,如邮件发送、文件处理等。

示例应用场景:异步任务队列、消息驱动的系统等。

TIP

nunu支持JobHTTP server同时运行,也同样支持独立于HTTP server运行,请参考Task或是Migration的实现。

基于 MIT 许可发布

+ + + + \ No newline at end of file diff --git a/docs/k8s.html b/docs/k8s.html index 8c35927..d33e34b 100644 --- a/docs/k8s.html +++ b/docs/k8s.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

基于 MIT 许可发布

+
Skip to content

基于 MIT 许可发布

diff --git a/docs/logger.html b/docs/logger.html index a449a97..44cade3 100644 --- a/docs/logger.html +++ b/docs/logger.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

基于 MIT 许可发布

+
Skip to content

基于 MIT 许可发布

diff --git a/docs/middleware.html b/docs/middleware.html index 7c57d1e..f381982 100644 --- a/docs/middleware.html +++ b/docs/middleware.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

HTTP中间件

限流器

日志Trace

签名验证

跨域

基于 MIT 许可发布

+
Skip to content

HTTP中间件

限流器

日志Trace

签名验证

跨域

基于 MIT 许可发布

diff --git a/docs/migration.html b/docs/migration.html new file mode 100644 index 0000000..14b3a32 --- /dev/null +++ b/docs/migration.html @@ -0,0 +1,33 @@ + + + + + + Migration | Nunu文档 + + + + + + + + + + + + + + + + + + + + + + +
Skip to content

Migration

用途:处理数据库迁移和数据迁移任务。

工作原理:Migration服务负责管理数据库结构的变化和数据的迁移,例如在软件升级过程中,需要更新数据库模式或迁移现有数据以适应新的模式。

示例应用场景:迁移数据库表结构,例如添加新的列、删除旧的列、修改列的数据类型等。 迁移数据,例如将旧数据格式转换为新的格式、合并数据、拆分数据等。 管理数据库版本,确保数据库结构与应用程序代码的版本兼容性。

TIP

Migration须谨慎用于生成环境,以免导致数据丢失或破坏。

基于 MIT 许可发布

+ + + + \ No newline at end of file diff --git a/docs/model.html b/docs/model.html index 675d664..b0f78ab 100644 --- a/docs/model.html +++ b/docs/model.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

基于 MIT 许可发布

+
Skip to content

基于 MIT 许可发布

diff --git a/docs/nginx.html b/docs/nginx.html index b0581a7..ae1ff69 100644 --- a/docs/nginx.html +++ b/docs/nginx.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

非容器部署(PM2+Nginx)

PM2

pm2 是一个进程管理器,可以管理后端服务进程,还可以可以监控进程状态、查看进程日志以及资源占用情况等信息。 安装PM2 由于PM2依赖于nodejs,所以需要在你的服务器先安装nodejs

然后直接使用npm安装PM2即可

npm i -g install pm2

在项目根目录,创建pm2配置文件pm2.json

json
{
+    
Skip to content

非容器部署(PM2+Nginx)

PM2

pm2 是一个进程管理器,可以管理后端服务进程,还可以可以监控进程状态、查看进程日志以及资源占用情况等信息。 安装PM2 由于PM2依赖于nodejs,所以需要在你的服务器先安装nodejs

然后直接使用npm安装PM2即可

npm i -g install pm2

在项目根目录,创建pm2配置文件pm2.json

json
{
   "apps": [
     {
       "name": "nunu-api",
@@ -60,7 +60,7 @@
       proxy_redirect      off;
       proxy_buffering off;
     }
-}

基于 MIT 许可发布

+}

基于 MIT 许可发布

diff --git a/docs/pkg.html b/docs/pkg.html index 6139b35..364cf3d 100644 --- a/docs/pkg.html +++ b/docs/pkg.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

基于 MIT 许可发布

+
Skip to content

基于 MIT 许可发布

diff --git a/docs/pr.html b/docs/pr.html index 418f861..9e3d6eb 100644 --- a/docs/pr.html +++ b/docs/pr.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

贡献指南

基于 MIT 许可发布

+
Skip to content

贡献指南

基于 MIT 许可发布

diff --git a/docs/redis.html b/docs/redis.html index cf95290..601b15c 100644 --- a/docs/redis.html +++ b/docs/redis.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

基于 MIT 许可发布

+
Skip to content

基于 MIT 许可发布

diff --git a/docs/repository.html b/docs/repository.html index ba895fd..46130cb 100644 --- a/docs/repository.html +++ b/docs/repository.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

基于 MIT 许可发布

+
Skip to content

基于 MIT 许可发布

diff --git a/docs/server.html b/docs/server.html index 7496c33..87f5bf6 100644 --- a/docs/server.html +++ b/docs/server.html @@ -7,12 +7,12 @@ - - + + - - + + @@ -26,10 +26,39 @@ -
Skip to content

Server基础概念

在Nunu中,我们将HTTPGRPCWebSocketTaskJob等服务都抽象为Server

go
type Server interface {
+    
Skip to content

Server基础概念

在Nunu中,我们将HTTPGRPCWebSocketTaskJob等服务都抽象为Server

go
type Server interface {
 	Start(context.Context) error
 	Stop(context.Context) error
-}

每个Server都必须实现Server接口中的方法,也就是Start(ctx)Stop(ctx)

HTTP

用途:处理基于HTTP协议的请求和响应。

工作原理:监听指定的HTTP端口,并根据接收到的请求执行相应的操作,然后返回相应的HTTP响应。

示例应用场景:Web应用程序、API服务等。

Task

用途:处理定时任务,类似于crontab的功能。

工作原理:定期执行预定义的任务或作业,通常用于周期性地执行一些重复性的任务。

示例应用场景:定时数据备份、定时数据清理、定时报表生成等。

TIP

定时任务建议独立于HTTP server运行,避免影响主应用程序的运行。但同时nunu支持TaskHTTP server同时运行,请参考Job的实现。

Job

用途:处理异步任务,通常用于处理消息队列(MQ)中的消息。

工作原理:从消息队列中获取任务并执行,可以是一些需要异步处理的任务,如邮件发送、文件处理等。

示例应用场景:异步任务队列、消息驱动的系统等。

TIP

nunu支持JobHTTP server同时运行,也同样支持独立于HTTP server运行,请参考Task或是Migration的实现。

Migration

用途:处理数据库迁移和数据迁移任务。

工作原理:Migration服务负责管理数据库结构的变化和数据的迁移,例如在软件升级过程中,需要更新数据库模式或迁移现有数据以适应新的模式。

示例应用场景:迁移数据库表结构,例如添加新的列、删除旧的列、修改列的数据类型等。 迁移数据,例如将旧数据格式转换为新的格式、合并数据、拆分数据等。 管理数据库版本,确保数据库结构与应用程序代码的版本兼容性。

TIP

Migration须谨慎用于生成环境,以免导致数据丢失或破坏。

基于 MIT 许可发布

+}

每个Server都必须实现Server接口中的方法,也就是Start(ctx)Stop(ctx)

服务依赖注册

在Nunu中,如果你想给你的某个服务进程注册相应的启动服务,

你只需要关心cmd/[服务器名称]/wire/wire.go文件即可。

go
var serverSet = wire.NewSet(
+	server.NewHTTPServer,
+	server.NewJob,
+	// 你想注册的其它服务
+)
+
+// build App
+func newApp(
+	httpServer *http.Server, 
+	job *server.Job,
+    // 你想注册的其它服务,需要从参数传入
+	) *app.App {
+	return app.NewApp(
+		app.WithServer(httpServer, job),
+		app.WithName("demo-server"),
+	)
+}
+
+func NewWire(*viper.Viper, *log.Logger) (*app.App, func(), error) {
+
+	panic(wire.Build(
+		repositorySet,
+		serviceSet,
+		handlerSet,
+		serverSet,  // 集中注册服务
+		sid.NewSid,
+		jwt.NewJwt,
+		newApp,
+	))
+}

基于 MIT 许可发布

diff --git a/docs/service.html b/docs/service.html index 410f8ec..9452539 100644 --- a/docs/service.html +++ b/docs/service.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

基于 MIT 许可发布

+
Skip to content

基于 MIT 许可发布

diff --git a/docs/sitemap.xml b/docs/sitemap.xml index 581dcf6..885db48 100644 --- a/docs/sitemap.xml +++ b/docs/sitemap.xml @@ -1 +1 @@ -https://go-nunu.dev/architecture2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/architecture2024-03-31T10:26:10.000Zhttps://go-nunu.dev/cli2024-03-31T15:42:50.000Zhttps://go-nunu.dev/en/cli2024-03-31T10:26:10.000Zhttps://go-nunu.dev/database2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/database2024-03-31T10:26:10.000Zhttps://go-nunu.dev/docker2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/docker2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/foo2024-03-31T10:26:10.000Zhttps://go-nunu.dev/foo2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/getting-started2024-03-31T10:26:10.000Zhttps://go-nunu.dev/getting-started2024-03-31T15:42:50.000Zhttps://go-nunu.dev/en/guide2024-03-31T10:26:10.000Zhttps://go-nunu.dev/guide2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/handler2024-03-31T10:26:10.000Zhttps://go-nunu.dev/handler2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/2024-03-31T11:01:00.000Zhttps://go-nunu.dev/2024-03-31T14:33:56.000Zhttps://go-nunu.dev/en/k8s2024-03-31T10:26:10.000Zhttps://go-nunu.dev/k8s2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/logger2024-03-31T10:26:10.000Zhttps://go-nunu.dev/logger2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/middleware2024-03-31T10:26:10.000Zhttps://go-nunu.dev/middleware2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/model2024-03-31T10:26:10.000Zhttps://go-nunu.dev/model2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/nginx2024-03-31T10:26:10.000Zhttps://go-nunu.dev/nginx2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/pkg2024-03-31T10:26:10.000Zhttps://go-nunu.dev/pkg2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/pr2024-03-31T10:26:10.000Zhttps://go-nunu.dev/pr2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/redis2024-03-31T10:26:10.000Zhttps://go-nunu.dev/redis2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/repository2024-03-31T10:26:10.000Zhttps://go-nunu.dev/repository2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/server2024-03-31T10:26:10.000Zhttps://go-nunu.dev/server2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/service2024-03-31T10:26:10.000Zhttps://go-nunu.dev/service2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/swagger2024-03-31T10:26:10.000Zhttps://go-nunu.dev/swagger2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/swarm2024-03-31T10:26:10.000Zhttps://go-nunu.dev/swarm2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/unit-test2024-03-31T10:26:10.000Zhttps://go-nunu.dev/unit-test2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/wire2024-03-31T10:26:10.000Zhttps://go-nunu.dev/wire2024-03-31T15:42:50.000Z \ No newline at end of file +https://go-nunu.dev/architecture2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/architecture2024-03-31T10:26:10.000Zhttps://go-nunu.dev/cli2024-03-31T15:42:50.000Zhttps://go-nunu.dev/en/cli2024-03-31T10:26:10.000Zhttps://go-nunu.dev/database2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/database2024-03-31T10:26:10.000Zhttps://go-nunu.dev/docker2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/docker2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/foo2024-03-31T10:26:10.000Zhttps://go-nunu.dev/foo2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/getting-started2024-03-31T10:26:10.000Zhttps://go-nunu.dev/getting-started2024-03-31T15:42:50.000Zhttps://go-nunu.dev/en/guide2024-03-31T10:26:10.000Zhttps://go-nunu.dev/guide2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/handler2024-03-31T10:26:10.000Zhttps://go-nunu.dev/handler2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/2024-03-31T11:01:00.000Zhttps://go-nunu.dev/2024-03-31T14:33:56.000Zhttps://go-nunu.dev/en/k8s2024-03-31T10:26:10.000Zhttps://go-nunu.dev/k8s2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/logger2024-03-31T10:26:10.000Zhttps://go-nunu.dev/logger2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/middleware2024-03-31T10:26:10.000Zhttps://go-nunu.dev/middleware2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/model2024-03-31T10:26:10.000Zhttps://go-nunu.dev/model2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/nginx2024-03-31T10:26:10.000Zhttps://go-nunu.dev/nginx2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/pkg2024-03-31T10:26:10.000Zhttps://go-nunu.dev/pkg2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/pr2024-03-31T10:26:10.000Zhttps://go-nunu.dev/pr2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/redis2024-03-31T10:26:10.000Zhttps://go-nunu.dev/redis2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/repository2024-03-31T10:26:10.000Zhttps://go-nunu.dev/repository2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/server2024-03-31T10:26:10.000Zhttps://go-nunu.dev/server2024-03-31T15:58:17.000Zhttps://go-nunu.dev/en/service2024-03-31T10:26:10.000Zhttps://go-nunu.dev/service2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/swagger2024-03-31T10:26:10.000Zhttps://go-nunu.dev/swagger2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/swarm2024-03-31T10:26:10.000Zhttps://go-nunu.dev/swarm2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/unit-test2024-03-31T10:26:10.000Zhttps://go-nunu.dev/unit-test2024-03-31T10:26:10.000Zhttps://go-nunu.dev/en/wire2024-03-31T10:26:10.000Zhttps://go-nunu.dev/wire2024-03-31T15:42:50.000Zhttps://go-nunu.dev/grpchttps://go-nunu.dev/httphttps://go-nunu.dev/jobhttps://go-nunu.dev/taskhttps://go-nunu.dev/websocket \ No newline at end of file diff --git a/docs/src/.vitepress/config/en.ts b/docs/src/.vitepress/config/en.ts index 9fff530..1a2031a 100644 --- a/docs/src/.vitepress/config/en.ts +++ b/docs/src/.vitepress/config/en.ts @@ -16,7 +16,7 @@ export const en = defineConfig({ }, editLink: { - pattern: 'https://github.com/go-nunu/nunu/edit/feature/docs/:path', + pattern: 'https://github.com/go-nunu/nunu/edit/feature/docs/docs/src/en/:path', text: 'Edit this page on GitHub' }, diff --git a/docs/src/.vitepress/config/zh.ts b/docs/src/.vitepress/config/zh.ts index f0c5801..134e8a6 100644 --- a/docs/src/.vitepress/config/zh.ts +++ b/docs/src/.vitepress/config/zh.ts @@ -17,7 +17,7 @@ export const zh = defineConfig({ }, editLink: { - pattern: 'https://github.com/go-nunu/nunu/edit/feature/docs/:path', + pattern: 'https://github.com/go-nunu/nunu/edit/feature/docs/docs/src/:path', text: '在 GitHub 上编辑此页面' }, @@ -104,7 +104,16 @@ function sidebarGuide(): DefaultTheme.SidebarItem[] { collapsed: false, items: [ { - text: 'Server', link: 'server', + text: 'Server', + link: 'server', + items: [ + {text: 'HTTP路由', link: 'http'}, + {text: 'Task定时任务', link: 'task'}, + {text: 'Job异步事件流', link: 'job'}, + {text: 'Migration数据迁移', link: 'migration'}, + {text: 'GRPC', link: 'grpc'}, + {text: 'Websocket', link: 'websocket'}, + ] }, {text: 'Handler', link: 'handler'}, { diff --git a/docs/src/.vitepress/dist/en/architecture.html b/docs/src/.vitepress/dist/en/architecture.html index 2db2d92..8c4d39f 100644 --- a/docs/src/.vitepress/dist/en/architecture.html +++ b/docs/src/.vitepress/dist/en/architecture.html @@ -7,11 +7,11 @@ - - + + - + @@ -56,7 +56,7 @@ ├── web ├── Makefile ├── go.mod -└── go.sum
  • cmd:应用程序的入口,包含了不同的子命令。
  • config:配置文件。
  • deploy:部署相关的文件,如 Dockerfile 、 docker-compose.yml等。
  • internal:应用程序的主要代码,按照分层架构进行组织。
  • pkg:公共的代码,包括配置、日志、HTTP 等。
  • script:脚本文件,用于部署和其他自动化任务。
  • storage:存储文件,如日志文件。
  • test:测试代码。
  • web:前端代码。

internal

  • internal/handler( or controller):处理 HTTP 请求,调用业务逻辑层的服务,返回 HTTP 响应。
  • internal/server(or router):HTTP 服务器,启动 HTTP 服务,监听端口,处理 HTTP 请求。
  • internal/service(or logic):服务,实现具体的业务逻辑,调用数据访问层repository。
  • internal/model(or entity):数据模型,定义了业务逻辑层需要的数据结构。
  • internal/repository(or dao):数据访问对象,封装了数据库操作,提供了对数据的增删改查。

依赖注入

本项目采用了依赖注入框架Wire,实现了模块化和解耦。Wire通过预编译wire.go,自动生成依赖注入的代码wire_gen.go,简化了依赖注入的过程。

  • cmd/job/wire.goWire配置文件,定义了job子命令需要的依赖关系。
  • cmd/migration/wire.goWire配置文件,定义了migration子命令需要的依赖关系。
  • cmd/server/wire.goWire配置文件,定义了server子命令需要的依赖关系。

Wire官方文档:https://github.com/google/wire/blob/main/docs/guide.md

注意:wire_gen.go文件为自动编译生成,禁止手动修改

公共代码

为了实现代码的复用和统一管理,本项目采用了公共代码的方式,将一些通用的代码放在了pkg目录下。

  • pkg/config:配置文件的读取和解析。
  • pkg/helper:一些通用的辅助函数,如 MD5 加密、UUID 生成等。
  • pkg/http:HTTP 相关的代码,如 HTTP 客户端、HTTP 服务器等。
  • pkg/log:日志相关的代码,如日志的初始化、日志的写入等。
  • more...:当然,你可以自由添加扩展更多的pkg。

Released under the MIT License.

+└── go.sum
  • cmd:应用程序的入口,包含了不同的子命令。
  • config:配置文件。
  • deploy:部署相关的文件,如 Dockerfile 、 docker-compose.yml等。
  • internal:应用程序的主要代码,按照分层架构进行组织。
  • pkg:公共的代码,包括配置、日志、HTTP 等。
  • script:脚本文件,用于部署和其他自动化任务。
  • storage:存储文件,如日志文件。
  • test:测试代码。
  • web:前端代码。

internal

  • internal/handler( or controller):处理 HTTP 请求,调用业务逻辑层的服务,返回 HTTP 响应。
  • internal/server(or router):HTTP 服务器,启动 HTTP 服务,监听端口,处理 HTTP 请求。
  • internal/service(or logic):服务,实现具体的业务逻辑,调用数据访问层repository。
  • internal/model(or entity):数据模型,定义了业务逻辑层需要的数据结构。
  • internal/repository(or dao):数据访问对象,封装了数据库操作,提供了对数据的增删改查。

依赖注入

本项目采用了依赖注入框架Wire,实现了模块化和解耦。Wire通过预编译wire.go,自动生成依赖注入的代码wire_gen.go,简化了依赖注入的过程。

  • cmd/job/wire.goWire配置文件,定义了job子命令需要的依赖关系。
  • cmd/migration/wire.goWire配置文件,定义了migration子命令需要的依赖关系。
  • cmd/server/wire.goWire配置文件,定义了server子命令需要的依赖关系。

Wire官方文档:https://github.com/google/wire/blob/main/docs/guide.md

注意:wire_gen.go文件为自动编译生成,禁止手动修改

公共代码

为了实现代码的复用和统一管理,本项目采用了公共代码的方式,将一些通用的代码放在了pkg目录下。

  • pkg/config:配置文件的读取和解析。
  • pkg/helper:一些通用的辅助函数,如 MD5 加密、UUID 生成等。
  • pkg/http:HTTP 相关的代码,如 HTTP 客户端、HTTP 服务器等。
  • pkg/log:日志相关的代码,如日志的初始化、日志的写入等。
  • more...:当然,你可以自由添加扩展更多的pkg。

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/cli.html b/docs/src/.vitepress/dist/en/cli.html index 94a1ea9..7f8adb7 100644 --- a/docs/src/.vitepress/dist/en/cli.html +++ b/docs/src/.vitepress/dist/en/cli.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

nunu命令行工具

nunu 命令行工具是一个为了协助快速开发 Golang 项目而创建的项目,通过 nunu 命令行工具, 您可以很容易的进行 Golang 项目的创建、热编译、开发、测试、和部署。

创建项目

nunu new [projectName]

启动项目

nunu run

创建组件

nunu create [type] [handler-name]

创建handler

nunu create handler [handler-name]

编译wire

nunu wire all

版本升级

nunu upgrade

Released under the MIT License.

+
Skip to content

nunu命令行工具

nunu 命令行工具是一个为了协助快速开发 Golang 项目而创建的项目,通过 nunu 命令行工具, 您可以很容易的进行 Golang 项目的创建、热编译、开发、测试、和部署。

创建项目

nunu new [projectName]

启动项目

nunu run

创建组件

nunu create [type] [handler-name]

创建handler

nunu create handler [handler-name]

编译wire

nunu wire all

版本升级

nunu upgrade

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/database.html b/docs/src/.vitepress/dist/en/database.html index eafe653..2d1689a 100644 --- a/docs/src/.vitepress/dist/en/database.html +++ b/docs/src/.vitepress/dist/en/database.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/docker.html b/docs/src/.vitepress/dist/en/docker.html index 15c0531..0cdc864 100644 --- a/docs/src/.vitepress/dist/en/docker.html +++ b/docs/src/.vitepress/dist/en/docker.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Docker

镜像构建

容器运行

Released under the MIT License.

+
Skip to content

Docker

镜像构建

容器运行

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/foo.html b/docs/src/.vitepress/dist/en/foo.html index 7fb74f6..4fea141 100644 --- a/docs/src/.vitepress/dist/en/foo.html +++ b/docs/src/.vitepress/dist/en/foo.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/getting-started.html b/docs/src/.vitepress/dist/en/getting-started.html index 5571f6c..8e78f5c 100644 --- a/docs/src/.vitepress/dist/en/getting-started.html +++ b/docs/src/.vitepress/dist/en/getting-started.html @@ -7,11 +7,11 @@ - - + + - + @@ -33,7 +33,7 @@ nunu new projectName -r https://gitee.com/go-nunu/nunu-layout-advanced.git // 使用基础模板 -nunu new projectName -r https://gitee.com/go-nunu/nunu-layout-basic.git

Nunu内置了两种类型的Layout:

  • 基础模板(Basic Layout)

    Basic Layout 包含一个非常精简的架构目录结构,适合非常熟悉Nunu项目的开发者使用。

  • 高级模板(Advanced Layout)

    Advanced Layout 包含了很多Nunu的用法示例( db、redis、 jwt、 cron、 migration等),适合开发者快速学习了解Nunu的架构思想。

    建议:我们推荐新手优先选择使用Advanced Layout。

启动服务

创建好项目之后,我们进入项目执行nunu run命令即可启动服务。

nunu run cmd/server/main.go

随后打开浏览器访问http://localhost:8080即可看到欢迎页面。

API文档地址: http://127.0.0.1:8000/swagger/index.html

Released under the MIT License.

+nunu new projectName -r https://gitee.com/go-nunu/nunu-layout-basic.git

Nunu内置了两种类型的Layout:

  • 基础模板(Basic Layout)

    Basic Layout 包含一个非常精简的架构目录结构,适合非常熟悉Nunu项目的开发者使用。

  • 高级模板(Advanced Layout)

    Advanced Layout 包含了很多Nunu的用法示例( db、redis、 jwt、 cron、 migration等),适合开发者快速学习了解Nunu的架构思想。

    建议:我们推荐新手优先选择使用Advanced Layout。

启动服务

创建好项目之后,我们进入项目执行nunu run命令即可启动服务。

nunu run cmd/server/main.go

随后打开浏览器访问http://localhost:8080即可看到欢迎页面。

API文档地址: http://127.0.0.1:8000/swagger/index.html

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/guide.html b/docs/src/.vitepress/dist/en/guide.html index 1bae5d6..e47f612 100644 --- a/docs/src/.vitepress/dist/en/guide.html +++ b/docs/src/.vitepress/dist/en/guide.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Nunu 是什么?

Nunu是一个基于Golang的应用脚手架,它的名字来自于英雄联盟中的游戏角色,一个骑在雪怪肩膀上的小男孩。和努努一样,该项目也是站在巨人的肩膀上,它是由Golang生态中各种非常流行的库整合而成的,它们的组合可以帮助你快速构建一个高效、可靠的应用程序。

只是想尝试一下?跳到快速开始

开发体验

Nunu 旨在Golang项目开发时提供出色的开发体验。

  • 超低学习成本和定制:Nunu封装了Gopher最熟悉的一些流行库。您可以轻松定制应用程序以满足特定需求。

  • 模块化和可扩展:Nunu旨在具有模块化和可扩展性。您可以通过使用第三方库或编写自己的模块轻松添加新功能和功能。

  • 文档完善和测试完备:Nunu文档完善,测试完备。它提供了全面的文档和示例,帮助您快速入门。它还包括一套测试套件,确保您的应用程序按预期工作。

性能

  • 高性能Gin

    Gin是一个Go(又称为Golang)语言编写的Web框架,以其轻量级和高性能著称。

  • 无损的依赖注入

    wire不是在运行时通过反射动态地进行依赖注入,而是在编译期通过静态代码生成的方式达成这个目的。

  • 轻度的组件封装

    Nunu没有过度的封装一些常用组件,而是简洁直观的导入第三方包,保证原生组件的性能与稳定性。

Released under the MIT License.

+
Skip to content

Nunu 是什么?

Nunu是一个基于Golang的应用脚手架,它的名字来自于英雄联盟中的游戏角色,一个骑在雪怪肩膀上的小男孩。和努努一样,该项目也是站在巨人的肩膀上,它是由Golang生态中各种非常流行的库整合而成的,它们的组合可以帮助你快速构建一个高效、可靠的应用程序。

只是想尝试一下?跳到快速开始

开发体验

Nunu 旨在Golang项目开发时提供出色的开发体验。

  • 超低学习成本和定制:Nunu封装了Gopher最熟悉的一些流行库。您可以轻松定制应用程序以满足特定需求。

  • 模块化和可扩展:Nunu旨在具有模块化和可扩展性。您可以通过使用第三方库或编写自己的模块轻松添加新功能和功能。

  • 文档完善和测试完备:Nunu文档完善,测试完备。它提供了全面的文档和示例,帮助您快速入门。它还包括一套测试套件,确保您的应用程序按预期工作。

性能

  • 高性能Gin

    Gin是一个Go(又称为Golang)语言编写的Web框架,以其轻量级和高性能著称。

  • 无损的依赖注入

    wire不是在运行时通过反射动态地进行依赖注入,而是在编译期通过静态代码生成的方式达成这个目的。

  • 轻度的组件封装

    Nunu没有过度的封装一些常用组件,而是简洁直观的导入第三方包,保证原生组件的性能与稳定性。

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/handler.html b/docs/src/.vitepress/dist/en/handler.html index fa5aac6..db12dd7 100644 --- a/docs/src/.vitepress/dist/en/handler.html +++ b/docs/src/.vitepress/dist/en/handler.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/index.html b/docs/src/.vitepress/dist/en/index.html index 3de0af9..ee233d7 100644 --- a/docs/src/.vitepress/dist/en/index.html +++ b/docs/src/.vitepress/dist/en/index.html @@ -7,11 +7,11 @@ - - + + - + diff --git a/docs/src/.vitepress/dist/en/k8s.html b/docs/src/.vitepress/dist/en/k8s.html index efd4e71..4a8ccbd 100644 --- a/docs/src/.vitepress/dist/en/k8s.html +++ b/docs/src/.vitepress/dist/en/k8s.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/logger.html b/docs/src/.vitepress/dist/en/logger.html index 13822ef..166acdf 100644 --- a/docs/src/.vitepress/dist/en/logger.html +++ b/docs/src/.vitepress/dist/en/logger.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/middleware.html b/docs/src/.vitepress/dist/en/middleware.html index 08b7eaf..9449b48 100644 --- a/docs/src/.vitepress/dist/en/middleware.html +++ b/docs/src/.vitepress/dist/en/middleware.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

HTTP中间件

限流器

日志Trace

签名验证

跨域

Released under the MIT License.

+
Skip to content

HTTP中间件

限流器

日志Trace

签名验证

跨域

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/model.html b/docs/src/.vitepress/dist/en/model.html index b45823a..f35a1b2 100644 --- a/docs/src/.vitepress/dist/en/model.html +++ b/docs/src/.vitepress/dist/en/model.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/nginx.html b/docs/src/.vitepress/dist/en/nginx.html index 8bf160e..6322630 100644 --- a/docs/src/.vitepress/dist/en/nginx.html +++ b/docs/src/.vitepress/dist/en/nginx.html @@ -7,11 +7,11 @@ - - + + - + @@ -60,7 +60,7 @@ proxy_redirect off; proxy_buffering off; } -}

Released under the MIT License.

+}

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/pkg.html b/docs/src/.vitepress/dist/en/pkg.html index 58c5ba7..e85695c 100644 --- a/docs/src/.vitepress/dist/en/pkg.html +++ b/docs/src/.vitepress/dist/en/pkg.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/pr.html b/docs/src/.vitepress/dist/en/pr.html index 681c656..760691a 100644 --- a/docs/src/.vitepress/dist/en/pr.html +++ b/docs/src/.vitepress/dist/en/pr.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/redis.html b/docs/src/.vitepress/dist/en/redis.html index 7c87de8..e8c5a22 100644 --- a/docs/src/.vitepress/dist/en/redis.html +++ b/docs/src/.vitepress/dist/en/redis.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/repository.html b/docs/src/.vitepress/dist/en/repository.html index 549c9f4..9f3ef2d 100644 --- a/docs/src/.vitepress/dist/en/repository.html +++ b/docs/src/.vitepress/dist/en/repository.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/server.html b/docs/src/.vitepress/dist/en/server.html index 71059a7..789c6d7 100644 --- a/docs/src/.vitepress/dist/en/server.html +++ b/docs/src/.vitepress/dist/en/server.html @@ -7,11 +7,11 @@ - - + + - + @@ -29,7 +29,7 @@
Skip to content

Server基础概念

在Nunu中,我们将HTTPGRPCWebSocketTaskJob等服务都抽象为Server

go
type Server interface {
 	Start(context.Context) error
 	Stop(context.Context) error
-}

每个Server都必须实现Server接口中的方法,也就是Start(ctx)Stop(ctx)

HTTP

HTTP服务,我们使用gin作为HTTP框架,ginEngine实现了Server接口,因此,我们只需要将Engine作为Server即可。

Task

Task服务,我们使用cron作为Task框架,cronCron实现了Server接口,因此,我们只需要将Cron作为Server即可。

Job

Job服务,我们使用cron作为Job框架,cronCron实现了Server接口,因此,我们只需要将Cron作为Server即可。

Migration

Migration服务,我们使用migrate作为Migration框架,migrateMigrate实现了Server接口,因此,我们只需要将Migrate作为Server即可。

Released under the MIT License.

+}

每个Server都必须实现Server接口中的方法,也就是Start(ctx)Stop(ctx)

HTTP

HTTP服务,我们使用gin作为HTTP框架,ginEngine实现了Server接口,因此,我们只需要将Engine作为Server即可。

Task

Task服务,我们使用cron作为Task框架,cronCron实现了Server接口,因此,我们只需要将Cron作为Server即可。

Job

Job服务,我们使用cron作为Job框架,cronCron实现了Server接口,因此,我们只需要将Cron作为Server即可。

Migration

Migration服务,我们使用migrate作为Migration框架,migrateMigrate实现了Server接口,因此,我们只需要将Migrate作为Server即可。

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/service.html b/docs/src/.vitepress/dist/en/service.html index 9b1c97a..83c0e6a 100644 --- a/docs/src/.vitepress/dist/en/service.html +++ b/docs/src/.vitepress/dist/en/service.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/swagger.html b/docs/src/.vitepress/dist/en/swagger.html index bb1dc23..210a245 100644 --- a/docs/src/.vitepress/dist/en/swagger.html +++ b/docs/src/.vitepress/dist/en/swagger.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/swarm.html b/docs/src/.vitepress/dist/en/swarm.html index 8392311..41daa2b 100644 --- a/docs/src/.vitepress/dist/en/swarm.html +++ b/docs/src/.vitepress/dist/en/swarm.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Docker Swarm集群部署

swarm.yml配置

滚动更新

Released under the MIT License.

+
Skip to content

Docker Swarm集群部署

swarm.yml配置

滚动更新

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/unit-test.html b/docs/src/.vitepress/dist/en/unit-test.html index b0a9d84..4fc491d 100644 --- a/docs/src/.vitepress/dist/en/unit-test.html +++ b/docs/src/.vitepress/dist/en/unit-test.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Released under the MIT License.

+
Skip to content

Released under the MIT License.

diff --git a/docs/src/.vitepress/dist/en/wire.html b/docs/src/.vitepress/dist/en/wire.html index 73e4036..4608654 100644 --- a/docs/src/.vitepress/dist/en/wire.html +++ b/docs/src/.vitepress/dist/en/wire.html @@ -7,11 +7,11 @@ - - + + - + @@ -158,7 +158,7 @@ jwt.NewJwt, newApp, )) -}

想学习更多关于Wire知识?前往到Wire官方文档

Released under the MIT License.

+}

想学习更多关于Wire知识?前往到Wire官方文档

Released under the MIT License.

diff --git a/docs/src/grpc.md b/docs/src/grpc.md new file mode 100644 index 0000000..f52cbd7 --- /dev/null +++ b/docs/src/grpc.md @@ -0,0 +1,3 @@ +# GRPC + +待更新 \ No newline at end of file diff --git a/docs/src/http.md b/docs/src/http.md new file mode 100644 index 0000000..95ba6af --- /dev/null +++ b/docs/src/http.md @@ -0,0 +1,32 @@ +# HTTP +**用途**:处理基于HTTP协议的请求和响应。 + +**工作原理**:监听指定的HTTP端口,并根据接收到的请求执行相应的操作,然后返回相应的HTTP响应。 + +**示例应用场景**:Web应用程序、API服务等。 + +## 路由定义 +`HTTP`的路由定义非常简单,大家可以直接参考`internal/server/http.go`中的`NewHTTPServer`方法。 + +在`NewHTTPServer`方法中,我们首先创建了一个`gin.Engine`对象,然后定义了路由规则,包括`GET`、`POST`、`PUT`、`DELETE`等方法。 + +需要注意的是在`高级Layout`示例中,我们为大家定义了三个路由组,`noAuthRouter`、`noStrictAuthRouter`和`strictAuthRouter`,他们的具体用法如下: +1. `noAuthRouter`:无需认证即可访问,用于一些无需认证的接口,例如登录、注册等。 +2. `noStrictAuthRouter`:无需严格认证即可访问,用于一些无需严格认证的接口,例如获取用户信息等。 +3. `strictAuthRouter`:需要严格认证即可访问,用于一些需要严格认证的接口,例如修改用户信息等。 + +三个路由组是基于不同的中间件实现的,具体中间件的实现可以参考`internal/middleware`目录下的代码。 + +## 依赖注入Handler +`HTTP`模块的依赖注入非常简单,只需要在`NewHTTPServer`方法中传入的用到的`Handler`结构即可。 +```go +func NewHTTPServer( + logger *log.Logger, + conf *viper.Viper, + jwt *jwt.JWT, + userHandler *handler.UserHandler, + // 更多handler +) *http.Server { + +} +``` \ No newline at end of file diff --git a/docs/src/job.md b/docs/src/job.md new file mode 100644 index 0000000..cc15b7a --- /dev/null +++ b/docs/src/job.md @@ -0,0 +1,9 @@ +# Job +**用途**:处理异步任务,通常用于处理消息队列(MQ)中的消息。 + +**工作原理**:从消息队列中获取任务并执行,可以是一些需要异步处理的任务,如邮件发送、文件处理等。 + +**示例应用场景**:异步任务队列、消息驱动的系统等。 +:::tip +nunu支持`Job`和`HTTP server`同时运行,也同样支持独立于`HTTP server`运行,请参考`Task`或是`Migration`的实现。 +::: \ No newline at end of file diff --git a/docs/src/migration.md b/docs/src/migration.md new file mode 100644 index 0000000..39baca3 --- /dev/null +++ b/docs/src/migration.md @@ -0,0 +1,11 @@ +# Migration +**用途**:处理数据库迁移和数据迁移任务。 + +**工作原理**:Migration服务负责管理数据库结构的变化和数据的迁移,例如在软件升级过程中,需要更新数据库模式或迁移现有数据以适应新的模式。 + +**示例应用场景**:迁移数据库表结构,例如添加新的列、删除旧的列、修改列的数据类型等。 +迁移数据,例如将旧数据格式转换为新的格式、合并数据、拆分数据等。 +管理数据库版本,确保数据库结构与应用程序代码的版本兼容性。 +:::tip +Migration须谨慎用于生成环境,以免导致数据丢失或破坏。 +::: \ No newline at end of file diff --git a/docs/src/server.md b/docs/src/server.md index 2f1e597..98c60c0 100644 --- a/docs/src/server.md +++ b/docs/src/server.md @@ -10,40 +10,47 @@ type Server interface { 每个`Server`都必须实现`Server`接口中的方法,也就是`Start(ctx)`和`Stop(ctx)` -## HTTP -**用途**:处理基于HTTP协议的请求和响应。 -**工作原理**:监听指定的HTTP端口,并根据接收到的请求执行相应的操作,然后返回相应的HTTP响应。 -**示例应用场景**:Web应用程序、API服务等。 -## Task -**用途**:处理定时任务,类似于crontab的功能。 +## 服务依赖注册 -**工作原理**:定期执行预定义的任务或作业,通常用于周期性地执行一些重复性的任务。 +在Nunu中,如果你想给你的某个服务进程注册相应的启动服务, -**示例应用场景**:定时数据备份、定时数据清理、定时报表生成等。 -:::tip -定时任务建议独立于`HTTP server`运行,避免影响主应用程序的运行。但同时nunu支持`Task`和`HTTP server`同时运行,请参考`Job`的实现。 -::: -## Job -**用途**:处理异步任务,通常用于处理消息队列(MQ)中的消息。 +你只需要关心`cmd/[服务器名称]/wire/wire.go`文件即可。 -**工作原理**:从消息队列中获取任务并执行,可以是一些需要异步处理的任务,如邮件发送、文件处理等。 +```go +var serverSet = wire.NewSet( + server.NewHTTPServer, + server.NewJob, + // 你想注册的其它服务 +) + +// build App +func newApp( + httpServer *http.Server, + job *server.Job, + // 你想注册的其它服务,需要从参数传入 + ) *app.App { + return app.NewApp( + app.WithServer(httpServer, job), + app.WithName("demo-server"), + ) +} -**示例应用场景**:异步任务队列、消息驱动的系统等。 -:::tip -nunu支持`Job`和`HTTP server`同时运行,也同样支持独立于`HTTP server`运行,请参考`Task`或是`Migration`的实现。 -::: -## Migration -**用途**:处理数据库迁移和数据迁移任务。 +func NewWire(*viper.Viper, *log.Logger) (*app.App, func(), error) { + + panic(wire.Build( + repositorySet, + serviceSet, + handlerSet, + serverSet, // 集中注册服务 + sid.NewSid, + jwt.NewJwt, + newApp, + )) +} -**工作原理**:Migration服务负责管理数据库结构的变化和数据的迁移,例如在软件升级过程中,需要更新数据库模式或迁移现有数据以适应新的模式。 -**示例应用场景**:迁移数据库表结构,例如添加新的列、删除旧的列、修改列的数据类型等。 -迁移数据,例如将旧数据格式转换为新的格式、合并数据、拆分数据等。 -管理数据库版本,确保数据库结构与应用程序代码的版本兼容性。 -:::tip -Migration须谨慎用于生成环境,以免导致数据丢失或破坏。 -::: +``` diff --git a/docs/src/task.md b/docs/src/task.md new file mode 100644 index 0000000..c624bc2 --- /dev/null +++ b/docs/src/task.md @@ -0,0 +1,9 @@ +# Task +**用途**:处理定时任务,类似于crontab的功能。 + +**工作原理**:定期执行预定义的任务或作业,通常用于周期性地执行一些重复性的任务。 + +**示例应用场景**:定时数据备份、定时数据清理、定时报表生成等。 +:::tip +定时任务建议独立于`HTTP server`运行,避免影响主应用程序的运行。但同时nunu支持`Task`和`HTTP server`同时运行,请参考`Job`的实现。 +::: \ No newline at end of file diff --git a/docs/src/websocket.md b/docs/src/websocket.md new file mode 100644 index 0000000..a42ccee --- /dev/null +++ b/docs/src/websocket.md @@ -0,0 +1,3 @@ +# Websocket + +待更新 \ No newline at end of file diff --git a/docs/swagger.html b/docs/swagger.html index fbb031f..51f2b51 100644 --- a/docs/swagger.html +++ b/docs/swagger.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

基于 MIT 许可发布

+
Skip to content

基于 MIT 许可发布

diff --git a/docs/swarm.html b/docs/swarm.html index 4c0b3c1..559da2d 100644 --- a/docs/swarm.html +++ b/docs/swarm.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

Docker Swarm集群部署

swarm.yml配置

滚动更新

基于 MIT 许可发布

+
Skip to content

Docker Swarm集群部署

swarm.yml配置

滚动更新

基于 MIT 许可发布

diff --git a/docs/task.html b/docs/task.html new file mode 100644 index 0000000..293f155 --- /dev/null +++ b/docs/task.html @@ -0,0 +1,33 @@ + + + + + + Task | Nunu文档 + + + + + + + + + + + + + + + + + + + + + + +
Skip to content

Task

用途:处理定时任务,类似于crontab的功能。

工作原理:定期执行预定义的任务或作业,通常用于周期性地执行一些重复性的任务。

示例应用场景:定时数据备份、定时数据清理、定时报表生成等。

TIP

定时任务建议独立于HTTP server运行,避免影响主应用程序的运行。但同时nunu支持TaskHTTP server同时运行,请参考Job的实现。

基于 MIT 许可发布

+ + + + \ No newline at end of file diff --git a/docs/unit-test.html b/docs/unit-test.html index 4e1a14d..0aab184 100644 --- a/docs/unit-test.html +++ b/docs/unit-test.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

基于 MIT 许可发布

+
Skip to content

基于 MIT 许可发布

diff --git a/docs/websocket.html b/docs/websocket.html new file mode 100644 index 0000000..995f6b5 --- /dev/null +++ b/docs/websocket.html @@ -0,0 +1,33 @@ + + + + + + Websocket | Nunu文档 + + + + + + + + + + + + + + + + + + + + + + +
Skip to content

基于 MIT 许可发布

+ + + + \ No newline at end of file diff --git a/docs/wire.html b/docs/wire.html index c328f30..65af91b 100644 --- a/docs/wire.html +++ b/docs/wire.html @@ -7,11 +7,11 @@ - - + + - + @@ -26,7 +26,7 @@ -
Skip to content

依赖注入

为什么需要依赖注入?

依赖注入是一种编程模式,用于管理代码中各个组件之间的依赖关系。在没有依赖注入的情况下,通常会使用全局变量或硬编码的方式来获取所需的依赖,这种方式会带来一些问题。

全局变量

让我们通过一个简单的 Go 语言示例来说明:

假设我们有一个简单的服务,它需要一个数据库连接。在没有依赖注入的情况下,我们可能会这样实现:

go
package main
+    
Skip to content

依赖注入

为什么需要依赖注入?

依赖注入是一种编程模式,用于管理代码中各个组件之间的依赖关系。在没有依赖注入的情况下,通常会使用全局变量或硬编码的方式来获取所需的依赖,这种方式会带来一些问题。

全局变量

让我们通过一个简单的 Go 语言示例来说明:

假设我们有一个简单的服务,它需要一个数据库连接。在没有依赖注入的情况下,我们可能会这样实现:

go
package main
 
 import (
 	"database/sql"
@@ -158,7 +158,7 @@
 		jwt.NewJwt,
 		newApp,
 	))
-}

想学习更多关于Wire知识?前往到Wire官方文档

基于 MIT 许可发布

+}

想学习更多关于Wire知识?前往到Wire官方文档

基于 MIT 许可发布