feat: items page

This commit is contained in:
2025-03-14 14:14:35 -04:00
parent f58b3cc18d
commit 50c8d18df9
17 changed files with 2384 additions and 54 deletions

View File

@ -6,7 +6,7 @@ import (
)
func Migrate(db *gorm.DB) error {
err := db.AutoMigrate(&models.User{})
err := db.AutoMigrate(&models.User{}, &models.Item{})
if err != nil {
return err
}

View File

@ -0,0 +1,171 @@
package handlers
import (
"context"
"errors"
"fmt"
"net/http"
"time"
"connectrpc.com/connect"
"github.com/spotdemo4/trevstack/server/internal/interceptors"
"github.com/spotdemo4/trevstack/server/internal/models"
itemv1 "github.com/spotdemo4/trevstack/server/internal/services/item/v1"
"github.com/spotdemo4/trevstack/server/internal/services/item/v1/itemv1connect"
"gorm.io/gorm"
)
type ItemHandler struct {
db *gorm.DB
key []byte
}
func (h *ItemHandler) GetItem(ctx context.Context, req *connect.Request[itemv1.GetItemRequest]) (*connect.Response[itemv1.GetItemResponse], error) {
userid, ok := interceptors.UserFromContext(ctx)
if !ok {
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("unauthenticated"))
}
// Get item
item := models.Item{}
if err := h.db.First(&item, "id = ? AND user_id = ?", req.Msg.Id, userid).Error; err != nil {
return nil, connect.NewError(connect.CodeNotFound, err)
}
res := connect.NewResponse(&itemv1.GetItemResponse{
Item: item.ToConnectV1(),
})
return res, nil
}
func (h *ItemHandler) GetItems(ctx context.Context, req *connect.Request[itemv1.GetItemsRequest]) (*connect.Response[itemv1.GetItemsResponse], error) {
userid, ok := interceptors.UserFromContext(ctx)
if !ok {
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("unauthenticated"))
}
// Filters
sql := h.db.Where("user_id = ?", userid)
if req.Msg.Start != nil {
sql = sql.Where("added >= ?", req.Msg.Start.AsTime())
}
if req.Msg.End != nil {
sql = sql.Where("added <= ?", req.Msg.End.AsTime())
}
if req.Msg.Filter != nil {
sql = sql.Where("name LIKE ?", fmt.Sprintf("%%%s%%", *req.Msg.Filter))
}
// Uncounted filters
sqlu := sql.Session(&gorm.Session{})
if req.Msg.Limit != nil {
sqlu = sqlu.Limit(int(*req.Msg.Limit))
}
if req.Msg.Offset != nil {
sqlu = sqlu.Offset(int(*req.Msg.Offset))
}
// Get items & count
items := []models.Item{}
var count int64
if err := sqlu.Order("added desc").Find(&items).Error; err != nil {
return nil, connect.NewError(connect.CodeNotFound, err)
}
if err := sql.Model(&items).Count(&count).Error; err != nil {
return nil, connect.NewError(connect.CodeInternal, err)
}
// Convert to connect v1 items
resItems := []*itemv1.Item{}
for _, item := range items {
resItems = append(resItems, item.ToConnectV1())
}
res := connect.NewResponse(&itemv1.GetItemsResponse{
Items: resItems,
Count: uint64(count),
})
return res, nil
}
func (h *ItemHandler) CreateItem(ctx context.Context, req *connect.Request[itemv1.CreateItemRequest]) (*connect.Response[itemv1.CreateItemResponse], error) {
userid, ok := interceptors.UserFromContext(ctx)
if !ok {
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("unauthenticated"))
}
// Create item
item := models.Item{
Name: req.Msg.Item.Name,
Description: req.Msg.Item.Description,
Price: req.Msg.Item.Price,
Quantity: int(req.Msg.Item.Quantity),
Added: time.Now(),
UserID: uint(userid),
}
if err := h.db.Create(&item).Error; err != nil {
return nil, connect.NewError(connect.CodeInternal, err)
}
res := connect.NewResponse(&itemv1.CreateItemResponse{
Item: item.ToConnectV1(),
})
return res, nil
}
func (h *ItemHandler) UpdateItem(ctx context.Context, req *connect.Request[itemv1.UpdateItemRequest]) (*connect.Response[itemv1.UpdateItemResponse], error) {
userid, ok := interceptors.UserFromContext(ctx)
if !ok {
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("unauthenticated"))
}
// Validate
if req.Msg.Item.Id == nil {
return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("id is required"))
}
// Update item
item := models.Item{
ID: *req.Msg.Item.Id,
Name: req.Msg.Item.Name,
Description: req.Msg.Item.Description,
Price: req.Msg.Item.Price,
Quantity: int(req.Msg.Item.Quantity),
UserID: uint(userid),
}
if err := h.db.Where("id = ? AND user_id = ?", req.Msg.Item.Id, userid).Updates(&item).Error; err != nil {
return nil, connect.NewError(connect.CodeInternal, err)
}
res := connect.NewResponse(&itemv1.UpdateItemResponse{
Item: item.ToConnectV1(),
})
return res, nil
}
func (h *ItemHandler) DeleteItem(ctx context.Context, req *connect.Request[itemv1.DeleteItemRequest]) (*connect.Response[itemv1.DeleteItemResponse], error) {
userid, ok := interceptors.UserFromContext(ctx)
if !ok {
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("unauthenticated"))
}
// Delete item
if err := h.db.Delete(&models.Item{}, "id = ? AND user_id = ?", req.Msg.Id, userid).Error; err != nil {
return nil, connect.NewError(connect.CodeInternal, err)
}
res := connect.NewResponse(&itemv1.DeleteItemResponse{})
return res, nil
}
func NewItemHandler(db *gorm.DB, key string) (string, http.Handler) {
interceptors := connect.WithInterceptors(interceptors.NewAuthInterceptor(key))
return itemv1connect.NewItemServiceHandler(
&ItemHandler{
db: db,
key: []byte(key),
},
interceptors,
)
}

