go-duck-cli 1.0.8 → 1.1.1

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.
Files changed (70) hide show
  1. package/README.md +30 -15
  2. package/generators/ai_docs.js +130 -0
  3. package/generators/broker.js +63 -0
  4. package/generators/config.js +149 -7
  5. package/generators/devops.js +210 -43
  6. package/generators/docs.js +23 -4
  7. package/generators/elasticsearch.js +263 -0
  8. package/generators/kratos.js +229 -41
  9. package/generators/metering.js +280 -48
  10. package/generators/migrations.js +92 -198
  11. package/generators/mqtt.js +2 -39
  12. package/generators/multitenancy.js +274 -71
  13. package/generators/nats.js +39 -0
  14. package/generators/outbox.js +171 -0
  15. package/generators/postgrest.js +7 -3
  16. package/generators/postman.js +405 -0
  17. package/generators/repository.js +27 -0
  18. package/generators/router.js +27 -0
  19. package/generators/security.js +95 -14
  20. package/generators/serverless.js +147 -0
  21. package/generators/storage.js +589 -0
  22. package/generators/swagger.js +84 -60
  23. package/generators/telemetry.js +23 -32
  24. package/generators/websocket.js +55 -21
  25. package/index.js +481 -116
  26. package/package.json +6 -4
  27. package/parser/gdl.js +163 -24
  28. package/templates/docs/index.html.hbs +5 -5
  29. package/templates/docs/layout.hbs +221 -62
  30. package/templates/docs/pages/audit.hbs +83 -35
  31. package/templates/docs/pages/cli.hbs +18 -0
  32. package/templates/docs/pages/configuration.hbs +241 -0
  33. package/templates/docs/pages/datadog.hbs +46 -0
  34. package/templates/docs/pages/elasticsearch.hbs +121 -0
  35. package/templates/docs/pages/federation.hbs +241 -0
  36. package/templates/docs/pages/gdl-advanced.hbs +91 -0
  37. package/templates/docs/pages/gdl-annotations.hbs +137 -0
  38. package/templates/docs/pages/gdl-entities.hbs +134 -0
  39. package/templates/docs/pages/gdl-relationships.hbs +80 -0
  40. package/templates/docs/pages/gdl.hbs +60 -204
  41. package/templates/docs/pages/graphql.hbs +58 -44
  42. package/templates/docs/pages/grpc.hbs +53 -90
  43. package/templates/docs/pages/hybrid-store.hbs +127 -0
  44. package/templates/docs/pages/index.hbs +418 -149
  45. package/templates/docs/pages/keycloak.hbs +43 -0
  46. package/templates/docs/pages/legend.hbs +116 -0
  47. package/templates/docs/pages/mosquitto.hbs +39 -0
  48. package/templates/docs/pages/multitenancy.hbs +139 -71
  49. package/templates/docs/pages/otel.hbs +40 -0
  50. package/templates/docs/pages/realtime.hbs +38 -12
  51. package/templates/docs/pages/redis.hbs +40 -0
  52. package/templates/docs/pages/rest.hbs +120 -202
  53. package/templates/docs/pages/saga.hbs +94 -0
  54. package/templates/docs/pages/security.hbs +150 -44
  55. package/templates/docs/pages/serverless.hbs +157 -0
  56. package/templates/docs/pages/storage.hbs +127 -0
  57. package/templates/docs/pages/wizard.hbs +683 -0
  58. package/templates/docs/triple_identity_registry.png +0 -0
  59. package/templates/go/controller.go.hbs +287 -283
  60. package/templates/go/entity.go.hbs +17 -15
  61. package/templates/go/main.go.hbs +47 -180
  62. package/templates/go/migrator.go.hbs +65 -0
  63. package/templates/go/router.go.hbs +272 -0
  64. package/templates/graphql/resolver.go.hbs +53 -34
  65. package/templates/graphql/schema.graphql.hbs +17 -5
  66. package/templates/kratos/service.go.hbs +169 -34
  67. package/templates/proto/entity.proto.hbs +10 -14
  68. package/test_nested.gdl +21 -0
  69. package/templates/docs/intro.mp4 +0 -0
  70. package/test_parser.js +0 -9
