gorig-cli 1.0.24 → 1.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +112 -22
- package/commands/create.js +267 -112
- package/commands/doc.js +21 -8
- package/commands/init.js +316 -255
- package/commands/skill.js +55 -17
- package/package.json +1 -1
- package/templates/config.go.ejs +6 -5
- package/templates/config.yaml.ejs +3 -38
- package/templates/controller.go.ejs +11 -42
- package/templates/crud.controller.go.ejs +71 -0
- package/templates/crud.doc.md.ejs +60 -0
- package/templates/crud.dto.go.ejs +103 -0
- package/templates/crud.integration.init_test.go.ejs +17 -0
- package/templates/crud.integration_test.go.ejs +66 -0
- package/templates/crud.model.go.ejs +25 -0
- package/templates/crud.module.README.md.ejs +70 -0
- package/templates/crud.mongo.config.yaml.ejs +19 -0
- package/templates/crud.mysql.config.yaml.ejs +14 -0
- package/templates/crud.router.go.ejs +18 -0
- package/templates/crud.service.go.ejs +179 -0
- package/templates/crud.test.go.ejs +52 -0
- package/templates/dto.go.ejs +16 -0
- package/templates/gitignore.ejs +18 -49
- package/templates/hello.controller.go.ejs +19 -0
- package/templates/hello.router.go.ejs +12 -0
- package/templates/hello.service.go.ejs +31 -0
- package/templates/hello.test.go.ejs +34 -0
- package/templates/init.go.ejs +1 -27
- package/templates/main.go.ejs +2 -5
- package/templates/model.go.ejs +3 -4
- package/templates/project.README.md.ejs +35 -0
- package/templates/router.go.ejs +4 -8
- package/templates/service.go.ejs +25 -77
- package/templates/skills/gorig-backend/SKILL.md +89 -0
- package/templates/skills/gorig-backend/agents/openai.yaml +4 -0
- package/templates/skills/gorig-backend/assets/api-doc-template.md +59 -0
- package/templates/skills/gorig-backend/assets/gorig.gitignore +65 -0
- package/templates/skills/gorig-backend/assets/module-readme-template.md +58 -0
- package/templates/skills/gorig-backend/references/advanced-data-access.md +275 -0
- package/templates/skills/gorig-backend/references/auth-security.md +194 -0
- package/templates/skills/gorig-backend/references/business-scenarios.md +155 -0
- package/templates/skills/gorig-backend/references/cache.md +301 -0
- package/templates/skills/gorig-backend/references/capability-matrix.md +37 -0
- package/templates/skills/gorig-backend/references/configuration.md +48 -0
- package/templates/skills/gorig-backend/references/framework-api.md +190 -0
- package/templates/skills/gorig-backend/references/messaging.md +143 -0
- package/templates/skills/gorig-backend/references/onboarding-files.md +46 -0
- package/templates/skills/gorig-backend/references/outbound-http.md +162 -0
- package/templates/skills/gorig-backend/references/persistent-crud.md +332 -0
- package/templates/skills/gorig-backend/references/project-bootstrap.md +128 -0
- package/templates/skills/gorig-backend/references/scheduled-tasks.md +231 -0
- package/templates/skills/gorig-backend/references/service-lifecycle.md +51 -0
- package/templates/skills/gorig-backend/references/source-map.md +43 -0
- package/templates/skills/gorig-backend/references/source-policy.md +58 -0
- package/templates/skills/gorig-backend/references/sse.md +121 -0
- package/templates/skills/gorig-backend/references/testing.md +171 -0
- package/templates/skills/gorig-backend/scripts/check-source-links.sh +48 -0
- package/templates/skills/gorig-backend/scripts/detect-gorig-context.sh +67 -0
- package/templates/skills/gorig-backend/scripts/verify-basic-project.sh +108 -0
- package/npm_publish copy.sh +0 -65
- package/templates/internal.go.ejs +0 -49
- package/templates/req.go.ejs +0 -8
- package/templates/resp.go.ejs +0 -8
- package/templates/service.pub.go.ejs +0 -22
- package/templates/skills/claude/gorig-backend/SKILL.md +0 -766
- package/templates/skills/claude/gorig-backend/assets/api-doc-template.md +0 -50
- package/templates/skills/claude/gorig-backend/assets/module-readme-template.md +0 -46
- package/templates/skills/claude/gorig-backend/references/onboarding-files.md +0 -44
- package/templates/skills/codex/gorig-backend/SKILL.md +0 -766
- package/templates/skills/codex/gorig-backend/agents/openai.yaml +0 -4
- package/templates/skills/codex/gorig-backend/assets/api-doc-template.md +0 -50
- package/templates/skills/codex/gorig-backend/assets/module-readme-template.md +0 -46
- package/templates/skills/codex/gorig-backend/references/onboarding-files.md +0 -44
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<%= dbName %>:
|
|
2
|
+
uri: mongodb://127.0.0.1:27017 # MongoDB URI;环境变量 GORIG_MONGO_<%= dbEnvName %>_URI
|
|
3
|
+
db:
|
|
4
|
+
name: <%= dbSchema %> # 数据库名;环境变量 GORIG_MONGO_<%= dbEnvName %>_DB_NAME
|
|
5
|
+
auth:
|
|
6
|
+
need: false # 是否启用认证
|
|
7
|
+
source: admin # 认证数据库;环境变量 GORIG_MONGO_<%= dbEnvName %>_AUTH_SOURCE
|
|
8
|
+
user: "" # 用户名;环境变量 GORIG_MONGO_<%= dbEnvName %>_AUTH_USER
|
|
9
|
+
password: "" # 密码;建议使用 GORIG_MONGO_<%= dbEnvName %>_AUTH_PASSWORD
|
|
10
|
+
retry:
|
|
11
|
+
writes: true # 是否自动重试写操作
|
|
12
|
+
reads: true # 是否自动重试读操作
|
|
13
|
+
pool:
|
|
14
|
+
max: 10 # 最大连接池大小
|
|
15
|
+
min: 1 # 最小连接池大小
|
|
16
|
+
conn:
|
|
17
|
+
idle:
|
|
18
|
+
time:
|
|
19
|
+
max: 10 # 最大空闲时间,单位秒
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<%= dbName %>:
|
|
2
|
+
GormInit: 1 # 1: 启动时初始化此 MySQL 连接;0: 不初始化
|
|
3
|
+
IsOpenReadDb: 0 # 1: 启用读写分离;0: 仅使用 Write
|
|
4
|
+
SlowThreshold: 30 # 慢 SQL 阈值,单位秒
|
|
5
|
+
Write:
|
|
6
|
+
Host: 127.0.0.1 # MySQL 地址;环境变量 GORIG_MYSQL_<%= dbEnvName %>_WRITE_HOST
|
|
7
|
+
Port: 3306 # MySQL 端口;环境变量 GORIG_MYSQL_<%= dbEnvName %>_WRITE_PORT
|
|
8
|
+
DataBase: <%= dbSchema %> # 数据库名;环境变量 GORIG_MYSQL_<%= dbEnvName %>_WRITE_DATABASE
|
|
9
|
+
User: root # 用户名;环境变量 GORIG_MYSQL_<%= dbEnvName %>_WRITE_USER
|
|
10
|
+
Pass: "" # 密码;建议使用 GORIG_MYSQL_<%= dbEnvName %>_WRITE_PASS
|
|
11
|
+
Charset: "utf8mb4" # 连接字符集
|
|
12
|
+
SetMaxIdleConns: 10 # 最大空闲连接数
|
|
13
|
+
SetMaxOpenConns: 100 # 最大打开连接数
|
|
14
|
+
SetConnMaxLifetime: 60 # 连接最大存活时间,单位秒
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
package <%= moduleName %>
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"github.com/gin-gonic/gin"
|
|
5
|
+
"github.com/jom-io/gorig/httpx"
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
func init() {
|
|
9
|
+
httpx.RegisterRouter(func(root *gin.RouterGroup) {
|
|
10
|
+
group := root.Group("/<%= moduleName %>")
|
|
11
|
+
group.POST("/create", CreateHTTP)
|
|
12
|
+
group.GET("/info", InfoHTTP)
|
|
13
|
+
group.GET("/list", ListHTTP)
|
|
14
|
+
group.GET("/page", PageHTTP)
|
|
15
|
+
group.POST("/update", UpdateHTTP)
|
|
16
|
+
group.DELETE("/delete", DeleteHTTP)
|
|
17
|
+
})
|
|
18
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
package <%= moduleName %>
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
|
|
6
|
+
"<%= projectName %>/domain/<%= moduleName %>/model"
|
|
7
|
+
|
|
8
|
+
"github.com/jom-io/gorig/apix/load"
|
|
9
|
+
"github.com/jom-io/gorig/domainx"
|
|
10
|
+
"github.com/jom-io/gorig/domainx/dx"
|
|
11
|
+
"github.com/jom-io/gorig/utils/errors"
|
|
12
|
+
"github.com/jom-io/gorig/utils/logger"
|
|
13
|
+
"go.uber.org/zap"
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
func init() {
|
|
17
|
+
domainx.AutoMigrate(
|
|
18
|
+
func() domainx.ConTable {
|
|
19
|
+
return dx.On[model.D](context.Background()).Complex()
|
|
20
|
+
},
|
|
21
|
+
domainx.CtIdx(domainx.Unique, "name"),
|
|
22
|
+
domainx.CtIdx(domainx.Idx, "status"),
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
func Create(ctx context.Context, req *CreateReq) (int64, *errors.Error) {
|
|
27
|
+
if err := req.Validate(); err != nil {
|
|
28
|
+
return 0, err
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
exists, err := dx.On[model.D](ctx).Eq("name", req.Name).Exists()
|
|
32
|
+
if err != nil {
|
|
33
|
+
logger.Error(ctx, "<%= moduleName %> duplicate check failed", zap.Error(err))
|
|
34
|
+
return 0, err
|
|
35
|
+
}
|
|
36
|
+
if exists {
|
|
37
|
+
return 0, errors.VerifyCode(409, "name already exists")
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
d := model.D{
|
|
41
|
+
Name: req.Name,
|
|
42
|
+
Status: req.Status,
|
|
43
|
+
Remark: req.Remark,
|
|
44
|
+
}
|
|
45
|
+
id, err := dx.On[model.D](ctx, &d).Save()
|
|
46
|
+
if err != nil {
|
|
47
|
+
logger.Error(ctx, "<%= moduleName %> create failed", zap.Error(err))
|
|
48
|
+
return 0, err
|
|
49
|
+
}
|
|
50
|
+
logger.Info(ctx, "<%= moduleName %> created", zap.Int64("id", id), zap.String("name", req.Name))
|
|
51
|
+
return id, nil
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
func Info(ctx context.Context, id int64) (*Resp, *errors.Error) {
|
|
55
|
+
if id <= 0 {
|
|
56
|
+
return nil, errors.VerifyCode(400, "id is required")
|
|
57
|
+
}
|
|
58
|
+
item, err := dx.On[model.D](ctx).WithID(id).Get()
|
|
59
|
+
if err != nil {
|
|
60
|
+
logger.Error(ctx, "<%= moduleName %> get failed", zap.Int64("id", id), zap.Error(err))
|
|
61
|
+
return nil, err
|
|
62
|
+
}
|
|
63
|
+
if item == nil || item.IsNil() || item.Data == nil {
|
|
64
|
+
return nil, errors.VerifyCode(404, "<%= moduleName %> not found")
|
|
65
|
+
}
|
|
66
|
+
return toResp(item), nil
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
func List(ctx context.Context, req *QueryReq) ([]*Resp, *errors.Error) {
|
|
70
|
+
query, err := buildQuery(ctx, req)
|
|
71
|
+
if err != nil {
|
|
72
|
+
return nil, err
|
|
73
|
+
}
|
|
74
|
+
result, err := query.Sort("id").Find()
|
|
75
|
+
if err != nil {
|
|
76
|
+
logger.Error(ctx, "<%= moduleName %> list failed", zap.Error(err))
|
|
77
|
+
return nil, err
|
|
78
|
+
}
|
|
79
|
+
return listToResp(result), nil
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
func Page(ctx context.Context, req *QueryReq, pageReq *load.Page) (*load.PageResp, *errors.Error) {
|
|
83
|
+
if pageReq == nil {
|
|
84
|
+
pageReq = load.BuildPage(ctx, 1, 10, 0)
|
|
85
|
+
}
|
|
86
|
+
query, err := buildQuery(ctx, req)
|
|
87
|
+
if err != nil {
|
|
88
|
+
return nil, err
|
|
89
|
+
}
|
|
90
|
+
result, err := query.Sort("id").Page(pageReq.Page, pageReq.Size, pageReq.LastID)
|
|
91
|
+
if err != nil {
|
|
92
|
+
logger.Error(ctx, "<%= moduleName %> page failed", zap.Error(err))
|
|
93
|
+
return nil, err
|
|
94
|
+
}
|
|
95
|
+
resp := &load.PageResp{
|
|
96
|
+
Page: result.Page,
|
|
97
|
+
Size: result.Size,
|
|
98
|
+
Total: result.Total,
|
|
99
|
+
LastID: result.LastID,
|
|
100
|
+
Result: pageToResp(result.Result),
|
|
101
|
+
}
|
|
102
|
+
return resp, nil
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
func Update(ctx context.Context, req *UpdateReq) *errors.Error {
|
|
106
|
+
fields, err := req.Updates()
|
|
107
|
+
if err != nil {
|
|
108
|
+
return err
|
|
109
|
+
}
|
|
110
|
+
if _, err = Info(ctx, req.ID); err != nil {
|
|
111
|
+
return err
|
|
112
|
+
}
|
|
113
|
+
if err = dx.On[model.D](ctx).WithID(req.ID).Updates(fields); err != nil {
|
|
114
|
+
logger.Error(ctx, "<%= moduleName %> update failed", zap.Int64("id", req.ID), zap.Error(err))
|
|
115
|
+
return err
|
|
116
|
+
}
|
|
117
|
+
logger.Info(ctx, "<%= moduleName %> updated", zap.Int64("id", req.ID))
|
|
118
|
+
return nil
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
func Delete(ctx context.Context, id int64) *errors.Error {
|
|
122
|
+
if _, err := Info(ctx, id); err != nil {
|
|
123
|
+
return err
|
|
124
|
+
}
|
|
125
|
+
if err := dx.On[model.D](ctx).WithID(id).Delete(); err != nil {
|
|
126
|
+
logger.Error(ctx, "<%= moduleName %> delete failed", zap.Int64("id", id), zap.Error(err))
|
|
127
|
+
return err
|
|
128
|
+
}
|
|
129
|
+
logger.Info(ctx, "<%= moduleName %> deleted", zap.Int64("id", id))
|
|
130
|
+
return nil
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
func buildQuery(ctx context.Context, req *QueryReq) (dx.DQuery[model.D], *errors.Error) {
|
|
134
|
+
if req == nil {
|
|
135
|
+
req = &QueryReq{}
|
|
136
|
+
}
|
|
137
|
+
if err := req.Normalize(); err != nil {
|
|
138
|
+
return nil, err
|
|
139
|
+
}
|
|
140
|
+
return dx.On[model.D](ctx).
|
|
141
|
+
NEmpty("name").
|
|
142
|
+
Like("name", req.Name).
|
|
143
|
+
Eq("status", req.Status), nil
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
func toResp(item *domainx.Complex[model.D]) *Resp {
|
|
147
|
+
if item == nil || item.Data == nil {
|
|
148
|
+
return nil
|
|
149
|
+
}
|
|
150
|
+
return &Resp{
|
|
151
|
+
ID: item.GetID().Int64(),
|
|
152
|
+
Name: item.Data.Name,
|
|
153
|
+
Status: item.Data.Status,
|
|
154
|
+
Remark: item.Data.Remark,
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
func listToResp(items domainx.ComplexList[model.D]) []*Resp {
|
|
159
|
+
resp := make([]*Resp, 0, len(items))
|
|
160
|
+
for _, item := range items {
|
|
161
|
+
if r := toResp(item); r != nil {
|
|
162
|
+
resp = append(resp, r)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return resp
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
func pageToResp(items *[]*domainx.Complex[model.D]) []*Resp {
|
|
169
|
+
if items == nil {
|
|
170
|
+
return []*Resp{}
|
|
171
|
+
}
|
|
172
|
+
resp := make([]*Resp, 0, len(*items))
|
|
173
|
+
for _, item := range *items {
|
|
174
|
+
if r := toResp(item); r != nil {
|
|
175
|
+
resp = append(resp, r)
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return resp
|
|
179
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
package test
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"testing"
|
|
5
|
+
|
|
6
|
+
"<%= projectName %>/domain/<%= moduleName %>"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
func Test<%= ModuleName %>CreateReqValidate(t *testing.T) {
|
|
10
|
+
req := &<%= moduleName %>.CreateReq{Name: " demo "}
|
|
11
|
+
if err := req.Validate(); err != nil {
|
|
12
|
+
t.Fatalf("Validate failed: %v", err)
|
|
13
|
+
}
|
|
14
|
+
if req.Name != "demo" {
|
|
15
|
+
t.Fatalf("expected trimmed name, got %q", req.Name)
|
|
16
|
+
}
|
|
17
|
+
if req.Status != <%= moduleName %>.StatusEnabled {
|
|
18
|
+
t.Fatalf("expected default enabled status, got %q", req.Status)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
func Test<%= ModuleName %>CreateReqValidateRejectsEmptyName(t *testing.T) {
|
|
23
|
+
req := &<%= moduleName %>.CreateReq{Name: " "}
|
|
24
|
+
if err := req.Validate(); err == nil {
|
|
25
|
+
t.Fatal("expected validation error")
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
func Test<%= ModuleName %>UpdateReqUpdates(t *testing.T) {
|
|
30
|
+
req := &<%= moduleName %>.UpdateReq{ID: 1, Status: <%= moduleName %>.StatusDisabled}
|
|
31
|
+
fields, err := req.Updates()
|
|
32
|
+
if err != nil {
|
|
33
|
+
t.Fatalf("Updates failed: %v", err)
|
|
34
|
+
}
|
|
35
|
+
if fields["status"] != <%= moduleName %>.StatusDisabled {
|
|
36
|
+
t.Fatalf("expected disabled status, got %#v", fields["status"])
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
func Test<%= ModuleName %>UpdateReqRejectsEmptyUpdate(t *testing.T) {
|
|
41
|
+
req := &<%= moduleName %>.UpdateReq{ID: 1}
|
|
42
|
+
if _, err := req.Updates(); err == nil {
|
|
43
|
+
t.Fatal("expected empty update error")
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
func Test<%= ModuleName %>QueryReqRejectsInvalidStatus(t *testing.T) {
|
|
48
|
+
req := &<%= moduleName %>.QueryReq{Status: "bad"}
|
|
49
|
+
if err := req.Normalize(); err == nil {
|
|
50
|
+
t.Fatal("expected invalid status error")
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
package <%= moduleName %>
|
|
2
|
+
|
|
3
|
+
import "<%= projectName %>/domain/<%= moduleName %>/model"
|
|
4
|
+
|
|
5
|
+
type EchoReq struct {
|
|
6
|
+
Message string `json:"message" form:"message"`
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
type InfoResp struct {
|
|
10
|
+
Item model.D `json:"item"`
|
|
11
|
+
Message string `json:"message"`
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type EchoResp struct {
|
|
15
|
+
Message string `json:"message"`
|
|
16
|
+
}
|
package/templates/gitignore.ejs
CHANGED
|
@@ -1,64 +1,33 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
/
|
|
4
|
-
/vendor/
|
|
5
|
-
|
|
6
|
-
# Output of the Go build process
|
|
7
|
-
# If you prefer the allow list template instead of the deny list, see community template:
|
|
8
|
-
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
|
9
|
-
#
|
|
10
|
-
# Binaries for programs and plugins
|
|
1
|
+
# Build output
|
|
2
|
+
<%= projectName %>
|
|
3
|
+
bin/
|
|
11
4
|
*.exe
|
|
12
|
-
*.exe~
|
|
13
|
-
*.dll
|
|
14
|
-
*.so
|
|
15
|
-
*.dylib
|
|
16
5
|
*.test
|
|
17
|
-
|
|
18
|
-
# Output of the go coverage tool, specifically when used with LiteIDE
|
|
19
6
|
*.out
|
|
20
7
|
|
|
21
|
-
#
|
|
22
|
-
|
|
8
|
+
# Runtime state
|
|
9
|
+
.cache/
|
|
10
|
+
.logs/
|
|
11
|
+
.deploy/
|
|
12
|
+
tokens.json
|
|
13
|
+
*.log
|
|
14
|
+
*.jsonl
|
|
23
15
|
|
|
24
|
-
#
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
16
|
+
# Secrets and local overrides
|
|
17
|
+
.env
|
|
18
|
+
_bin/*.secret.yaml
|
|
19
|
+
*.pem
|
|
20
|
+
*.crt
|
|
21
|
+
*.key
|
|
28
22
|
|
|
29
|
-
#
|
|
23
|
+
# Editors and operating systems
|
|
30
24
|
.vscode/
|
|
31
25
|
.idea/
|
|
32
26
|
*.swp
|
|
33
|
-
*.swo
|
|
34
|
-
*.swn
|
|
35
27
|
*~
|
|
36
|
-
|
|
37
|
-
# Operating system files
|
|
38
28
|
.DS_Store
|
|
39
29
|
Thumbs.db
|
|
40
30
|
|
|
41
|
-
#
|
|
42
|
-
.env
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
# Ignore everything
|
|
46
|
-
*.sh
|
|
47
|
-
*.log
|
|
48
|
-
*.jsonl
|
|
49
|
-
.logs
|
|
50
|
-
_bin/
|
|
51
|
-
*.yaml
|
|
52
|
-
*.pem
|
|
53
|
-
*.crt
|
|
54
|
-
/test/output/
|
|
55
|
-
*.html
|
|
56
|
-
*.json
|
|
57
|
-
*.cache
|
|
58
|
-
*.cache.json
|
|
59
|
-
|
|
60
|
-
# Go workspace file
|
|
31
|
+
# Go workspace files
|
|
61
32
|
go.work
|
|
62
33
|
go.work.sum
|
|
63
|
-
|
|
64
|
-
# env file
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
package hello
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"github.com/gin-gonic/gin"
|
|
5
|
+
"github.com/jom-io/gorig/apix"
|
|
6
|
+
"github.com/jom-io/gorig/global/consts"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
func Get(ctx *gin.Context) {
|
|
10
|
+
defer apix.HandlePanic(ctx)
|
|
11
|
+
|
|
12
|
+
name, err := apix.GetParamType[string](ctx, "name", apix.NotForce, "world")
|
|
13
|
+
if err != nil {
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
result, serviceErr := Greeting(ctx, name)
|
|
18
|
+
apix.HandleData(ctx, consts.CurdSelectFailCode, result, serviceErr)
|
|
19
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
package hello
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
"strings"
|
|
6
|
+
|
|
7
|
+
"github.com/jom-io/gorig/utils/errors"
|
|
8
|
+
"github.com/jom-io/gorig/utils/logger"
|
|
9
|
+
"<%= moduleName %>/global"
|
|
10
|
+
"go.uber.org/zap"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
type Info struct {
|
|
14
|
+
App string `json:"app"`
|
|
15
|
+
Mode string `json:"mode"`
|
|
16
|
+
Message string `json:"message"`
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
func Greeting(ctx context.Context, name string) (*Info, *errors.Error) {
|
|
20
|
+
name = strings.TrimSpace(name)
|
|
21
|
+
if name == "" {
|
|
22
|
+
return nil, errors.Verify("name cannot be empty")
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
logger.Info(ctx, "building greeting", zap.String("name", name))
|
|
26
|
+
return &Info{
|
|
27
|
+
App: global.SysName,
|
|
28
|
+
Mode: global.RunMode,
|
|
29
|
+
Message: "hello " + name,
|
|
30
|
+
}, nil
|
|
31
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
package test
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
"testing"
|
|
6
|
+
|
|
7
|
+
"<%= moduleName %>/domain/hello"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
func TestGreeting(t *testing.T) {
|
|
11
|
+
result, err := hello.Greeting(context.Background(), "Gorig")
|
|
12
|
+
if err != nil {
|
|
13
|
+
t.Fatalf("Greeting failed: %v", err)
|
|
14
|
+
}
|
|
15
|
+
if result == nil {
|
|
16
|
+
t.Fatal("expected result, got nil")
|
|
17
|
+
}
|
|
18
|
+
if result.Mode != "local" {
|
|
19
|
+
t.Fatalf("expected local mode, got %q", result.Mode)
|
|
20
|
+
}
|
|
21
|
+
if result.Message != "hello Gorig" {
|
|
22
|
+
t.Fatalf("unexpected message: %q", result.Message)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
func TestGreetingRejectsEmptyName(t *testing.T) {
|
|
27
|
+
result, err := hello.Greeting(context.Background(), " ")
|
|
28
|
+
if err == nil {
|
|
29
|
+
t.Fatal("expected validation error")
|
|
30
|
+
}
|
|
31
|
+
if result != nil {
|
|
32
|
+
t.Fatalf("expected nil result, got %#v", result)
|
|
33
|
+
}
|
|
34
|
+
}
|
package/templates/init.go.ejs
CHANGED
|
@@ -1,29 +1,3 @@
|
|
|
1
1
|
package domain
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
"github.com/gin-gonic/gin"
|
|
5
|
-
"github.com/jom-io/gorig/apix/response"
|
|
6
|
-
"github.com/jom-io/gorig/httpx"
|
|
7
|
-
"github.com/jom-io/gorig/serv"
|
|
8
|
-
configure "github.com/jom-io/gorig/utils/cofigure"
|
|
9
|
-
"github.com/jom-io/gorig/utils/sys"
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
func init() {
|
|
13
|
-
httpx.RegisterRouter(func(groupRouter *gin.RouterGroup) {
|
|
14
|
-
groupRouter.GET("/", func(ctx *gin.Context) {
|
|
15
|
-
response.Success(ctx, "Hello world, this is <%= projectNameUpper %> project generated by gorig-cli", nil)
|
|
16
|
-
})
|
|
17
|
-
})
|
|
18
|
-
err := serv.RegisterService(
|
|
19
|
-
serv.Service{
|
|
20
|
-
Code: "<%= projectNameUpper %>_HTTP",
|
|
21
|
-
PORT: configure.GetString("api.rest.addr", ":9527"),
|
|
22
|
-
Startup: httpx.Startup,
|
|
23
|
-
Shutdown: httpx.Shutdown,
|
|
24
|
-
},
|
|
25
|
-
)
|
|
26
|
-
if err != nil {
|
|
27
|
-
sys.Exit(err)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
3
|
+
import _ "<%= moduleName %>/domain/hello"
|
package/templates/main.go.ejs
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
package main
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
"github.com/jom-io/gorig/bootstrap"
|
|
5
|
-
)
|
|
3
|
+
import "github.com/jom-io/gorig/bootstrap"
|
|
6
4
|
|
|
7
|
-
import _ "<%=
|
|
8
|
-
import _ "<%= projectName %>/domain"
|
|
5
|
+
import _ "<%= moduleName %>/domain"
|
|
9
6
|
|
|
10
7
|
func main() {
|
|
11
8
|
bootstrap.StartUp()
|
package/templates/model.go.ejs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
package model
|
|
2
2
|
|
|
3
|
-
type
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
FieldInt int64 `gorm:"column:fieldInt;type:bigint(20);comment:fieldInt" json:"fieldInt" form:"fieldInt"`
|
|
3
|
+
type D struct {
|
|
4
|
+
ID string `json:"id" form:"id"`
|
|
5
|
+
Name string `json:"name" form:"name"`
|
|
7
6
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# <%= projectName %>
|
|
2
|
+
|
|
3
|
+
Basic Gorig backend generated by `gorig-cli`.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Go 1.23+
|
|
8
|
+
- Gorig `<%= gorigVersion %>`
|
|
9
|
+
|
|
10
|
+
## Run
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
GORIG_SYS_MODE=local go run ./_cmd
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Environment configuration:
|
|
17
|
+
|
|
18
|
+
| Mode | File | Default port |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| local | `_bin/local.yaml` | <%= localPort %> |
|
|
21
|
+
| dev | `_bin/dev.yaml` | <%= devPort %> |
|
|
22
|
+
| prod | `_bin/prod.yaml` | <%= prodPort %> |
|
|
23
|
+
|
|
24
|
+
Select a configuration with `GORIG_SYS_MODE`. Override individual values with variables such as `GORIG_API_REST_ADDR`.
|
|
25
|
+
|
|
26
|
+
## Verify
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
go fmt ./...
|
|
30
|
+
go vet ./...
|
|
31
|
+
go build ./...
|
|
32
|
+
go test ./... -v
|
|
33
|
+
curl 'http://127.0.0.1:<%= localPort %>/ping'
|
|
34
|
+
curl 'http://127.0.0.1:<%= localPort %>/hello?name=Gorig'
|
|
35
|
+
```
|
package/templates/router.go.ejs
CHANGED
|
@@ -6,13 +6,9 @@ import (
|
|
|
6
6
|
)
|
|
7
7
|
|
|
8
8
|
func init() {
|
|
9
|
-
httpx.RegisterRouter(func(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
<%= moduleName %>.GET("list", List<%= ModuleName %>)
|
|
14
|
-
<%= moduleName %>.POST("save", Save<%= ModuleName %>)
|
|
15
|
-
<%= moduleName %>.GET("info", Get<%= ModuleName %>)
|
|
16
|
-
<%= moduleName %>.DELETE("delete", Delete<%= ModuleName %>)
|
|
9
|
+
httpx.RegisterRouter(func(root *gin.RouterGroup) {
|
|
10
|
+
group := root.Group("/<%= moduleName %>")
|
|
11
|
+
group.GET("/info", Info)
|
|
12
|
+
group.POST("/echo", Echo)
|
|
17
13
|
})
|
|
18
14
|
}
|