View File

@ -24,11 +24,12 @@ func WithAuthRedirect(next http.Handler, key string) http.Handler {
}
switch pathItems[1] {
case "auth":
next.ServeHTTP(w, r)
return
case "auth":
fallthrough
case "_app":
fallthrough
case "favicon.png":
next.ServeHTTP(w, r)
return

View File

@ -2,7 +2,7 @@ package interceptors
import (
"context"
"log"
"errors"
"sync"
"time"
@ -44,8 +44,11 @@ func (i *ratelimitInterceptor) WrapUnary(next connect.UnaryFunc) connect.UnaryFu
return next(ctx, req)
}
// Get ip
log.Println(req.Peer().Addr)
// Get user agent
limiter := i.getVisitor(req.Header().Get("User-Agent"))
if limiter.Allow() == false {
return nil, connect.NewError(connect.CodeResourceExhausted, errors.New("rate limit exceeded"))
}
return next(ctx, req)
})
@ -65,22 +68,25 @@ func (i *ratelimitInterceptor) WrapStreamingHandler(next connect.StreamingHandle
ctx context.Context,
conn connect.StreamingHandlerConn,
) error {
// Get ip
log.Println(conn.Peer().Query)
// Get user agent
limiter := i.getVisitor(conn.RequestHeader().Get("User-Agent"))
if limiter.Allow() == false {
return connect.NewError(connect.CodeResourceExhausted, errors.New("rate limit exceeded"))
}
return next(ctx, conn)
})
}
func (i *ratelimitInterceptor) getVisitor(ip string) *rate.Limiter {
func (i *ratelimitInterceptor) getVisitor(userAgent string) *rate.Limiter {
i.mu.Lock()
defer i.mu.Unlock()
v, exists := i.visitors[ip]
v, exists := i.visitors[userAgent]
if !exists {
limiter := rate.NewLimiter(1, 3)
// Include the current time when creating a new visitor.
i.visitors[ip] = &visitor{limiter, time.Now()}
i.visitors[userAgent] = &visitor{limiter, time.Now()}
return limiter
}

View File

@ -0,0 +1,33 @@
package models
import (
"time"
itemv1 "github.com/spotdemo4/trevstack/server/internal/services/item/v1"
"google.golang.org/protobuf/types/known/timestamppb"
)
type Item struct {
ID uint32 `gorm:"primaryKey"`
Name string
Description string
Price float32
Quantity int
Added time.Time
// User
UserID uint
User User
}
func (i Item) ToConnectV1() *itemv1.Item {
return &itemv1.Item{
Id: &i.ID,
Name: i.Name,
Description: i.Description,
Price: i.Price,
Quantity: uint32(i.Quantity),
Added: timestamppb.New(i.Added),
}
}

View File

@ -0,0 +1,759 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.5
// protoc (unknown)
// source: item/v1/item.proto
package itemv1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
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 Item struct {
state protoimpl.MessageState `protogen:"open.v1"`
Id *uint32 `protobuf:"varint,1,opt,name=id,proto3,oneof" json:"id,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
Price float32 `protobuf:"fixed32,4,opt,name=price,proto3" json:"price,omitempty"`
Quantity uint32 `protobuf:"varint,5,opt,name=quantity,proto3" json:"quantity,omitempty"`
Added *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=added,proto3,oneof" json:"added,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Item) Reset() {
*x = Item{}
mi := &file_item_v1_item_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Item) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Item) ProtoMessage() {}
func (x *Item) ProtoReflect() protoreflect.Message {
mi := &file_item_v1_item_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Item.ProtoReflect.Descriptor instead.
func (*Item) Descriptor() ([]byte, []int) {
return file_item_v1_item_proto_rawDescGZIP(), []int{0}
}
func (x *Item) GetId() uint32 {
if x != nil && x.Id != nil {
return *x.Id
}
return 0
}
func (x *Item) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *Item) GetDescription() string {
if x != nil {
return x.Description
}
return ""
}
func (x *Item) GetPrice() float32 {
if x != nil {
return x.Price
}
return 0
}
func (x *Item) GetQuantity() uint32 {
if x != nil {
return x.Quantity
}
return 0
}
func (x *Item) GetAdded() *timestamppb.Timestamp {
if x != nil {
return x.Added
}
return nil
}
type GetItemRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetItemRequest) Reset() {
*x = GetItemRequest{}
mi := &file_item_v1_item_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetItemRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetItemRequest) ProtoMessage() {}
func (x *GetItemRequest) ProtoReflect() protoreflect.Message {
mi := &file_item_v1_item_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetItemRequest.ProtoReflect.Descriptor instead.
func (*GetItemRequest) Descriptor() ([]byte, []int) {
return file_item_v1_item_proto_rawDescGZIP(), []int{1}
}
func (x *GetItemRequest) GetId() uint32 {
if x != nil {
return x.Id
}
return 0
}
type GetItemResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Item *Item `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetItemResponse) Reset() {
*x = GetItemResponse{}
mi := &file_item_v1_item_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetItemResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetItemResponse) ProtoMessage() {}
func (x *GetItemResponse) ProtoReflect() protoreflect.Message {
mi := &file_item_v1_item_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetItemResponse.ProtoReflect.Descriptor instead.
func (*GetItemResponse) Descriptor() ([]byte, []int) {
return file_item_v1_item_proto_rawDescGZIP(), []int{2}
}
func (x *GetItemResponse) GetItem() *Item {
if x != nil {
return x.Item
}
return nil
}
type GetItemsRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Start *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=start,proto3,oneof" json:"start,omitempty"`
End *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=end,proto3,oneof" json:"end,omitempty"`
Filter *string `protobuf:"bytes,3,opt,name=filter,proto3,oneof" json:"filter,omitempty"`
Limit *uint32 `protobuf:"varint,4,opt,name=limit,proto3,oneof" json:"limit,omitempty"`
Offset *uint32 `protobuf:"varint,5,opt,name=offset,proto3,oneof" json:"offset,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetItemsRequest) Reset() {
*x = GetItemsRequest{}
mi := &file_item_v1_item_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetItemsRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetItemsRequest) ProtoMessage() {}
func (x *GetItemsRequest) ProtoReflect() protoreflect.Message {
mi := &file_item_v1_item_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetItemsRequest.ProtoReflect.Descriptor instead.
func (*GetItemsRequest) Descriptor() ([]byte, []int) {
return file_item_v1_item_proto_rawDescGZIP(), []int{3}
}
func (x *GetItemsRequest) GetStart() *timestamppb.Timestamp {
if x != nil {
return x.Start
}
return nil
}
func (x *GetItemsRequest) GetEnd() *timestamppb.Timestamp {
if x != nil {
return x.End
}
return nil
}
func (x *GetItemsRequest) GetFilter() string {
if x != nil && x.Filter != nil {
return *x.Filter
}
return ""
}
func (x *GetItemsRequest) GetLimit() uint32 {
if x != nil && x.Limit != nil {
return *x.Limit
}
return 0
}
func (x *GetItemsRequest) GetOffset() uint32 {
if x != nil && x.Offset != nil {
return *x.Offset
}
return 0
}
type GetItemsResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Items []*Item `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"`
Count uint64 `protobuf:"varint,2,opt,name=count,proto3" json:"count,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetItemsResponse) Reset() {
*x = GetItemsResponse{}
mi := &file_item_v1_item_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetItemsResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetItemsResponse) ProtoMessage() {}
func (x *GetItemsResponse) ProtoReflect() protoreflect.Message {
mi := &file_item_v1_item_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetItemsResponse.ProtoReflect.Descriptor instead.
func (*GetItemsResponse) Descriptor() ([]byte, []int) {
return file_item_v1_item_proto_rawDescGZIP(), []int{4}
}
func (x *GetItemsResponse) GetItems() []*Item {
if x != nil {
return x.Items
}
return nil
}
func (x *GetItemsResponse) GetCount() uint64 {
if x != nil {
return x.Count
}
return 0
}
type CreateItemRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Item *Item `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *CreateItemRequest) Reset() {
*x = CreateItemRequest{}
mi := &file_item_v1_item_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CreateItemRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateItemRequest) ProtoMessage() {}
func (x *CreateItemRequest) ProtoReflect() protoreflect.Message {
mi := &file_item_v1_item_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CreateItemRequest.ProtoReflect.Descriptor instead.
func (*CreateItemRequest) Descriptor() ([]byte, []int) {
return file_item_v1_item_proto_rawDescGZIP(), []int{5}
}
func (x *CreateItemRequest) GetItem() *Item {
if x != nil {
return x.Item
}
return nil
}
type CreateItemResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Item *Item `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *CreateItemResponse) Reset() {
*x = CreateItemResponse{}
mi := &file_item_v1_item_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CreateItemResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateItemResponse) ProtoMessage() {}
func (x *CreateItemResponse) ProtoReflect() protoreflect.Message {
mi := &file_item_v1_item_proto_msgTypes[6]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CreateItemResponse.ProtoReflect.Descriptor instead.
func (*CreateItemResponse) Descriptor() ([]byte, []int) {
return file_item_v1_item_proto_rawDescGZIP(), []int{6}
}
func (x *CreateItemResponse) GetItem() *Item {
if x != nil {
return x.Item
}
return nil
}
type UpdateItemRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Item *Item `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *UpdateItemRequest) Reset() {
*x = UpdateItemRequest{}
mi := &file_item_v1_item_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *UpdateItemRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateItemRequest) ProtoMessage() {}
func (x *UpdateItemRequest) ProtoReflect() protoreflect.Message {
mi := &file_item_v1_item_proto_msgTypes[7]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpdateItemRequest.ProtoReflect.Descriptor instead.
func (*UpdateItemRequest) Descriptor() ([]byte, []int) {
return file_item_v1_item_proto_rawDescGZIP(), []int{7}
}
func (x *UpdateItemRequest) GetItem() *Item {
if x != nil {
return x.Item
}
return nil
}
type UpdateItemResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Item *Item `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *UpdateItemResponse) Reset() {
*x = UpdateItemResponse{}
mi := &file_item_v1_item_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *UpdateItemResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateItemResponse) ProtoMessage() {}
func (x *UpdateItemResponse) ProtoReflect() protoreflect.Message {
mi := &file_item_v1_item_proto_msgTypes[8]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpdateItemResponse.ProtoReflect.Descriptor instead.
func (*UpdateItemResponse) Descriptor() ([]byte, []int) {
return file_item_v1_item_proto_rawDescGZIP(), []int{8}
}
func (x *UpdateItemResponse) GetItem() *Item {
if x != nil {
return x.Item
}
return nil
}
type DeleteItemRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *DeleteItemRequest) Reset() {
*x = DeleteItemRequest{}
mi := &file_item_v1_item_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *DeleteItemRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DeleteItemRequest) ProtoMessage() {}
func (x *DeleteItemRequest) ProtoReflect() protoreflect.Message {
mi := &file_item_v1_item_proto_msgTypes[9]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DeleteItemRequest.ProtoReflect.Descriptor instead.
func (*DeleteItemRequest) Descriptor() ([]byte, []int) {
return file_item_v1_item_proto_rawDescGZIP(), []int{9}
}
func (x *DeleteItemRequest) GetId() uint32 {
if x != nil {
return x.Id
}
return 0
}
type DeleteItemResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *DeleteItemResponse) Reset() {
*x = DeleteItemResponse{}
mi := &file_item_v1_item_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *DeleteItemResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DeleteItemResponse) ProtoMessage() {}
func (x *DeleteItemResponse) ProtoReflect() protoreflect.Message {
mi := &file_item_v1_item_proto_msgTypes[10]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DeleteItemResponse.ProtoReflect.Descriptor instead.
func (*DeleteItemResponse) Descriptor() ([]byte, []int) {
return file_item_v1_item_proto_rawDescGZIP(), []int{10}
}
var File_item_v1_item_proto protoreflect.FileDescriptor
var file_item_v1_item_proto_rawDesc = string([]byte{
0x0a, 0x12, 0x69, 0x74, 0x65, 0x6d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74,
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xcb,
0x01, 0x0a, 0x04, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x13, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x88, 0x01, 0x01, 0x12, 0x12, 0x0a, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18,
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
0x02, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e,
0x74, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x71, 0x75, 0x61, 0x6e,
0x74, 0x69, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x65, 0x64, 0x18, 0x06, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48,
0x01, 0x52, 0x05, 0x61, 0x64, 0x64, 0x65, 0x64, 0x88, 0x01, 0x01, 0x42, 0x05, 0x0a, 0x03, 0x5f,
0x69, 0x64, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x61, 0x64, 0x64, 0x65, 0x64, 0x22, 0x20, 0x0a, 0x0e,
0x47, 0x65, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e,
0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x22, 0x34,
0x0a, 0x0f, 0x47, 0x65, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x21, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x0d, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04,
0x69, 0x74, 0x65, 0x6d, 0x22, 0x82, 0x02, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x49, 0x74, 0x65, 0x6d,
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72,
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
0x61, 0x6d, 0x70, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x88, 0x01, 0x01, 0x12,
0x31, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54,
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x01, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x88,
0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01,
0x28, 0x09, 0x48, 0x02, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12,
0x19, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x03,
0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x6f, 0x66,
0x66, 0x73, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x04, 0x52, 0x06, 0x6f, 0x66,
0x66, 0x73, 0x65, 0x74, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72,
0x74, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x65, 0x6e, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x66, 0x69,
0x6c, 0x74, 0x65, 0x72, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x42, 0x09,
0x0a, 0x07, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x22, 0x4d, 0x0a, 0x10, 0x47, 0x65, 0x74,
0x49, 0x74, 0x65, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a,
0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x69,
0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65,
0x6d, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x36, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a,
0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x69, 0x74,
0x65, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d,
0x22, 0x37, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x49,
0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x36, 0x0a, 0x11, 0x55, 0x70, 0x64,
0x61, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21,
0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x69,
0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74, 0x65,
0x6d, 0x22, 0x37, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x2e,
0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x23, 0x0a, 0x11, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x22,
0x14, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xeb, 0x02, 0x0a, 0x0b, 0x49, 0x74, 0x65, 0x6d, 0x53, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x74, 0x65, 0x6d,
0x12, 0x17, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x74,
0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x69, 0x74, 0x65, 0x6d,
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x49, 0x74, 0x65, 0x6d,
0x73, 0x12, 0x18, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49,
0x74, 0x65, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x69, 0x74,
0x65, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1a, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31,
0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65,
0x61, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x12, 0x47, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x12,
0x1a, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x69, 0x74,
0x65, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x0a, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1a, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x2e,
0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x44,
0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x42, 0x9d, 0x01, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x2e, 0x69, 0x74, 0x65, 0x6d,
0x2e, 0x76, 0x31, 0x42, 0x09, 0x49, 0x74, 0x65, 0x6d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01,
0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x70, 0x6f,
0x74, 0x64, 0x65, 0x6d, 0x6f, 0x34, 0x2f, 0x74, 0x72, 0x65, 0x76, 0x73, 0x74, 0x61, 0x63, 0x6b,
0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x74, 0x65, 0x6d, 0x2f, 0x76,
0x31, 0x3b, 0x69, 0x74, 0x65, 0x6d, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x49, 0x58, 0x58, 0xaa, 0x02,
0x07, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x07, 0x49, 0x74, 0x65, 0x6d, 0x5c,
0x56, 0x31, 0xe2, 0x02, 0x13, 0x49, 0x74, 0x65, 0x6d, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42,
0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x08, 0x49, 0x74, 0x65, 0x6d, 0x3a,
0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
})
var (
file_item_v1_item_proto_rawDescOnce sync.Once
file_item_v1_item_proto_rawDescData []byte
)
func file_item_v1_item_proto_rawDescGZIP() []byte {
file_item_v1_item_proto_rawDescOnce.Do(func() {
file_item_v1_item_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_item_v1_item_proto_rawDesc), len(file_item_v1_item_proto_rawDesc)))
})
return file_item_v1_item_proto_rawDescData
}
var file_item_v1_item_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
var file_item_v1_item_proto_goTypes = []any{
(*Item)(nil), // 0: item.v1.Item
(*GetItemRequest)(nil), // 1: item.v1.GetItemRequest
(*GetItemResponse)(nil), // 2: item.v1.GetItemResponse
(*GetItemsRequest)(nil), // 3: item.v1.GetItemsRequest
(*GetItemsResponse)(nil), // 4: item.v1.GetItemsResponse
(*CreateItemRequest)(nil), // 5: item.v1.CreateItemRequest
(*CreateItemResponse)(nil), // 6: item.v1.CreateItemResponse
(*UpdateItemRequest)(nil), // 7: item.v1.UpdateItemRequest
(*UpdateItemResponse)(nil), // 8: item.v1.UpdateItemResponse
(*DeleteItemRequest)(nil), // 9: item.v1.DeleteItemRequest
(*DeleteItemResponse)(nil), // 10: item.v1.DeleteItemResponse
(*timestamppb.Timestamp)(nil), // 11: google.protobuf.Timestamp
}
var file_item_v1_item_proto_depIdxs = []int32{
11, // 0: item.v1.Item.added:type_name -> google.protobuf.Timestamp
0, // 1: item.v1.GetItemResponse.item:type_name -> item.v1.Item
11, // 2: item.v1.GetItemsRequest.start:type_name -> google.protobuf.Timestamp
11, // 3: item.v1.GetItemsRequest.end:type_name -> google.protobuf.Timestamp
0, // 4: item.v1.GetItemsResponse.items:type_name -> item.v1.Item
0, // 5: item.v1.CreateItemRequest.item:type_name -> item.v1.Item
0, // 6: item.v1.CreateItemResponse.item:type_name -> item.v1.Item
0, // 7: item.v1.UpdateItemRequest.item:type_name -> item.v1.Item
0, // 8: item.v1.UpdateItemResponse.item:type_name -> item.v1.Item
1, // 9: item.v1.ItemService.GetItem:input_type -> item.v1.GetItemRequest
3, // 10: item.v1.ItemService.GetItems:input_type -> item.v1.GetItemsRequest
5, // 11: item.v1.ItemService.CreateItem:input_type -> item.v1.CreateItemRequest
7, // 12: item.v1.ItemService.UpdateItem:input_type -> item.v1.UpdateItemRequest
9, // 13: item.v1.ItemService.DeleteItem:input_type -> item.v1.DeleteItemRequest
2, // 14: item.v1.ItemService.GetItem:output_type -> item.v1.GetItemResponse
4, // 15: item.v1.ItemService.GetItems:output_type -> item.v1.GetItemsResponse
6, // 16: item.v1.ItemService.CreateItem:output_type -> item.v1.CreateItemResponse
8, // 17: item.v1.ItemService.UpdateItem:output_type -> item.v1.UpdateItemResponse
10, // 18: item.v1.ItemService.DeleteItem:output_type -> item.v1.DeleteItemResponse
14, // [14:19] is the sub-list for method output_type
9, // [9:14] is the sub-list for method input_type
9, // [9:9] is the sub-list for extension type_name
9, // [9:9] is the sub-list for extension extendee
0, // [0:9] is the sub-list for field type_name
}
func init() { file_item_v1_item_proto_init() }
func file_item_v1_item_proto_init() {
if File_item_v1_item_proto != nil {
return
}
file_item_v1_item_proto_msgTypes[0].OneofWrappers = []any{}
file_item_v1_item_proto_msgTypes[3].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_item_v1_item_proto_rawDesc), len(file_item_v1_item_proto_rawDesc)),
NumEnums: 0,
NumMessages: 11,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_item_v1_item_proto_goTypes,
DependencyIndexes: file_item_v1_item_proto_depIdxs,
MessageInfos: file_item_v1_item_proto_msgTypes,
}.Build()
File_item_v1_item_proto = out.File
file_item_v1_item_proto_goTypes = nil
file_item_v1_item_proto_depIdxs = nil
}

View File

@ -0,0 +1,220 @@
// Code generated by protoc-gen-connect-go. DO NOT EDIT.
//
// Source: item/v1/item.proto
package itemv1connect
import (
connect "connectrpc.com/connect"
context "context"
errors "errors"
v1 "github.com/spotdemo4/trevstack/server/internal/services/item/v1"
http "net/http"
strings "strings"
)
// This is a compile-time assertion to ensure that this generated file and the connect package are
// compatible. If you get a compiler error that this constant is not defined, this code was
// generated with a version of connect newer than the one compiled into your binary. You can fix the
// problem by either regenerating this code with an older version of connect or updating the connect
// version compiled into your binary.
const _ = connect.IsAtLeastVersion1_13_0
const (
// ItemServiceName is the fully-qualified name of the ItemService service.
ItemServiceName = "item.v1.ItemService"
)
// These constants are the fully-qualified names of the RPCs defined in this package. They're
// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
//
// Note that these are different from the fully-qualified method names used by
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
// period.
const (
// ItemServiceGetItemProcedure is the fully-qualified name of the ItemService's GetItem RPC.
ItemServiceGetItemProcedure = "/item.v1.ItemService/GetItem"
// ItemServiceGetItemsProcedure is the fully-qualified name of the ItemService's GetItems RPC.
ItemServiceGetItemsProcedure = "/item.v1.ItemService/GetItems"
// ItemServiceCreateItemProcedure is the fully-qualified name of the ItemService's CreateItem RPC.
ItemServiceCreateItemProcedure = "/item.v1.ItemService/CreateItem"
// ItemServiceUpdateItemProcedure is the fully-qualified name of the ItemService's UpdateItem RPC.
ItemServiceUpdateItemProcedure = "/item.v1.ItemService/UpdateItem"
// ItemServiceDeleteItemProcedure is the fully-qualified name of the ItemService's DeleteItem RPC.
ItemServiceDeleteItemProcedure = "/item.v1.ItemService/DeleteItem"
)
// ItemServiceClient is a client for the item.v1.ItemService service.
type ItemServiceClient interface {
GetItem(context.Context, *connect.Request[v1.GetItemRequest]) (*connect.Response[v1.GetItemResponse], error)
GetItems(context.Context, *connect.Request[v1.GetItemsRequest]) (*connect.Response[v1.GetItemsResponse], error)
CreateItem(context.Context, *connect.Request[v1.CreateItemRequest]) (*connect.Response[v1.CreateItemResponse], error)
UpdateItem(context.Context, *connect.Request[v1.UpdateItemRequest]) (*connect.Response[v1.UpdateItemResponse], error)
DeleteItem(context.Context, *connect.Request[v1.DeleteItemRequest]) (*connect.Response[v1.DeleteItemResponse], error)
}
// NewItemServiceClient constructs a client for the item.v1.ItemService service. By default, it uses
// the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends
// uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or
// connect.WithGRPCWeb() options.
//
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
// http://api.acme.com or https://acme.com/grpc).
func NewItemServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) ItemServiceClient {
baseURL = strings.TrimRight(baseURL, "/")
itemServiceMethods := v1.File_item_v1_item_proto.Services().ByName("ItemService").Methods()
return &itemServiceClient{
getItem: connect.NewClient[v1.GetItemRequest, v1.GetItemResponse](
httpClient,
baseURL+ItemServiceGetItemProcedure,
connect.WithSchema(itemServiceMethods.ByName("GetItem")),
connect.WithClientOptions(opts...),
),
getItems: connect.NewClient[v1.GetItemsRequest, v1.GetItemsResponse](
httpClient,
baseURL+ItemServiceGetItemsProcedure,
connect.WithSchema(itemServiceMethods.ByName("GetItems")),
connect.WithClientOptions(opts...),
),
createItem: connect.NewClient[v1.CreateItemRequest, v1.CreateItemResponse](
httpClient,
baseURL+ItemServiceCreateItemProcedure,
connect.WithSchema(itemServiceMethods.ByName("CreateItem")),
connect.WithClientOptions(opts...),
),
updateItem: connect.NewClient[v1.UpdateItemRequest, v1.UpdateItemResponse](
httpClient,
baseURL+ItemServiceUpdateItemProcedure,
connect.WithSchema(itemServiceMethods.ByName("UpdateItem")),
connect.WithClientOptions(opts...),
),
deleteItem: connect.NewClient[v1.DeleteItemRequest, v1.DeleteItemResponse](
httpClient,
baseURL+ItemServiceDeleteItemProcedure,
connect.WithSchema(itemServiceMethods.ByName("DeleteItem")),
connect.WithClientOptions(opts...),
),
}
}
// itemServiceClient implements ItemServiceClient.
type itemServiceClient struct {
getItem *connect.Client[v1.GetItemRequest, v1.GetItemResponse]
getItems *connect.Client[v1.GetItemsRequest, v1.GetItemsResponse]
createItem *connect.Client[v1.CreateItemRequest, v1.CreateItemResponse]
updateItem *connect.Client[v1.UpdateItemRequest, v1.UpdateItemResponse]
deleteItem *connect.Client[v1.DeleteItemRequest, v1.DeleteItemResponse]
}
// GetItem calls item.v1.ItemService.GetItem.
func (c *itemServiceClient) GetItem(ctx context.Context, req *connect.Request[v1.GetItemRequest]) (*connect.Response[v1.GetItemResponse], error) {
return c.getItem.CallUnary(ctx, req)
}
// GetItems calls item.v1.ItemService.GetItems.
func (c *itemServiceClient) GetItems(ctx context.Context, req *connect.Request[v1.GetItemsRequest]) (*connect.Response[v1.GetItemsResponse], error) {
return c.getItems.CallUnary(ctx, req)
}
// CreateItem calls item.v1.ItemService.CreateItem.
func (c *itemServiceClient) CreateItem(ctx context.Context, req *connect.Request[v1.CreateItemRequest]) (*connect.Response[v1.CreateItemResponse], error) {
return c.createItem.CallUnary(ctx, req)
}
// UpdateItem calls item.v1.ItemService.UpdateItem.
func (c *itemServiceClient) UpdateItem(ctx context.Context, req *connect.Request[v1.UpdateItemRequest]) (*connect.Response[v1.UpdateItemResponse], error) {
return c.updateItem.CallUnary(ctx, req)
}
// DeleteItem calls item.v1.ItemService.DeleteItem.
func (c *itemServiceClient) DeleteItem(ctx context.Context, req *connect.Request[v1.DeleteItemRequest]) (*connect.Response[v1.DeleteItemResponse], error) {
return c.deleteItem.CallUnary(ctx, req)
}
// ItemServiceHandler is an implementation of the item.v1.ItemService service.
type ItemServiceHandler interface {
GetItem(context.Context, *connect.Request[v1.GetItemRequest]) (*connect.Response[v1.GetItemResponse], error)
GetItems(context.Context, *connect.Request[v1.GetItemsRequest]) (*connect.Response[v1.GetItemsResponse], error)
CreateItem(context.Context, *connect.Request[v1.CreateItemRequest]) (*connect.Response[v1.CreateItemResponse], error)
UpdateItem(context.Context, *connect.Request[v1.UpdateItemRequest]) (*connect.Response[v1.UpdateItemResponse], error)
DeleteItem(context.Context, *connect.Request[v1.DeleteItemRequest]) (*connect.Response[v1.DeleteItemResponse], error)
}
// NewItemServiceHandler builds an HTTP handler from the service implementation. It returns the path
// on which to mount the handler and the handler itself.
//
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
// and JSON codecs. They also support gzip compression.
func NewItemServiceHandler(svc ItemServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
itemServiceMethods := v1.File_item_v1_item_proto.Services().ByName("ItemService").Methods()
itemServiceGetItemHandler := connect.NewUnaryHandler(
ItemServiceGetItemProcedure,
svc.GetItem,
connect.WithSchema(itemServiceMethods.ByName("GetItem")),
connect.WithHandlerOptions(opts...),
)
itemServiceGetItemsHandler := connect.NewUnaryHandler(
ItemServiceGetItemsProcedure,
svc.GetItems,
connect.WithSchema(itemServiceMethods.ByName("GetItems")),
connect.WithHandlerOptions(opts...),
)
itemServiceCreateItemHandler := connect.NewUnaryHandler(
ItemServiceCreateItemProcedure,
svc.CreateItem,
connect.WithSchema(itemServiceMethods.ByName("CreateItem")),
connect.WithHandlerOptions(opts...),
)
itemServiceUpdateItemHandler := connect.NewUnaryHandler(
ItemServiceUpdateItemProcedure,
svc.UpdateItem,
connect.WithSchema(itemServiceMethods.ByName("UpdateItem")),
connect.WithHandlerOptions(opts...),
)
itemServiceDeleteItemHandler := connect.NewUnaryHandler(
ItemServiceDeleteItemProcedure,
svc.DeleteItem,
connect.WithSchema(itemServiceMethods.ByName("DeleteItem")),
connect.WithHandlerOptions(opts...),
)
return "/item.v1.ItemService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case ItemServiceGetItemProcedure:
itemServiceGetItemHandler.ServeHTTP(w, r)
case ItemServiceGetItemsProcedure:
itemServiceGetItemsHandler.ServeHTTP(w, r)
case ItemServiceCreateItemProcedure:
itemServiceCreateItemHandler.ServeHTTP(w, r)
case ItemServiceUpdateItemProcedure:
itemServiceUpdateItemHandler.ServeHTTP(w, r)
case ItemServiceDeleteItemProcedure:
itemServiceDeleteItemHandler.ServeHTTP(w, r)
default:
http.NotFound(w, r)
}
})
}
// UnimplementedItemServiceHandler returns CodeUnimplemented from all methods.
type UnimplementedItemServiceHandler struct{}
func (UnimplementedItemServiceHandler) GetItem(context.Context, *connect.Request[v1.GetItemRequest]) (*connect.Response[v1.GetItemResponse], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("item.v1.ItemService.GetItem is not implemented"))
}
func (UnimplementedItemServiceHandler) GetItems(context.Context, *connect.Request[v1.GetItemsRequest]) (*connect.Response[v1.GetItemsResponse], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("item.v1.ItemService.GetItems is not implemented"))
}
func (UnimplementedItemServiceHandler) CreateItem(context.Context, *connect.Request[v1.CreateItemRequest]) (*connect.Response[v1.CreateItemResponse], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("item.v1.ItemService.CreateItem is not implemented"))
}
func (UnimplementedItemServiceHandler) UpdateItem(context.Context, *connect.Request[v1.UpdateItemRequest]) (*connect.Response[v1.UpdateItemResponse], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("item.v1.ItemService.UpdateItem is not implemented"))
}
func (UnimplementedItemServiceHandler) DeleteItem(context.Context, *connect.Request[v1.DeleteItemRequest]) (*connect.Response[v1.DeleteItemResponse], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("item.v1.ItemService.DeleteItem is not implemented"))
}

View File

@ -114,6 +114,7 @@ func main() {
api := http.NewServeMux()
api.Handle(withCORS(handlers.NewAuthHandler(db, env.Key)))
api.Handle(withCORS(handlers.NewUserHandler(db, env.Key)))
api.Handle(withCORS(handlers.NewItemHandler(db, env.Key)))
// Serve web interface
mux := http.NewServeMux()
@ -153,7 +154,9 @@ func main() {
}
}()
server.ListenAndServe()
if err := server.ListenAndServe(); err != nil {
log.Fatal(err)
}
}
// withCORS adds CORS support to a Connect HTTP handler.