@@ -1,50 +1,69 @@
1
1
  package graph
2
2
 
3
3
  import (
4
- "encoding/json"
5
4
  "net/http"
5
+ {{#if entities}}
6
6
  "{{app_name}}/models"
7
+ {{/if}}
7
8
 
8
9
  "github.com/gin-gonic/gin"
9
10
  "gorm.io/gorm"
11
+ "fmt"
10
12
  )
11
13
 
12
- // HandleGraphQLRequest is the main bridge for the Gin web framework.
13
- // In a production app, we would use a more robust engine (like gqlgen).
14
- func HandleGraphQLRequest(db *gorm.DB, c *gin.Context) {
15
- var input struct {
16
- Query string \`json:"query"\`
17
- Variables map[string]interface{} \`json:"variables"\`
14
+ // Resolver for each entity (Federated)
15
+ {{#each entities}}
16
+ func Resolve{{capitalize name}}Federated(silos map[string]*gorm.DB, id uint) ([]interface{}, error) {
17
+ var results []interface{}
18
+ for role, db := range silos {
19
+ var e models.{{capitalize name}}
20
+ if err := db.First(&e, id).Error; err == nil {
21
+ results = append(results, gin.H{
22
+ "role": role,
23
+ "data": e,
24
+ })
25
+ }
26
+ }
27
+ return results, nil
18
28
  }
19
29
 
20
- if err := c.BindJSON(&input); err != nil {
21
- c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid GraphQL request"})
22
- return
30
+ func ResolveAll{{capitalize name}}sFederated(silos map[string]*gorm.DB) ([]interface{}, error) {
31
+ var results []interface{}
32
+ for role, db := range silos {
33
+ var list []models.{{capitalize name}}
34
+ if err := db.Find(&list).Error; err == nil {
35
+ results = append(results, gin.H{
36
+ "role": role,
37
+ "items": list,
38
+ })
39
+ }
40
+ }
41
+ return results, nil
23
42
  }
43
+ {{/each}}
24
44
 
25
- // We'll perform basic routing for the POC.
26
- // For production, this should integrate with a real schema loader.
27
- c.JSON(http.StatusOK, gin.H{
28
- "data": "GraphQL Handler Integrated Successfully!",
29
- "note": "Ready for schema execution.",
30
- })
31
- }
45
+ // HandleGraphQLRequest is the main bridge for the Federated Gin context
46
+ func HandleGraphQLRequest(c *gin.Context) {
47
+ siloConns, exists := c.Get("tenantSiloConns")
48
+ if !exists {
49
+ c.JSON(http.StatusForbidden, gin.H{"error": "No tenant context found"})
50
+ return
51
+ }
52
+ conns := siloConns.(map[string]*gorm.DB)
32
53
 
33
- // Resolver for each entity
34
- {{#each entities}}
35
- func Resolve{{capitalize name}}(db *gorm.DB, id uint) (*models.{{capitalize name}}, error) {
36
- var e models.{{capitalize name}}
37
- if err := db.First(&e, id).Error; err != nil {
38
- return nil, err
39
- }
40
- return &e, nil
41
- }
54
+ var input struct {
55
+ Query string `json:"query"`
56
+ Variables map[string]interface{} `json:"variables"`
57
+ }
42
58
 
43
- func ResolveAll{{capitalize name}}s(db *gorm.DB) ([]models.{{capitalize name}}, error) {
44
- var list []models.{{capitalize name}}
45
- if err := db.Find(&list).Error; err != nil {
46
- return nil, err
47
- }
48
- return list, nil
49
- }
50
- {{/each}}
59
+ if err := c.BindJSON(&input); err != nil {
60
+ c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid GraphQL request"})
61
+ return
62
+ }
63
+
64
+ // This is where real schema execution would happen using 'conns'
65
+ // For POC, return successful federation state
66
+ c.JSON(http.StatusOK, gin.H{
67
+ "data": "Federated GraphQL Handler active with " + fmt.Sprintf("%d", len(conns)) + " silos.",
68
+ })
69
+ }
@@ -48,17 +48,29 @@ enum {{name}} {
48
48
  }
49
49
  {{/each}}
50
50
 
51
+ {{#each entities}}
52
+ type Federated{{capitalize name}}List {
53
+ role: String!
54
+ items: [{{capitalize name}}]
55
+ }
56
+
57
+ type Federated{{capitalize name}} {
58
+ role: String!
59
+ data: {{capitalize name}}
60
+ }
61
+ {{/each}}
62
+
51
63
  type Query {
52
64
  {{#each entities}}
53
- get{{capitalize name}}(id: ID!): {{name}}
54
- list{{capitalize name}}s(page: Int, size: Int): [{{name}}]
65
+ get{{capitalize name}}(id: ID!): [Federated{{capitalize name}}]
66
+ list{{capitalize name}}s(page: Int, size: Int): [Federated{{capitalize name}}List]
55
67
  {{/each}}
56
68
  }
57
69
 
58
70
  type Mutation {
59
71
  {{#each entities}}
60
- create{{capitalize name}}(input: Create{{name}}Input!): {{name}}
61
- update{{capitalize name}}(id: ID!, input: Update{{name}}Input!): {{name}}
62
- delete{{capitalize name}}(id: ID!): Boolean
72
+ create{{capitalize name}}(input: Create{{capitalize name}}Input!): Federated{{capitalize name}}
73
+ update{{capitalize name}}(id: ID!, input: Update{{capitalize name}}Input!): Federated{{capitalize name}}
74
+ delete{{capitalize name}}(id: ID!): Boolean
63
75
  {{/each}}
64
76
  }
@@ -2,12 +2,28 @@ package service
2
2
 
3
3
  import (
4
4
  "context"
5
+ {{#if isDocument}}
6
+ "fmt"
7
+ {{/if}}
8
+ {{#if (hasNested fields)}}
9
+ "encoding/json"
10
+ {{/if}}
11
+ {{#if (hasInstant fields)}}
12
+ "time"
13
+ {{/if}}
5
14
  pb "{{projectName}}/api/v1"
6
15
  "{{projectName}}/internal/repository"
7
16
  "{{projectName}}/models"
8
17
  {{#if (hasJson fields)}}
9
18
  "gorm.io/datatypes"
10
19
  {{/if}}
20
+ {{#if isDocument}}
21
+ "go.mongodb.org/mongo-driver/bson"
22
+ "go.mongodb.org/mongo-driver/mongo"
23
+ "go.mongodb.org/mongo-driver/mongo/options"
24
+ {{else}}
25
+ "gorm.io/gorm"
26
+ {{/if}}
11
27
  "google.golang.org/protobuf/types/known/timestamppb"
12
28
  )
13
29
 
@@ -21,84 +37,203 @@ func New{{capitalize name}}Service(repo *repository.Repository) *{{capitalize na
21
37
  }
22
38
 
23
39
  func (s *{{capitalize name}}Service) Create{{capitalize name}}(ctx context.Context, req *pb.Create{{capitalize name}}Request) (*pb.{{capitalize name}}Reply, error) {
40
+ {{#if isDocument}}
41
+ db, ok := ctx.Value("tenantMongoDB").(*mongo.Database)
42
+ if !ok { return nil, fmt.Errorf("mongo database not found in context") }
43
+ {{else}}
44
+ siloConns, _ := ctx.Value("tenantSiloConns").(map[string]*gorm.DB)
45
+ {{/if}}
46
+ federatedData := make(map[string]*pb.{{capitalize name}})
47
+
24
48
  entity := &models.{{capitalize name}}{
25
49
  {{#each fields}}
26
- {{capitalize name}}: {{#if (isJson type)}}datatypes.JSON(req.{{capitalize name}}){{else}}{{#if (toGoCast type)}}{{toGoCast type}}(req.{{capitalize name}}){{else}}req.{{capitalize name}}{{/if}}{{/if}},
50
+ {{#if (eq (toLowerCase type) "localdate")}}
51
+ {{capitalize name}}: parseDate(req.{{toProtoFieldName name}}),
52
+ {{else if (eq (toLowerCase type) "instant")}}
53
+ {{capitalize name}}: parseInstant(req.{{toProtoFieldName name}}),
54
+ {{else if (eq (toLowerCase type) "datetime")}}
55
+ {{capitalize name}}: parseInstant(req.{{toProtoFieldName name}}),
56
+ {{else if (isJson type)}}
57
+ {{capitalize name}}: datatypes.JSON(req.{{toProtoFieldName name}}),
58
+ {{else if isNested}}
59
+ // Nested fields are mapped via JSON for simplicity in gRPC
60
+ {{else}}
61
+ {{capitalize name}}: {{#if (toGoCast type)}}{{toGoCast type}}(req.{{toProtoFieldName name}}){{else}}req.{{toProtoFieldName name}}{{/if}},
62
+ {{/if}}
27
63
  {{/each}}
28
64
  }
29
- if err := s.repo.DB.WithContext(ctx).Create(entity).Error; err != nil {
30
- return nil, err
65
+
66
+ {{#if isDocument}}
67
+ {{#each fields}}{{#if isNested}}
68
+ json.Unmarshal([]byte(req.{{toProtoFieldName name}}), &entity.{{capitalize name}})
69
+ {{/if}}{{/each}}
70
+ res, err := db.Collection("{{toLowerCase name}}s").InsertOne(ctx, entity)
71
+ if err == nil {
72
+ entity.ID = fmt.Sprintf("%v", res.InsertedID)
73
+ federatedData["tenant"] = map{{capitalize name}}ToPb(entity)
74
+ }
75
+ {{else}}
76
+ for role, db := range siloConns {
77
+ if err := db.WithContext(ctx).Create(entity).Error; err == nil {
78
+ federatedData[role] = map{{capitalize name}}ToPb(entity)
79
+ }
31
80
  }
81
+ {{/if}}
82
+
32
83
  return &pb.{{capitalize name}}Reply{
33
- Data: map{{capitalize name}}ToPb(entity),
84
+ FederatedData: federatedData,
34
85
  }, nil
35
86
  }
36
87
 
37
88
  func (s *{{capitalize name}}Service) Get{{capitalize name}}(ctx context.Context, req *pb.Get{{capitalize name}}Request) (*pb.{{capitalize name}}Reply, error) {
89
+ federatedData := make(map[string]*pb.{{capitalize name}})
90
+
91
+ {{#if isDocument}}
92
+ db, _ := ctx.Value("tenantMongoDB").(*mongo.Database)
38
93
  var entity models.{{capitalize name}}
39
- if err := s.repo.DB.WithContext(ctx).First(&entity, req.Id).Error; err != nil {
40
- return nil, err
94
+ if err := db.Collection("{{toLowerCase name}}s").FindOne(ctx, bson.M{"_id": req.Id}).Decode(&entity); err == nil {
95
+ federatedData["tenant"] = map{{capitalize name}}ToPb(&entity)
96
+ }
97
+ {{else}}
98
+ siloConns, _ := ctx.Value("tenantSiloConns").(map[string]*gorm.DB)
99
+ for role, db := range siloConns {
100
+ var entity models.{{capitalize name}}
101
+ if err := db.WithContext(ctx).First(&entity, req.Id).Error; err == nil {
102
+ federatedData[role] = map{{capitalize name}}ToPb(&entity)
103
+ }
41
104
  }
105
+ {{/if}}
106
+
42
107
  return &pb.{{capitalize name}}Reply{
43
- Data: map{{capitalize name}}ToPb(&entity),
108
+ FederatedData: federatedData,
44
109
  }, nil
45
110
  }
46
111
 
47
112
  func (s *{{capitalize name}}Service) Update{{capitalize name}}(ctx context.Context, req *pb.Update{{capitalize name}}Request) (*pb.{{capitalize name}}Reply, error) {
113
+ federatedData := make(map[string]*pb.{{capitalize name}})
114
+
48
115
  var entity models.{{capitalize name}}
49
- if err := s.repo.DB.WithContext(ctx).First(&entity, req.Id).Error; err != nil {
50
- return nil, err
51
- }
52
-
116
+ {{#if isDocument}}
117
+ entity.ID = req.Id
118
+ {{/if}}
53
119
  {{#each fields}}
54
- entity.{{capitalize name}} = {{#if (isJson type)}}datatypes.JSON(req.{{capitalize name}}){{else}}{{#if (toGoCast type)}}{{toGoCast type}}(req.{{capitalize name}}){{else}}req.{{capitalize name}}{{/if}}{{/if}}
120
+ {{#if (eq (toLowerCase type) "localdate")}}
121
+ entity.{{capitalize name}} = parseDate(req.{{toProtoFieldName name}})
122
+ {{else if (eq (toLowerCase type) "instant")}}
123
+ entity.{{capitalize name}} = parseInstant(req.{{toProtoFieldName name}})
124
+ {{else if (eq (toLowerCase type) "datetime")}}
125
+ entity.{{capitalize name}} = parseInstant(req.{{toProtoFieldName name}})
126
+ {{else if (isJson type)}}
127
+ entity.{{capitalize name}} = datatypes.JSON(req.{{toProtoFieldName name}})
128
+ {{else if isNested}}
129
+ json.Unmarshal([]byte(req.{{toProtoFieldName name}}), &entity.{{capitalize name}})
130
+ {{else}}
131
+ entity.{{capitalize name}} = {{#if (toGoCast type)}}{{toGoCast type}}(req.{{toProtoFieldName name}}){{else}}req.{{toProtoFieldName name}}{{/if}}
132
+ {{/if}}
55
133
  {{/each}}
56
134
 
57
- if err := s.repo.DB.WithContext(ctx).Save(&entity).Error; err != nil {
58
- return nil, err
135
+ {{#if isDocument}}
136
+ db, _ := ctx.Value("tenantMongoDB").(*mongo.Database)
137
+ if _, err := db.Collection("{{toLowerCase name}}s").ReplaceOne(ctx, bson.M{"_id": req.Id}, entity); err == nil {
138
+ federatedData["tenant"] = map{{capitalize name}}ToPb(&entity)
139
+ }
140
+ {{else}}
141
+ siloConns, _ := ctx.Value("tenantSiloConns").(map[string]*gorm.DB)
142
+ for role, db := range siloConns {
143
+ if err := db.WithContext(ctx).Model(&models.{{capitalize name}}{}).Where("id = ?", req.Id).Save(&entity).Error; err == nil {
144
+ federatedData[role] = map{{capitalize name}}ToPb(&entity)
145
+ }
59
146
  }
147
+ {{/if}}
148
+
60
149
  return &pb.{{capitalize name}}Reply{
61
- Data: map{{capitalize name}}ToPb(&entity),
150
+ FederatedData: federatedData,
62
151
  }, nil
63
152
  }
64
153
 
65
154
  func (s *{{capitalize name}}Service) Delete{{capitalize name}}(ctx context.Context, req *pb.Delete{{capitalize name}}Request) (*pb.Delete{{capitalize name}}Reply, error) {
66
- if err := s.repo.DB.WithContext(ctx).Delete(&models.{{capitalize name}}{}, req.Id).Error; err != nil {
67
- return nil, err
155
+ {{#if isDocument}}
156
+ db, _ := ctx.Value("tenantMongoDB").(*mongo.Database)
157
+ db.Collection("{{toLowerCase name}}s").DeleteOne(ctx, bson.M{"_id": req.Id})
158
+ {{else}}
159
+ siloConns, _ := ctx.Value("tenantSiloConns").(map[string]*gorm.DB)
160
+ for _, db := range siloConns {
161
+ db.WithContext(ctx).Where("id = ?", req.Id).Delete(&models.{{capitalize name}}{})
68
162
  }
69
- return &pb.Delete{{capitalize name}}Reply{Message: "Success"}, nil
163
+ {{/if}}
164
+ return &pb.Delete{{capitalize name}}Reply{Message: "Delete completed"}, nil
70
165
  }
71
166
 
72
167
  func (s *{{capitalize name}}Service) List{{capitalize name}}(ctx context.Context, req *pb.List{{capitalize name}}Request) (*pb.List{{capitalize name}}Reply, error) {
73
- var results []models.{{capitalize name}}
168
+ federatedResults := make(map[string]*pb.{{capitalize name}}List)
74
169
  var total int64
75
-
76
- db := s.repo.DB.WithContext(ctx).Model(&models.{{capitalize name}}{})
77
- db.Count(&total)
78
-
79
- offset := (req.Page - 1) * req.PageSize
80
- if err := db.Limit(int(req.PageSize)).Offset(int(offset)).Find(&results).Error; err != nil {
81
- return nil, err
170
+
171
+ {{#if isDocument}}
172
+ db, _ := ctx.Value("tenantMongoDB").(*mongo.Database)
173
+ var results []models.{{capitalize name}}
174
+ opts := options.Find().SetSkip(int64((req.Page - 1) * req.PageSize)).SetLimit(int64(req.PageSize))
175
+ cursor, err := db.Collection("{{toLowerCase name}}s").Find(ctx, bson.M{}, opts)
176
+ if err == nil {
177
+ cursor.All(ctx, &results)
178
+ items := make([]*pb.{{capitalize name}}, len(results))
179
+ for i, r := range results {
180
+ items[i] = map{{capitalize name}}ToPb(&r)
181
+ }
182
+ federatedResults["tenant"] = &pb.{{capitalize name}}List{Items: items}
183
+ count, _ := db.Collection("{{toLowerCase name}}s").CountDocuments(ctx, bson.M{})
184
+ total = count
82
185
  }
83
-
84
- pbResults := make([]*pb.{{capitalize name}}, len(results))
85
- for i, r := range results {
86
- pbResults[i] = map{{capitalize name}}ToPb(&r)
186
+ {{else}}
187
+ siloConns, _ := ctx.Value("tenantSiloConns").(map[string]*gorm.DB)
188
+ for role, db := range siloConns {
189
+ var results []models.{{capitalize name}}
190
+ query := db.WithContext(ctx).Model(&models.{{capitalize name}}{})
191
+
192
+ var count int64
193
+ query.Count(&count)
194
+ total += count
195
+
196
+ offset := (req.Page - 1) * req.PageSize
197
+ if err := query.Limit(int(req.PageSize)).Offset(int(offset)).Find(&results).Error; err == nil {
198
+ items := make([]*pb.{{capitalize name}}, len(results))
199
+ for i, r := range results {
200
+ items[i] = map{{capitalize name}}ToPb(&r)
201
+ }
202
+ federatedResults[role] = &pb.{{capitalize name}}List{Items: items}
203
+ }
87
204
  }
205
+ {{/if}}
88
206
 
89
207
  return &pb.List{{capitalize name}}Reply{
90
- Results: pbResults,
91
- Total: total,
208
+ FederatedResults: federatedResults,
209
+ Total: total,
92
210
  }, nil
93
211
  }
94
212
 
95
213
  func map{{capitalize name}}ToPb(m *models.{{capitalize name}}) *pb.{{capitalize name}} {
96
214
  return &pb.{{capitalize name}}{
97
- Id: uint64(m.ID),
215
+ Id: {{#if isDocument}}m.ID{{else}}uint64(m.ID){{/if}},
98
216
  {{#each fields}}
99
- {{capitalize name}}: {{#if (isJson type)}}string(m.{{capitalize name}}){{else}}{{#if (toProtoCast type)}}{{toProtoCast type}}(m.{{capitalize name}}){{else}}m.{{capitalize name}}{{/if}}{{/if}},
217
+ {{#if (eq (toLowerCase type) "localdate")}}
218
+ {{toProtoFieldName name}}: m.{{capitalize name}}.Format("2006-01-02"),
219
+ {{else if (eq (toLowerCase type) "instant")}}
220
+ {{toProtoFieldName name}}: m.{{capitalize name}}.Format(time.RFC3339),
221
+ {{else if (eq (toLowerCase type) "datetime")}}
222
+ {{toProtoFieldName name}}: m.{{capitalize name}}.Format(time.RFC3339),
223
+ {{else if (isJson type)}}
224
+ {{toProtoFieldName name}}: string(m.{{capitalize name}}),
225
+ {{else if isNested}}
226
+ {{toProtoFieldName name}}: (func() string { b, _ := json.Marshal(m.{{capitalize name}}); return string(b) })(),
227
+ {{else}}
228
+ {{toProtoFieldName name}}: {{#if (toProtoCast type)}}{{toProtoCast type}}(m.{{capitalize name}}){{else}}m.{{capitalize name}}{{/if}},
229
+ {{/if}}
100
230
  {{/each}}
231
+ {{#if isAudited}}
232
+ CreatedAt: timestamppb.New(m.CreatedDate),
233
+ UpdatedAt: timestamppb.New(m.LastModifiedDate),
234
+ {{else}}
101
235
  CreatedAt: timestamppb.New(m.CreatedAt),
102
236
  UpdatedAt: timestamppb.New(m.UpdatedAt),
237
+ {{/if}}
103
238
  }
104
239
  }
@@ -38,7 +38,7 @@ service {{capitalize name}}Service {
38
38
  }
39
39
 
40
40
  message {{capitalize name}} {
41
- uint64 id = 1;
41
+ {{#if isDocument}}string{{else}}uint64{{/if}} id = 1;
42
42
  {{#each fields}}
43
43
  {{toProtoType type}} {{name}} = {{add @index 2}};
44
44
  {{/each}}
@@ -53,14 +53,14 @@ message Create{{capitalize name}}Request {
53
53
  }
54
54
 
55
55
  message Update{{capitalize name}}Request {
56
- uint64 id = 1;
56
+ {{#if isDocument}}string{{else}}uint64{{/if}} id = 1;
57
57
  {{#each fields}}
58
58
  {{toProtoType type}} {{name}} = {{add @index 2}};
59
59
  {{/each}}
60
60
  }
61
61
 
62
62
  message Delete{{capitalize name}}Request {
63
- uint64 id = 1;
63
+ {{#if isDocument}}string{{else}}uint64{{/if}} id = 1;
64
64
  }
65
65
 
66
66
  message Delete{{capitalize name}}Reply {
@@ -68,11 +68,15 @@ message Delete{{capitalize name}}Reply {
68
68
  }
69
69
 
70
70
  message Get{{capitalize name}}Request {
71
- uint64 id = 1;
71
+ {{#if isDocument}}string{{else}}uint64{{/if}} id = 1;
72
+ }
73
+
74
+ message {{capitalize name}}List {
75
+ repeated {{capitalize name}} items = 1;
72
76
  }
73
77
 
74
78
  message {{capitalize name}}Reply {
75
- {{capitalize name}} data = 1;
79
+ map<string, {{capitalize name}}> federated_data = 1;
76
80
  }
77
81
 
78
82
  message List{{capitalize name}}Request {
@@ -82,14 +86,6 @@ message List{{capitalize name}}Request {
82
86
  }
83
87
 
84
88
  message List{{capitalize name}}Reply {
85
- repeated {{capitalize name}} results = 1;
89
+ map<string, {{capitalize name}}List> federated_results = 1;
86
90
  int64 total = 2;
87
91
  }
88
- {{#each enums}}
89
- enum {{capitalize name}} {
90
- {{capitalize name}}_UNSPECIFIED = 0;
91
- {{#each values}}
92
- {{capitalize ../name}}_{{this}} = {{add @index 1}};
93
- {{/each}}
94
- }
95
- {{/each}}
@@ -0,0 +1,21 @@
1
+ @Document @Audited @Federated
2
+ entity PatientRecord {
3
+ patientId String required unique
4
+ clinicalData {
5
+ vitals {
6
+ bpm Integer
7
+ temp Float
8
+ }
9
+ notes Text
10
+ }
11
+ }
12
+
13
+ relationship OneToMany {
14
+ PatientRecord to ClinicalNote
15
+ }
16
+
17
+ enum PatientStatus {
18
+ ACTIVE, INACTIVE, DECEASED
19
+ }
20
+
21
+ open PatientRecord(read, create)
Binary file
package/test_parser.js DELETED
@@ -1,9 +0,0 @@
1
- import fs from 'fs-extra';
2
-
3
- const content = fs.readFileSync('../GDL/app.gdl', 'utf8');
4
- const relRegex = /relationship\s+(\w+)\s*\{([^}]*)\}/g;
5
- let match;
6
- while ((match = relRegex.exec(content)) !== null) {
7
- console.log('Type:', match[1]);
8
- console.log('Block:', match[2]);
9
- }