From 8206ee7c181da9940aa533555b3ef47aa93a7f0c Mon Sep 17 00:00:00 2001 From: Daniel Pupius Date: Sat, 27 Apr 2024 10:01:35 -0700 Subject: [PATCH] Use field_name?: field_type for optional fields, instead of OneOf extension, see #5 (#13) --- data/message.go | 2 ++ generator/template.go | 8 ++++++-- registry/field.go | 6 +++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/data/message.go b/data/message.go index 3552547..ebb421c 100644 --- a/data/message.go +++ b/data/message.go @@ -14,6 +14,8 @@ type Message struct { Fields []*Field // NonOneOfFields contains a subset of fields that are not in the one-of groups NonOneOfFields []*Field + // OptionalFields contains a subset of fields that are optional + OptionalFields []*Field // Message is the nested messages defined inside the message Messages []*Message // OneOfFieldsGroups is the grouped list of one of fields with same index. so that renderer can render the clearing of other fields on set. diff --git a/generator/template.go b/generator/template.go index f04f084..f6f6b4b 100644 --- a/generator/template.go +++ b/generator/template.go @@ -37,6 +37,9 @@ type Base{{.Name}} = { {{- range .NonOneOfFields}} {{tsTypeKey .}}: {{tsTypeDef .}} {{- end}} +{{- range .OptionalFields}} + {{tsTypeKey .}}: {{tsTypeDef .}} +{{- end}} } export type {{.Name}} = Base{{.Name}} @@ -541,9 +544,10 @@ func include(t *template.Template) func(name string, data interface{}) (string, func tsTypeKey(r *registry.Registry) func(field *data.Field) string { return func(field *data.Field) string { name := fieldName(r)(field.Name) - if !r.EmitUnpopulated { + if !r.EmitUnpopulated || field.IsOptional { // When EmitUnpopulated is false, the gateway will return undefined for - // any zero value, so all fields may be undefined. + // any zero value, so all fields may be undefined. Optional fields, may + // also be undefined if unset. return name + "?" } // When it is false, only optional fields can be undefined, however they are diff --git a/registry/field.go b/registry/field.go index 53390e4..d84740b 100644 --- a/registry/field.go +++ b/registry/field.go @@ -74,6 +74,9 @@ func (r *Registry) analyseField(fileData *data.File, msgData *data.Message, pack if !fieldData.IsOneOfField { msgData.NonOneOfFields = append(msgData.NonOneOfFields, fieldData) } + if fieldData.IsOptional { + msgData.OptionalFields = append(msgData.OptionalFields, fieldData) + } // if it's an external dependencies. store in the file data so that they can be collected when every file's finished if isExternal { @@ -81,7 +84,8 @@ func (r *Registry) analyseField(fileData *data.File, msgData *data.Message, pack } // if it's a one of field. register the field data in the group of the same one of index. - if fieldData.IsOneOfField { // one of field + // internally, optional fields are modeled as OneOf, however, we don't want to include them here. + if fieldData.IsOneOfField && !fieldData.IsOptional { index := f.GetOneofIndex() fieldData.OneOfIndex = index _, ok := msgData.OneOfFieldsGroups[index]