diff --git a/contact/.gitignore b/contact/.gitignore new file mode 100644 index 0000000..82255ce --- /dev/null +++ b/contact/.gitignore @@ -0,0 +1,2 @@ + +contact diff --git a/contact/Dockerfile b/contact/Dockerfile new file mode 100644 index 0000000..17aa35a --- /dev/null +++ b/contact/Dockerfile @@ -0,0 +1,3 @@ +FROM alpine +ADD contact /contact +ENTRYPOINT [ "/contact" ] diff --git a/contact/Makefile b/contact/Makefile new file mode 100644 index 0000000..20b66cc --- /dev/null +++ b/contact/Makefile @@ -0,0 +1,28 @@ + +GOPATH:=$(shell go env GOPATH) +.PHONY: init +init: + go get -u github.com/golang/protobuf/proto + go get -u github.com/golang/protobuf/protoc-gen-go + go get github.com/micro/micro/v3/cmd/protoc-gen-micro + go get github.com/micro/micro/v3/cmd/protoc-gen-openapi + +.PHONY: api +api: + protoc --openapi_out=. --proto_path=. proto/contact.proto + +.PHONY: proto +proto: + protoc --proto_path=. --micro_out=. --go_out=:. proto/contact.proto + +.PHONY: build +build: + go build -o contact *.go + +.PHONY: test +test: + go test -v ./... -cover + +.PHONY: docker +docker: + docker build . -t contact:latest diff --git a/contact/README.md b/contact/README.md new file mode 100644 index 0000000..3758504 --- /dev/null +++ b/contact/README.md @@ -0,0 +1,5 @@ +Store your contacts + +# Contact Service + +This is the Contact service diff --git a/contact/domain/contact.go b/contact/domain/contact.go new file mode 100644 index 0000000..965f709 --- /dev/null +++ b/contact/domain/contact.go @@ -0,0 +1,119 @@ +package domain + +import ( + "context" + "encoding/json" + "fmt" + "time" + + "github.com/micro/micro/v3/service/store" + "github.com/pkg/errors" + + pb "github.com/micro/services/contact/proto" +) + +type Contact interface { + Create(ctx context.Context, info *pb.ContactInfo) error + Update(ctx context.Context, id string, info *pb.ContactInfo) error + Read(ctx context.Context, id string) (result *pb.ContactInfo, err error) + Delete(ctx context.Context, id string) error + List(ctx context.Context, offset, limit uint) (result []*pb.ContactInfo, err error) +} + +type contact struct { + store store.Store +} + +func NewContactDomain(s store.Store) *contact { + return &contact{ + store: s, + } +} + +// contactIdPrefix return the contact prefix of the store key +func contactIdPrefix() string { + return "contact/id/" +} + +// contactIdPrefix return the store key of one contact +func contactIdKey(id string) string { + return fmt.Sprintf("%s%s", contactIdPrefix(), id) +} + +// Create a contact +func (c *contact) Create(ctx context.Context, info *pb.ContactInfo) error { + info.CreatedAt = time.Now().Format(time.RFC3339) + info.UpdatedAt = time.Now().Format(time.RFC3339) + + val, err := json.Marshal(info) + if err != nil { + return err + } + + return store.Write(&store.Record{ + Key: contactIdKey(info.Id), + Value: val, + }) +} + +// Update contact information by id +func (c *contact) Update(ctx context.Context, id string, info *pb.ContactInfo) error { + info.UpdatedAt = time.Now().Format(time.RFC3339) + + val, err := json.Marshal(info) + if err != nil { + return err + } + + return store.Write(&store.Record{ + Key: contactIdKey(id), + Value: val, + }) +} + +// Read one contact by id +func (c *contact) Read(ctx context.Context, id string) (*pb.ContactInfo, error) { + records, err := c.store.Read(contactIdKey(id)) + if err != nil { + return nil, err + } + + if len(records) == 0 { + return nil, errors.New("not found") + } + + info := &pb.ContactInfo{} + if err := json.Unmarshal(records[0].Value, info); err != nil { + return nil, err + } + + return info, err +} + +// Delete one contact by id +func (c *contact) Delete(ctx context.Context, id string) error { + return c.store.Delete(contactIdKey(id)) +} + +// List contacts by offset and limit +func (c *contact) List(ctx context.Context, offset, limit uint) (result []*pb.ContactInfo, err error) { + records, err := c.store.Read(contactIdPrefix(), + store.ReadPrefix(), + store.ReadOffset(offset), + store.ReadLimit(limit)) + if err != nil { + return nil, err + } + + if len(records) == 0 { + return nil, errors.New("not found") + } + + for _, rec := range records { + cinfo := &pb.ContactInfo{} + json.Unmarshal(rec.Value, cinfo) + result = append(result, cinfo) + } + + return result, err +} diff --git a/contact/examples.json b/contact/examples.json new file mode 100644 index 0000000..313b253 --- /dev/null +++ b/contact/examples.json @@ -0,0 +1,387 @@ +{ + "create": [ + { + "title": "Create a contact", + "run_check": false, + "description": "Create a contact with post data", + "request": { + "name": "joe", + "phones": [ + { + "label": "home", + "number": "010-12345678" + }, + { + "label": "work", + "number": "010-87654321" + } + ], + "emails": [ + { + "label": "home", + "address": "home@example.com" + }, + { + "label": "work", + "address": "work@example.com" + } + ], + "links": [ + { + "label": "blog", + "url": "https://blog.joe.me" + } + ], + "birthday": "1995-01-01", + "addresses": [ + { + "label": "company address", + "address": "https://company.of.joe.com" + } + ], + "social_medias": [ + { + "label": "twitter", + "username": "joe-twitter" + }, + { + "label": "facebook", + "username": "joe-facebook" + } + ], + "note": "this person is very important" + }, + "response": { + "contact": { + "id": "42e48a3c-6221-11ec-96d2-acde48001122", + "name": "joe", + "phones": [ + { + "label": "home", + "number": "010-12345678" + }, + { + "label": "work", + "number": "010-87654321" + } + ], + "emails": [ + { + "label": "home", + "address": "home@example.com" + }, + { + "label": "work", + "address": "work@example.com" + } + ], + "links": [ + { + "label": "blog", + "url": "https://blog.joe.me" + } + ], + "birthday": "1995-01-01", + "addresses": [ + { + "label": "company address", + "address": "https://company.of.joe.com" + } + ], + "social_medias": [ + { + "label": "twitter", + "username": "joe-twitter" + }, + { + "label": "facebook", + "username": "joe-facebook" + } + ], + "note": "this person is very important", + "created_at": "2021-12-21T17:28:15+08:00", + "updated_at": "2021-12-21T17:31:21+08:00" + } + } + } + ], + "update": [ + { + "title": "Update a contact", + "run_check": false, + "description": "Update a contact with post data", + "request": { + "id": "42e48a3c-6221-11ec-96d2-acde48001122", + "name": "joe", + "phones": [ + { + "label": "home", + "number": "010-12345678" + }, + { + "label": "work", + "number": "010-87654321" + } + ], + "emails": [ + { + "label": "home", + "address": "home@example.com" + }, + { + "label": "work", + "address": "work@example.com" + } + ], + "links": [ + { + "label": "blog", + "url": "https://blog.joe.me" + } + ], + "birthday": "1995-01-01", + "addresses": [ + { + "label": "company address", + "address": "https://company.of.joe.com" + } + ], + "social_medias": [ + { + "label": "twitter", + "username": "joe-twitter" + }, + { + "label": "facebook", + "username": "joe-facebook" + } + ], + "note": "this person is very important" + }, + "response": { + "contact": { + "id": "42e48a3c-6221-11ec-96d2-acde48001122", + "name": "joe", + "phones": [ + { + "label": "home", + "number": "010-12345678" + }, + { + "label": "work", + "number": "010-87654321" + } + ], + "emails": [ + { + "label": "home", + "address": "home@example.com" + }, + { + "label": "work", + "address": "work@example.com" + } + ], + "links": [ + { + "label": "blog", + "url": "https://blog.joe.me" + } + ], + "birthday": "1995-01-01", + "addresses": [ + { + "label": "company address", + "address": "https://company.of.joe.com" + } + ], + "social_medias": [ + { + "label": "twitter", + "username": "joe-twitter" + }, + { + "label": "facebook", + "username": "joe-facebook" + } + ], + "note": "this person is very important", + "created_at": "2021-12-21T17:28:15+08:00", + "updated_at": "2021-12-21T17:31:21+08:00" + } + } + } + ], + "read": [ + { + "title": "Get a contact", + "run_check": false, + "description": "Get a contact by id", + "request": { + "id": "42e48a3c-6221-11ec-96d2-acde48001122" + }, + "response": { + "contact": { + "id": "42e48a3c-6221-11ec-96d2-acde48001122", + "name": "joe", + "phones": [ + { + "label": "home", + "number": "010-12345678" + }, + { + "label": "work", + "number": "010-87654321" + } + ], + "emails": [ + { + "label": "home", + "address": "home@example.com" + }, + { + "label": "work", + "address": "work@example.com" + } + ], + "links": [ + { + "label": "blog", + "url": "https://blog.joe.me" + } + ], + "birthday": "1995-01-01", + "addresses": [ + { + "label": "company address", + "address": "https://company.of.joe.com" + } + ], + "social_medias": [ + { + "label": "twitter", + "username": "joe-twitter" + }, + { + "label": "facebook", + "username": "joe-facebook" + } + ], + "note": "this person is very important", + "created_at": "2021-12-21T17:28:15+08:00", + "updated_at": "2021-12-21T17:31:21+08:00" + } + } + } + ], + "delete": [ + { + "title": "Delete a contact", + "run_check": false, + "description": "Delete a contact by id", + "request": { + "id": "42e48a3c-6221-11ec-96d2-acde48001122" + }, + "response": { + } + } + ], + "list": [ + { + "title": "List contacts with default offset and limit, default limit is 20", + "run_check": false, + "description": "List contacts", + "request": { + }, + "response": { + "contacts": [ + { + "id": "7765a308-6222-11ec-96d2-acde48001122", + "name": "contact-1", + "phones": [ + { + "label": "home", + "number": "010-1234567" + } + ], + "emails": [], + "links": [], + "birthday": "", + "addresses": [], + "social_medias": [], + "note": "", + "created_at": "2021-12-21T17:28:15+08:00", + "updated_at": "2021-12-21T17:31:21+08:00" + }, + { + "id": "7a7c1806-6222-11ec-96d2-acde48001122", + "name": "contact-2", + "phones": [ + { + "label": "home", + "number": "010-1234567" + } + ], + "emails": [], + "links": [], + "birthday": "", + "addresses": [], + "social_medias": [], + "note": "", + "created_at": "2021-12-21T17:28:15+08:00", + "updated_at": "2021-12-21T17:31:21+08:00" + }, + { + "id": "7d4a8e28-6222-11ec-96d2-acde48001122", + "name": "contact-3", + "phones": [ + { + "label": "home", + "number": "010-1234567" + } + ], + "emails": [], + "links": [], + "birthday": "", + "addresses": [], + "social_medias": [], + "note": "", + "created_at": "2021-12-21T17:28:15+08:00", + "updated_at": "2021-12-21T17:31:21+08:00" + } + ] + } + }, + { + "title": "List contacts with specific offset and limit", + "run_check": false, + "description": "List contacts", + "request": { + "offset": 1, + "limit": 1 + }, + "response": { + "contacts": [ + { + "id": "7a7c1806-6222-11ec-96d2-acde48001122", + "name": "contact-2", + "phones": [ + { + "label": "home", + "number": "010-1234567" + } + ], + "emails": [], + "links": [], + "birthday": "", + "addresses": [], + "social_medias": [], + "note": "", + "created_at": "2021-12-21T17:28:15+08:00", + "updated_at": "2021-12-21T17:31:21+08:00" + } + ] + } + } + ] +} diff --git a/contact/generate.go b/contact/generate.go new file mode 100644 index 0000000..7d9db91 --- /dev/null +++ b/contact/generate.go @@ -0,0 +1,3 @@ +package main + +//go:generate make proto diff --git a/contact/handler/contact.go b/contact/handler/contact.go new file mode 100644 index 0000000..9827433 --- /dev/null +++ b/contact/handler/contact.go @@ -0,0 +1,127 @@ +package handler + +import ( + "context" + "strings" + + "github.com/google/uuid" + "github.com/micro/micro/v3/service/errors" + + "github.com/micro/services/contact/domain" + pb "github.com/micro/services/contact/proto" +) + +type contact struct { + contact domain.Contact +} + +func NewContact(c domain.Contact) *contact { + return &contact{ + contact: c, + } +} + +// Create a contact +func (c *contact) Create(ctx context.Context, req *pb.CreateRequest, rsp *pb.CreateResponse) error { + req.Name = strings.TrimSpace(req.Name) + if len(req.Name) == 0 { + return errors.BadRequest("contact.create", "contact name is required") + } + + uid, err := uuid.NewUUID() + if err != nil { + return errors.InternalServerError("contact.create", "generate contact id error: %v", err) + } + + info := &pb.ContactInfo{ + Id: uid.String(), + Name: req.Name, + Phones: req.Phones, + Emails: req.Emails, + Links: req.Links, + Birthday: req.Birthday, + Addresses: req.Addresses, + SocialMedias: req.SocialMedias, + Note: req.Note, + } + + if err := c.contact.Create(ctx, info); err != nil { + return errors.InternalServerError("contact.create", "create contact error: %v", err) + } + + rsp.Contact = info + + return nil +} + +// Update information of the contact submitted +func (c *contact) Update(ctx context.Context, req *pb.UpdateRequest, rsp *pb.UpdateResponse) error { + req.Name = strings.TrimSpace(req.Name) + if len(req.Name) == 0 { + return errors.BadRequest("contact.create", "contact name is required") + } + + old, err := c.contact.Read(ctx, req.Id) + if err != nil { + return errors.InternalServerError("contact.update", "get contact info error: %v", err) + } + + info := &pb.ContactInfo{ + Id: req.Id, + Name: req.Name, + Phones: req.Phones, + Emails: req.Emails, + Links: req.Links, + Birthday: req.Birthday, + Addresses: req.Addresses, + SocialMedias: req.SocialMedias, + Note: req.Note, + CreatedAt: old.CreatedAt, + } + + if err := c.contact.Update(ctx, req.Id, info); err != nil { + return errors.InternalServerError("contact.update", "update contact error: %v", err) + } + + rsp.Contact = info + + return nil +} + +// Read a contact by id +func (c *contact) Read(ctx context.Context, req *pb.ReadRequest, rsp *pb.ReadResponse) error { + info, err := c.contact.Read(ctx, req.Id) + if err != nil { + return errors.InternalServerError("contact.read", "get contact info error: %v", err) + } + + rsp.Contact = info + + return nil +} + +// Delete contact by id +func (c *contact) Delete(ctx context.Context, req *pb.DeleteRequest, _ *pb.DeleteResponse) error { + err := c.contact.Delete(ctx, req.Id) + if err != nil { + return errors.InternalServerError("contact.delete", "delete contact error: %v", err) + } + + return nil +} + +// List contacts with offset and limit +func (c *contact) List(ctx context.Context, req *pb.ListRequest, rsp *pb.ListResponse) error { + if req.Limit == 0 { + req.Limit = 30 + } + + list, err := c.contact.List(ctx, uint(req.Offset), uint(req.Limit)) + if err != nil { + return errors.InternalServerError("contact.list", "get contact info error: %v", err) + } + + rsp.Contacts = list + + return nil +} diff --git a/contact/main.go b/contact/main.go new file mode 100644 index 0000000..eb821b2 --- /dev/null +++ b/contact/main.go @@ -0,0 +1,30 @@ +package main + +import ( + "github.com/micro/micro/v3/service/store" + + "github.com/micro/services/contact/domain" + "github.com/micro/services/contact/handler" + pb "github.com/micro/services/contact/proto" + + "github.com/micro/micro/v3/service" + "github.com/micro/micro/v3/service/logger" +) + +func main() { + // Create service + srv := service.New( + service.Name("contact"), + service.Version("latest"), + ) + + contactDomain := domain.NewContactDomain(store.DefaultStore) + + // Register handler + pb.RegisterContactHandler(srv.Server(), handler.NewContact(contactDomain)) + + // Run service + if err := srv.Run(); err != nil { + logger.Fatal(err) + } +} diff --git a/contact/micro.mu b/contact/micro.mu new file mode 100644 index 0000000..6352287 --- /dev/null +++ b/contact/micro.mu @@ -0,0 +1 @@ +service contact diff --git a/contact/proto/contact.pb.go b/contact/proto/contact.pb.go new file mode 100644 index 0000000..45463d5 --- /dev/null +++ b/contact/proto/contact.pb.go @@ -0,0 +1,1475 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.19.1 +// source: proto/contact.proto + +package contact + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Phone struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the label of the phone number + Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"` + // phone number + Number string `protobuf:"bytes,2,opt,name=number,proto3" json:"number,omitempty"` +} + +func (x *Phone) Reset() { + *x = Phone{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_contact_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Phone) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Phone) ProtoMessage() {} + +func (x *Phone) ProtoReflect() protoreflect.Message { + mi := &file_proto_contact_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Phone.ProtoReflect.Descriptor instead. +func (*Phone) Descriptor() ([]byte, []int) { + return file_proto_contact_proto_rawDescGZIP(), []int{0} +} + +func (x *Phone) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *Phone) GetNumber() string { + if x != nil { + return x.Number + } + return "" +} + +type Email struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the label of the email + Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"` + // the email address + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` +} + +func (x *Email) Reset() { + *x = Email{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_contact_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Email) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Email) ProtoMessage() {} + +func (x *Email) ProtoReflect() protoreflect.Message { + mi := &file_proto_contact_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Email.ProtoReflect.Descriptor instead. +func (*Email) Descriptor() ([]byte, []int) { + return file_proto_contact_proto_rawDescGZIP(), []int{1} +} + +func (x *Email) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *Email) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +type Link struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the label of the link + Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"` + // the url of the contact + Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` +} + +func (x *Link) Reset() { + *x = Link{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_contact_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Link) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Link) ProtoMessage() {} + +func (x *Link) ProtoReflect() protoreflect.Message { + mi := &file_proto_contact_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Link.ProtoReflect.Descriptor instead. +func (*Link) Descriptor() ([]byte, []int) { + return file_proto_contact_proto_rawDescGZIP(), []int{2} +} + +func (x *Link) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *Link) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +type Address struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the label of the address + Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"` + // the address + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` +} + +func (x *Address) Reset() { + *x = Address{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_contact_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Address) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Address) ProtoMessage() {} + +func (x *Address) ProtoReflect() protoreflect.Message { + mi := &file_proto_contact_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Address.ProtoReflect.Descriptor instead. +func (*Address) Descriptor() ([]byte, []int) { + return file_proto_contact_proto_rawDescGZIP(), []int{3} +} + +func (x *Address) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *Address) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +type SocialMedia struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the label of the social + Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"` + // the username of social media + Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"` +} + +func (x *SocialMedia) Reset() { + *x = SocialMedia{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_contact_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SocialMedia) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SocialMedia) ProtoMessage() {} + +func (x *SocialMedia) ProtoReflect() protoreflect.Message { + mi := &file_proto_contact_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SocialMedia.ProtoReflect.Descriptor instead. +func (*SocialMedia) Descriptor() ([]byte, []int) { + return file_proto_contact_proto_rawDescGZIP(), []int{4} +} + +func (x *SocialMedia) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *SocialMedia) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +type ContactInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // contact id + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // the contact name + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // the phone numbers + Phones []*Phone `protobuf:"bytes,3,rep,name=phones,proto3" json:"phones,omitempty"` + // the emails + Emails []*Email `protobuf:"bytes,4,rep,name=emails,proto3" json:"emails,omitempty"` + // the contact links + Links []*Link `protobuf:"bytes,5,rep,name=links,proto3" json:"links,omitempty"` + // the birthday + Birthday string `protobuf:"bytes,6,opt,name=birthday,proto3" json:"birthday,omitempty"` + // the address + Addresses []*Address `protobuf:"bytes,7,rep,name=addresses,proto3" json:"addresses,omitempty"` + // the social media username + SocialMedias []*SocialMedia `protobuf:"bytes,8,rep,name=social_medias,json=socialMedias,proto3" json:"social_medias,omitempty"` + // note of the contact + Note string `protobuf:"bytes,9,opt,name=note,proto3" json:"note,omitempty"` + // create date string in RFC3339 + CreatedAt string `protobuf:"bytes,10,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + // update date string in RFC3339 + UpdatedAt string `protobuf:"bytes,11,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` +} + +func (x *ContactInfo) Reset() { + *x = ContactInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_contact_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ContactInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContactInfo) ProtoMessage() {} + +func (x *ContactInfo) ProtoReflect() protoreflect.Message { + mi := &file_proto_contact_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContactInfo.ProtoReflect.Descriptor instead. +func (*ContactInfo) Descriptor() ([]byte, []int) { + return file_proto_contact_proto_rawDescGZIP(), []int{5} +} + +func (x *ContactInfo) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ContactInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ContactInfo) GetPhones() []*Phone { + if x != nil { + return x.Phones + } + return nil +} + +func (x *ContactInfo) GetEmails() []*Email { + if x != nil { + return x.Emails + } + return nil +} + +func (x *ContactInfo) GetLinks() []*Link { + if x != nil { + return x.Links + } + return nil +} + +func (x *ContactInfo) GetBirthday() string { + if x != nil { + return x.Birthday + } + return "" +} + +func (x *ContactInfo) GetAddresses() []*Address { + if x != nil { + return x.Addresses + } + return nil +} + +func (x *ContactInfo) GetSocialMedias() []*SocialMedia { + if x != nil { + return x.SocialMedias + } + return nil +} + +func (x *ContactInfo) GetNote() string { + if x != nil { + return x.Note + } + return "" +} + +func (x *ContactInfo) GetCreatedAt() string { + if x != nil { + return x.CreatedAt + } + return "" +} + +func (x *ContactInfo) GetUpdatedAt() string { + if x != nil { + return x.UpdatedAt + } + return "" +} + +type CreateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // required, the name of the contact + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // optional, phone numbers + Phones []*Phone `protobuf:"bytes,2,rep,name=phones,proto3" json:"phones,omitempty"` + // optional, emails + Emails []*Email `protobuf:"bytes,3,rep,name=emails,proto3" json:"emails,omitempty"` + // optional, links + Links []*Link `protobuf:"bytes,4,rep,name=links,proto3" json:"links,omitempty"` + // optional, birthday + Birthday string `protobuf:"bytes,5,opt,name=birthday,proto3" json:"birthday,omitempty"` + // optional, address + Addresses []*Address `protobuf:"bytes,6,rep,name=addresses,proto3" json:"addresses,omitempty"` + // optional, social media + SocialMedias []*SocialMedia `protobuf:"bytes,7,rep,name=social_medias,json=socialMedias,proto3" json:"social_medias,omitempty"` + // optional, note of the contact + Note string `protobuf:"bytes,8,opt,name=note,proto3" json:"note,omitempty"` +} + +func (x *CreateRequest) Reset() { + *x = CreateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_contact_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateRequest) ProtoMessage() {} + +func (x *CreateRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_contact_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateRequest.ProtoReflect.Descriptor instead. +func (*CreateRequest) Descriptor() ([]byte, []int) { + return file_proto_contact_proto_rawDescGZIP(), []int{6} +} + +func (x *CreateRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateRequest) GetPhones() []*Phone { + if x != nil { + return x.Phones + } + return nil +} + +func (x *CreateRequest) GetEmails() []*Email { + if x != nil { + return x.Emails + } + return nil +} + +func (x *CreateRequest) GetLinks() []*Link { + if x != nil { + return x.Links + } + return nil +} + +func (x *CreateRequest) GetBirthday() string { + if x != nil { + return x.Birthday + } + return "" +} + +func (x *CreateRequest) GetAddresses() []*Address { + if x != nil { + return x.Addresses + } + return nil +} + +func (x *CreateRequest) GetSocialMedias() []*SocialMedia { + if x != nil { + return x.SocialMedias + } + return nil +} + +func (x *CreateRequest) GetNote() string { + if x != nil { + return x.Note + } + return "" +} + +type CreateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Contact *ContactInfo `protobuf:"bytes,1,opt,name=contact,proto3" json:"contact,omitempty"` +} + +func (x *CreateResponse) Reset() { + *x = CreateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_contact_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateResponse) ProtoMessage() {} + +func (x *CreateResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_contact_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateResponse.ProtoReflect.Descriptor instead. +func (*CreateResponse) Descriptor() ([]byte, []int) { + return file_proto_contact_proto_rawDescGZIP(), []int{7} +} + +func (x *CreateResponse) GetContact() *ContactInfo { + if x != nil { + return x.Contact + } + return nil +} + +type ReadRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *ReadRequest) Reset() { + *x = ReadRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_contact_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadRequest) ProtoMessage() {} + +func (x *ReadRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_contact_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReadRequest.ProtoReflect.Descriptor instead. +func (*ReadRequest) Descriptor() ([]byte, []int) { + return file_proto_contact_proto_rawDescGZIP(), []int{8} +} + +func (x *ReadRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type ReadResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Contact *ContactInfo `protobuf:"bytes,1,opt,name=contact,proto3" json:"contact,omitempty"` +} + +func (x *ReadResponse) Reset() { + *x = ReadResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_contact_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadResponse) ProtoMessage() {} + +func (x *ReadResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_contact_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReadResponse.ProtoReflect.Descriptor instead. +func (*ReadResponse) Descriptor() ([]byte, []int) { + return file_proto_contact_proto_rawDescGZIP(), []int{9} +} + +func (x *ReadResponse) GetContact() *ContactInfo { + if x != nil { + return x.Contact + } + return nil +} + +type DeleteRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the id of the contact + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *DeleteRequest) Reset() { + *x = DeleteRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_contact_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteRequest) ProtoMessage() {} + +func (x *DeleteRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_contact_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteRequest.ProtoReflect.Descriptor instead. +func (*DeleteRequest) Descriptor() ([]byte, []int) { + return file_proto_contact_proto_rawDescGZIP(), []int{10} +} + +func (x *DeleteRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type DeleteResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteResponse) Reset() { + *x = DeleteResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_contact_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteResponse) ProtoMessage() {} + +func (x *DeleteResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_contact_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteResponse.ProtoReflect.Descriptor instead. +func (*DeleteResponse) Descriptor() ([]byte, []int) { + return file_proto_contact_proto_rawDescGZIP(), []int{11} +} + +type UpdateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // required, the contact id + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // required, the name + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // optional, phone number + Phones []*Phone `protobuf:"bytes,3,rep,name=phones,proto3" json:"phones,omitempty"` + // optional, emails + Emails []*Email `protobuf:"bytes,4,rep,name=emails,proto3" json:"emails,omitempty"` + // optional, links + Links []*Link `protobuf:"bytes,5,rep,name=links,proto3" json:"links,omitempty"` + // optional, birthday + Birthday string `protobuf:"bytes,6,opt,name=birthday,proto3" json:"birthday,omitempty"` + // optional, addresses + Addresses []*Address `protobuf:"bytes,7,rep,name=addresses,proto3" json:"addresses,omitempty"` + // optional, social media + SocialMedias []*SocialMedia `protobuf:"bytes,8,rep,name=social_medias,json=socialMedias,proto3" json:"social_medias,omitempty"` + // optional, note + Note string `protobuf:"bytes,9,opt,name=note,proto3" json:"note,omitempty"` +} + +func (x *UpdateRequest) Reset() { + *x = UpdateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_contact_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateRequest) ProtoMessage() {} + +func (x *UpdateRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_contact_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateRequest.ProtoReflect.Descriptor instead. +func (*UpdateRequest) Descriptor() ([]byte, []int) { + return file_proto_contact_proto_rawDescGZIP(), []int{12} +} + +func (x *UpdateRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UpdateRequest) GetPhones() []*Phone { + if x != nil { + return x.Phones + } + return nil +} + +func (x *UpdateRequest) GetEmails() []*Email { + if x != nil { + return x.Emails + } + return nil +} + +func (x *UpdateRequest) GetLinks() []*Link { + if x != nil { + return x.Links + } + return nil +} + +func (x *UpdateRequest) GetBirthday() string { + if x != nil { + return x.Birthday + } + return "" +} + +func (x *UpdateRequest) GetAddresses() []*Address { + if x != nil { + return x.Addresses + } + return nil +} + +func (x *UpdateRequest) GetSocialMedias() []*SocialMedia { + if x != nil { + return x.SocialMedias + } + return nil +} + +func (x *UpdateRequest) GetNote() string { + if x != nil { + return x.Note + } + return "" +} + +type UpdateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Contact *ContactInfo `protobuf:"bytes,1,opt,name=contact,proto3" json:"contact,omitempty"` +} + +func (x *UpdateResponse) Reset() { + *x = UpdateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_contact_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateResponse) ProtoMessage() {} + +func (x *UpdateResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_contact_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateResponse.ProtoReflect.Descriptor instead. +func (*UpdateResponse) Descriptor() ([]byte, []int) { + return file_proto_contact_proto_rawDescGZIP(), []int{13} +} + +func (x *UpdateResponse) GetContact() *ContactInfo { + if x != nil { + return x.Contact + } + return nil +} + +type ListRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // optional + Offset uint32 `protobuf:"varint,1,opt,name=offset,proto3" json:"offset,omitempty"` + // optional, default is 30 + Limit uint32 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` +} + +func (x *ListRequest) Reset() { + *x = ListRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_contact_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListRequest) ProtoMessage() {} + +func (x *ListRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_contact_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListRequest.ProtoReflect.Descriptor instead. +func (*ListRequest) Descriptor() ([]byte, []int) { + return file_proto_contact_proto_rawDescGZIP(), []int{14} +} + +func (x *ListRequest) GetOffset() uint32 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *ListRequest) GetLimit() uint32 { + if x != nil { + return x.Limit + } + return 0 +} + +type ListResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Contacts []*ContactInfo `protobuf:"bytes,1,rep,name=contacts,proto3" json:"contacts,omitempty"` +} + +func (x *ListResponse) Reset() { + *x = ListResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_contact_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListResponse) ProtoMessage() {} + +func (x *ListResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_contact_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListResponse.ProtoReflect.Descriptor instead. +func (*ListResponse) Descriptor() ([]byte, []int) { + return file_proto_contact_proto_rawDescGZIP(), []int{15} +} + +func (x *ListResponse) GetContacts() []*ContactInfo { + if x != nil { + return x.Contacts + } + return nil +} + +var File_proto_contact_proto protoreflect.FileDescriptor + +var file_proto_contact_proto_rawDesc = []byte{ + 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x22, 0x35, + 0x0a, 0x05, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x16, 0x0a, + 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x37, 0x0a, 0x05, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x14, + 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x2e, + 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x10, 0x0a, 0x03, + 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x39, + 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, + 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x3f, 0x0a, 0x0b, 0x53, 0x6f, 0x63, + 0x69, 0x61, 0x6c, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x1a, + 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xff, 0x02, 0x0a, 0x0b, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x26, + 0x0a, 0x06, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x52, 0x06, + 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x06, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, + 0x2e, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x06, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x23, + 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x05, 0x6c, 0x69, + 0x6e, 0x6b, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x12, + 0x2e, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, + 0x39, 0x0a, 0x0d, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x5f, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x73, + 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, + 0x2e, 0x53, 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x52, 0x0c, 0x73, 0x6f, + 0x63, 0x69, 0x61, 0x6c, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, + 0x74, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x12, 0x1d, + 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, + 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0xb3, 0x02, 0x0a, + 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x50, 0x68, 0x6f, + 0x6e, 0x65, 0x52, 0x06, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x06, 0x65, 0x6d, + 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x63, 0x74, 0x2e, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x06, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x73, 0x12, 0x23, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, + 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x69, 0x72, 0x74, 0x68, + 0x64, 0x61, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x69, 0x72, 0x74, 0x68, + 0x64, 0x61, 0x79, 0x12, 0x2e, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, + 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x0d, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x5f, 0x6d, 0x65, + 0x64, 0x69, 0x61, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x63, 0x74, 0x2e, 0x53, 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x4d, 0x65, 0x64, 0x69, 0x61, + 0x52, 0x0c, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x73, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, + 0x74, 0x65, 0x22, 0x40, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x63, 0x74, 0x22, 0x1d, 0x0a, 0x0b, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x02, 0x69, 0x64, 0x22, 0x3e, 0x0a, 0x0c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x63, 0x74, 0x22, 0x1f, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x22, 0x10, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc3, 0x02, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x06, + 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x52, 0x06, 0x70, 0x68, + 0x6f, 0x6e, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x06, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x45, + 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x06, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x23, 0x0a, 0x05, + 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b, + 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x12, 0x2e, 0x0a, + 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x10, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x39, 0x0a, + 0x0d, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x5f, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x73, 0x18, 0x08, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x53, + 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x52, 0x0c, 0x73, 0x6f, 0x63, 0x69, + 0x61, 0x6c, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x22, 0x40, 0x0a, 0x0e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, + 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x22, 0x3b, + 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, + 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x40, 0x0a, 0x0c, 0x4c, + 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x08, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x32, 0xae, 0x02, + 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x3b, 0x0a, 0x06, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, 0x12, 0x14, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x52, + 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3b, 0x0a, + 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, + 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x17, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x06, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, + 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x11, + 0x5a, 0x0f, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, + 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_proto_contact_proto_rawDescOnce sync.Once + file_proto_contact_proto_rawDescData = file_proto_contact_proto_rawDesc +) + +func file_proto_contact_proto_rawDescGZIP() []byte { + file_proto_contact_proto_rawDescOnce.Do(func() { + file_proto_contact_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_contact_proto_rawDescData) + }) + return file_proto_contact_proto_rawDescData +} + +var file_proto_contact_proto_msgTypes = make([]protoimpl.MessageInfo, 16) +var file_proto_contact_proto_goTypes = []interface{}{ + (*Phone)(nil), // 0: contact.Phone + (*Email)(nil), // 1: contact.Email + (*Link)(nil), // 2: contact.Link + (*Address)(nil), // 3: contact.Address + (*SocialMedia)(nil), // 4: contact.SocialMedia + (*ContactInfo)(nil), // 5: contact.ContactInfo + (*CreateRequest)(nil), // 6: contact.CreateRequest + (*CreateResponse)(nil), // 7: contact.CreateResponse + (*ReadRequest)(nil), // 8: contact.ReadRequest + (*ReadResponse)(nil), // 9: contact.ReadResponse + (*DeleteRequest)(nil), // 10: contact.DeleteRequest + (*DeleteResponse)(nil), // 11: contact.DeleteResponse + (*UpdateRequest)(nil), // 12: contact.UpdateRequest + (*UpdateResponse)(nil), // 13: contact.UpdateResponse + (*ListRequest)(nil), // 14: contact.ListRequest + (*ListResponse)(nil), // 15: contact.ListResponse +} +var file_proto_contact_proto_depIdxs = []int32{ + 0, // 0: contact.ContactInfo.phones:type_name -> contact.Phone + 1, // 1: contact.ContactInfo.emails:type_name -> contact.Email + 2, // 2: contact.ContactInfo.links:type_name -> contact.Link + 3, // 3: contact.ContactInfo.addresses:type_name -> contact.Address + 4, // 4: contact.ContactInfo.social_medias:type_name -> contact.SocialMedia + 0, // 5: contact.CreateRequest.phones:type_name -> contact.Phone + 1, // 6: contact.CreateRequest.emails:type_name -> contact.Email + 2, // 7: contact.CreateRequest.links:type_name -> contact.Link + 3, // 8: contact.CreateRequest.addresses:type_name -> contact.Address + 4, // 9: contact.CreateRequest.social_medias:type_name -> contact.SocialMedia + 5, // 10: contact.CreateResponse.contact:type_name -> contact.ContactInfo + 5, // 11: contact.ReadResponse.contact:type_name -> contact.ContactInfo + 0, // 12: contact.UpdateRequest.phones:type_name -> contact.Phone + 1, // 13: contact.UpdateRequest.emails:type_name -> contact.Email + 2, // 14: contact.UpdateRequest.links:type_name -> contact.Link + 3, // 15: contact.UpdateRequest.addresses:type_name -> contact.Address + 4, // 16: contact.UpdateRequest.social_medias:type_name -> contact.SocialMedia + 5, // 17: contact.UpdateResponse.contact:type_name -> contact.ContactInfo + 5, // 18: contact.ListResponse.contacts:type_name -> contact.ContactInfo + 6, // 19: contact.Contact.Create:input_type -> contact.CreateRequest + 8, // 20: contact.Contact.Read:input_type -> contact.ReadRequest + 12, // 21: contact.Contact.Update:input_type -> contact.UpdateRequest + 10, // 22: contact.Contact.Delete:input_type -> contact.DeleteRequest + 14, // 23: contact.Contact.List:input_type -> contact.ListRequest + 7, // 24: contact.Contact.Create:output_type -> contact.CreateResponse + 9, // 25: contact.Contact.Read:output_type -> contact.ReadResponse + 13, // 26: contact.Contact.Update:output_type -> contact.UpdateResponse + 11, // 27: contact.Contact.Delete:output_type -> contact.DeleteResponse + 15, // 28: contact.Contact.List:output_type -> contact.ListResponse + 24, // [24:29] is the sub-list for method output_type + 19, // [19:24] is the sub-list for method input_type + 19, // [19:19] is the sub-list for extension type_name + 19, // [19:19] is the sub-list for extension extendee + 0, // [0:19] is the sub-list for field type_name +} + +func init() { file_proto_contact_proto_init() } +func file_proto_contact_proto_init() { + if File_proto_contact_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_proto_contact_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Phone); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_contact_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Email); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_contact_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Link); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_contact_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Address); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_contact_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SocialMedia); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_contact_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ContactInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_contact_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_contact_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_contact_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_contact_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_contact_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_contact_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_contact_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_contact_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_contact_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_contact_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_contact_proto_rawDesc, + NumEnums: 0, + NumMessages: 16, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_proto_contact_proto_goTypes, + DependencyIndexes: file_proto_contact_proto_depIdxs, + MessageInfos: file_proto_contact_proto_msgTypes, + }.Build() + File_proto_contact_proto = out.File + file_proto_contact_proto_rawDesc = nil + file_proto_contact_proto_goTypes = nil + file_proto_contact_proto_depIdxs = nil +} diff --git a/contact/proto/contact.pb.micro.go b/contact/proto/contact.pb.micro.go new file mode 100644 index 0000000..0ce032c --- /dev/null +++ b/contact/proto/contact.pb.micro.go @@ -0,0 +1,161 @@ +// Code generated by protoc-gen-micro. DO NOT EDIT. +// source: proto/contact.proto + +package contact + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +import ( + context "context" + api "github.com/micro/micro/v3/service/api" + client "github.com/micro/micro/v3/service/client" + server "github.com/micro/micro/v3/service/server" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// Reference imports to suppress errors if they are not otherwise used. +var _ api.Endpoint +var _ context.Context +var _ client.Option +var _ server.Option + +// Api Endpoints for Contact service + +func NewContactEndpoints() []*api.Endpoint { + return []*api.Endpoint{} +} + +// Client API for Contact service + +type ContactService interface { + Create(ctx context.Context, in *CreateRequest, opts ...client.CallOption) (*CreateResponse, error) + Read(ctx context.Context, in *ReadRequest, opts ...client.CallOption) (*ReadResponse, error) + Update(ctx context.Context, in *UpdateRequest, opts ...client.CallOption) (*UpdateResponse, error) + Delete(ctx context.Context, in *DeleteRequest, opts ...client.CallOption) (*DeleteResponse, error) + List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) +} + +type contactService struct { + c client.Client + name string +} + +func NewContactService(name string, c client.Client) ContactService { + return &contactService{ + c: c, + name: name, + } +} + +func (c *contactService) Create(ctx context.Context, in *CreateRequest, opts ...client.CallOption) (*CreateResponse, error) { + req := c.c.NewRequest(c.name, "Contact.Create", in) + out := new(CreateResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *contactService) Read(ctx context.Context, in *ReadRequest, opts ...client.CallOption) (*ReadResponse, error) { + req := c.c.NewRequest(c.name, "Contact.Read", in) + out := new(ReadResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *contactService) Update(ctx context.Context, in *UpdateRequest, opts ...client.CallOption) (*UpdateResponse, error) { + req := c.c.NewRequest(c.name, "Contact.Update", in) + out := new(UpdateResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *contactService) Delete(ctx context.Context, in *DeleteRequest, opts ...client.CallOption) (*DeleteResponse, error) { + req := c.c.NewRequest(c.name, "Contact.Delete", in) + out := new(DeleteResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *contactService) List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) { + req := c.c.NewRequest(c.name, "Contact.List", in) + out := new(ListResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for Contact service + +type ContactHandler interface { + Create(context.Context, *CreateRequest, *CreateResponse) error + Read(context.Context, *ReadRequest, *ReadResponse) error + Update(context.Context, *UpdateRequest, *UpdateResponse) error + Delete(context.Context, *DeleteRequest, *DeleteResponse) error + List(context.Context, *ListRequest, *ListResponse) error +} + +func RegisterContactHandler(s server.Server, hdlr ContactHandler, opts ...server.HandlerOption) error { + type contact interface { + Create(ctx context.Context, in *CreateRequest, out *CreateResponse) error + Read(ctx context.Context, in *ReadRequest, out *ReadResponse) error + Update(ctx context.Context, in *UpdateRequest, out *UpdateResponse) error + Delete(ctx context.Context, in *DeleteRequest, out *DeleteResponse) error + List(ctx context.Context, in *ListRequest, out *ListResponse) error + } + type Contact struct { + contact + } + h := &contactHandler{hdlr} + return s.Handle(s.NewHandler(&Contact{h}, opts...)) +} + +type contactHandler struct { + ContactHandler +} + +func (h *contactHandler) Create(ctx context.Context, in *CreateRequest, out *CreateResponse) error { + return h.ContactHandler.Create(ctx, in, out) +} + +func (h *contactHandler) Read(ctx context.Context, in *ReadRequest, out *ReadResponse) error { + return h.ContactHandler.Read(ctx, in, out) +} + +func (h *contactHandler) Update(ctx context.Context, in *UpdateRequest, out *UpdateResponse) error { + return h.ContactHandler.Update(ctx, in, out) +} + +func (h *contactHandler) Delete(ctx context.Context, in *DeleteRequest, out *DeleteResponse) error { + return h.ContactHandler.Delete(ctx, in, out) +} + +func (h *contactHandler) List(ctx context.Context, in *ListRequest, out *ListResponse) error { + return h.ContactHandler.List(ctx, in, out) +} diff --git a/contact/proto/contact.proto b/contact/proto/contact.proto new file mode 100644 index 0000000..7a7cd5e --- /dev/null +++ b/contact/proto/contact.proto @@ -0,0 +1,151 @@ +syntax = "proto3"; + +package contact; + +option go_package = "./proto;contact"; + +service Contact { + rpc Create(CreateRequest) returns (CreateResponse) {} + rpc Read(ReadRequest) returns (ReadResponse) {} + rpc Update(UpdateRequest) returns (UpdateResponse) {} + rpc Delete(DeleteRequest) returns (DeleteResponse) {} + rpc List(ListRequest) returns (ListResponse) {} + // TODO: wait for the search API + // rpc Search(Request) returns (Response) {} +} + +message Phone { + // the label of the phone number + string label = 1; + // phone number + string number = 2; +} + +message Email { + // the label of the email + string label = 1; + // the email address + string address = 2; +} + +message Link { + // the label of the link + string label = 1; + // the url of the contact + string url = 2; +} + +message Address { + // the label of the address + string label = 1; + // the address + string address = 2; +} + +message SocialMedia { + // the label of the social + string label = 1; + // the username of social media + string username = 2; +} + +message ContactInfo { + // contact id + string id = 1; + // the contact name + string name = 2; + // the phone numbers + repeated Phone phones = 3; + // the emails + repeated Email emails = 4; + // the contact links + repeated Link links = 5; + // the birthday + string birthday = 6; + // the address + repeated Address addresses = 7; + // the social media username + repeated SocialMedia social_medias = 8; + // note of the contact + string note = 9; + // create date string in RFC3339 + string created_at = 10; + // update date string in RFC3339 + string updated_at = 11; +} + +message CreateRequest { + // required, the name of the contact + string name = 1; + // optional, phone numbers + repeated Phone phones = 2; + // optional, emails + repeated Email emails = 3; + // optional, links + repeated Link links = 4; + // optional, birthday + string birthday = 5; + // optional, address + repeated Address addresses = 6; + // optional, social media + repeated SocialMedia social_medias = 7; + // optional, note of the contact + string note = 8; +} + +message CreateResponse { + ContactInfo contact = 1; +} + +message ReadRequest { + string id = 1; +} + +message ReadResponse { + ContactInfo contact = 1; +} + +message DeleteRequest { + // the id of the contact + string id = 1; +} + +message DeleteResponse { +} + + +message UpdateRequest { + // required, the contact id + string id = 1; + // required, the name + string name = 2; + // optional, phone number + repeated Phone phones = 3; + // optional, emails + repeated Email emails = 4; + // optional, links + repeated Link links = 5; + // optional, birthday + string birthday = 6; + // optional, addresses + repeated Address addresses = 7; + // optional, social media + repeated SocialMedia social_medias = 8; + // optional, note + string note = 9; +} + +message UpdateResponse { + ContactInfo contact = 1; +} + +message ListRequest { + // optional + uint32 offset = 1; + // optional, default is 30 + uint32 limit = 2; +} + +message ListResponse { + repeated ContactInfo contacts = 1; +} \ No newline at end of file diff --git a/contact/publicapi.json b/contact/publicapi.json new file mode 100644 index 0000000..9e0f464 --- /dev/null +++ b/contact/publicapi.json @@ -0,0 +1,6 @@ +{ + "name": "contact", + "icon": "👥", + "category": "communication", + "display_name": "Contacts" +} diff --git a/go.mod b/go.mod index 6f9e1f9..99bda14 100644 --- a/go.mod +++ b/go.mod @@ -64,7 +64,6 @@ require ( googlemaps.github.io/maps v1.3.1 gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df - gopkg.in/yaml.v2 v2.3.0 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect gorm.io/datatypes v1.0.1 gorm.io/driver/postgres v1.0.8 diff --git a/go.sum b/go.sum index 0aba582..1cdcf66 100644 --- a/go.sum +++ b/go.sum @@ -493,8 +493,6 @@ github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KK github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/micro/micro/v3 v3.8.0 h1:RTH2835RJ4/aqLZGMjGCIf7HroCmYlJh2KRHHuSL/AE= -github.com/micro/micro/v3 v3.8.0/go.mod h1:gjFa8T2ouD6BvorPTVPXLWtrRJwSKT5KxUNuu23Kkts= github.com/micro/micro/v3 v3.8.1-0.20211216122745-2e7245423520 h1:LtErHRofRQf5damrjb5AkpvmklaIhx3anLJ9sN4fMrI= github.com/micro/micro/v3 v3.8.1-0.20211216122745-2e7245423520/go.mod h1:gjFa8T2ouD6BvorPTVPXLWtrRJwSKT5KxUNuu23Kkts= github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=