Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
d7284fe8
Commit
d7284fe8
authored
Dec 30, 2025
by
Johnny
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor: nest reaction resource names under memos
parent
c2aea5a4
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
63 additions
and
53 deletions
+63
-53
memo_service.proto
proto/api/v1/memo_service.proto
+4
-4
memo_service.pb.go
proto/gen/api/v1/memo_service.pb.go
+8
-8
memo_service.pb.gw.go
proto/gen/api/v1/memo_service.pb.gw.go
+3
-3
openapi.yaml
proto/gen/openapi.yaml
+30
-24
reaction_service.go
server/router/api/v1/reaction_service.go
+4
-2
resource_name.go
server/router/api/v1/resource_name.go
+9
-8
reaction_service_test.go
server/router/api/v1/test/reaction_service_test.go
+2
-1
memo_service_pb.ts
web/src/types/proto/api/v1/memo_service_pb.ts
+3
-3
No files found.
proto/api/v1/memo_service.proto
View file @
d7284fe8
...
@@ -100,7 +100,7 @@ service MemoService {
...
@@ -100,7 +100,7 @@ service MemoService {
}
}
// DeleteMemoReaction deletes a reaction for a memo.
// DeleteMemoReaction deletes a reaction for a memo.
rpc
DeleteMemoReaction
(
DeleteMemoReactionRequest
)
returns
(
google.protobuf.Empty
)
{
rpc
DeleteMemoReaction
(
DeleteMemoReactionRequest
)
returns
(
google.protobuf.Empty
)
{
option
(
google.api.http
)
=
{
delete
:
"/api/v1/{name=reactions/*}"
};
option
(
google.api.http
)
=
{
delete
:
"/api/v1/{name=
memos/*/
reactions/*}"
};
option
(
google.api.method_signature
)
=
"name"
;
option
(
google.api.method_signature
)
=
"name"
;
}
}
}
}
...
@@ -115,14 +115,14 @@ enum Visibility {
...
@@ -115,14 +115,14 @@ enum Visibility {
message
Reaction
{
message
Reaction
{
option
(
google.api.resource
)
=
{
option
(
google.api.resource
)
=
{
type
:
"memos.api.v1/Reaction"
type
:
"memos.api.v1/Reaction"
pattern
:
"reactions/{reaction}"
pattern
:
"
memos/{memo}/
reactions/{reaction}"
name_field
:
"name"
name_field
:
"name"
singular
:
"reaction"
singular
:
"reaction"
plural
:
"reactions"
plural
:
"reactions"
};
};
// The resource name of the reaction.
// The resource name of the reaction.
// Format: reactions/{reaction}
// Format:
memos/{memo}/
reactions/{reaction}
string
name
=
1
[
string
name
=
1
[
(
google.api.field_behavior
)
=
OUTPUT_ONLY
,
(
google.api.field_behavior
)
=
OUTPUT_ONLY
,
(
google.api.field_behavior
)
=
IDENTIFIER
(
google.api.field_behavior
)
=
IDENTIFIER
...
@@ -501,7 +501,7 @@ message UpsertMemoReactionRequest {
...
@@ -501,7 +501,7 @@ message UpsertMemoReactionRequest {
message
DeleteMemoReactionRequest
{
message
DeleteMemoReactionRequest
{
// Required. The resource name of the reaction to delete.
// Required. The resource name of the reaction to delete.
// Format: reactions/{reaction}
// Format:
memos/{memo}/
reactions/{reaction}
string
name
=
1
[
string
name
=
1
[
(
google.api.field_behavior
)
=
REQUIRED
,
(
google.api.field_behavior
)
=
REQUIRED
,
(
google.api.resource_reference
)
=
{
type
:
"memos.api.v1/Reaction"
}
(
google.api.resource_reference
)
=
{
type
:
"memos.api.v1/Reaction"
}
...
...
proto/gen/api/v1/memo_service.pb.go
View file @
d7284fe8
...
@@ -130,7 +130,7 @@ func (MemoRelation_Type) EnumDescriptor() ([]byte, []int) {
...
@@ -130,7 +130,7 @@ func (MemoRelation_Type) EnumDescriptor() ([]byte, []int) {
type
Reaction
struct
{
type
Reaction
struct
{
state
protoimpl
.
MessageState
`protogen:"open.v1"`
state
protoimpl
.
MessageState
`protogen:"open.v1"`
// The resource name of the reaction.
// The resource name of the reaction.
// Format: reactions/{reaction}
// Format:
memos/{memo}/
reactions/{reaction}
Name
string
`protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Name
string
`protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
// The resource name of the creator.
// The resource name of the creator.
// Format: users/{user}
// Format: users/{user}
...
@@ -1627,7 +1627,7 @@ func (x *UpsertMemoReactionRequest) GetReaction() *Reaction {
...
@@ -1627,7 +1627,7 @@ func (x *UpsertMemoReactionRequest) GetReaction() *Reaction {
type
DeleteMemoReactionRequest
struct
{
type
DeleteMemoReactionRequest
struct
{
state
protoimpl
.
MessageState
`protogen:"open.v1"`
state
protoimpl
.
MessageState
`protogen:"open.v1"`
// Required. The resource name of the reaction to delete.
// Required. The resource name of the reaction to delete.
// Format: reactions/{reaction}
// Format:
memos/{memo}/
reactions/{reaction}
Name
string
`protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Name
string
`protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
unknownFields
protoimpl
.
UnknownFields
unknownFields
protoimpl
.
UnknownFields
sizeCache
protoimpl
.
SizeCache
sizeCache
protoimpl
.
SizeCache
...
@@ -1799,7 +1799,7 @@ var File_api_v1_memo_service_proto protoreflect.FileDescriptor
...
@@ -1799,7 +1799,7 @@ var File_api_v1_memo_service_proto protoreflect.FileDescriptor
const
file_api_v1_memo_service_proto_rawDesc
=
""
+
const
file_api_v1_memo_service_proto_rawDesc
=
""
+
"
\n
"
+
"
\n
"
+
"
\x19
api/v1/memo_service.proto
\x12\f
memos.api.v1
\x1a\x1f
api/v1/attachment_service.proto
\x1a\x13
api/v1/common.proto
\x1a\x1c
google/api/annotations.proto
\x1a\x17
google/api/client.proto
\x1a\x1f
google/api/field_behavior.proto
\x1a\x19
google/api/resource.proto
\x1a\x1b
google/protobuf/empty.proto
\x1a
google/protobuf/field_mask.proto
\x1a\x1f
google/protobuf/timestamp.proto
\"\x
ce
\x02\n
"
+
"
\x19
api/v1/memo_service.proto
\x12\f
memos.api.v1
\x1a\x1f
api/v1/attachment_service.proto
\x1a\x13
api/v1/common.proto
\x1a\x1c
google/api/annotations.proto
\x1a\x17
google/api/client.proto
\x1a\x1f
google/api/field_behavior.proto
\x1a\x19
google/api/resource.proto
\x1a\x1b
google/protobuf/empty.proto
\x1a
google/protobuf/field_mask.proto
\x1a\x1f
google/protobuf/timestamp.proto
\"\x
db
\x02\n
"
+
"
\b
Reaction
\x12\x1a\n
"
+
"
\b
Reaction
\x12\x1a\n
"
+
"
\x04
name
\x18\x01
\x01
(
\t
B
\x06\xe0
A
\x03\xe0
A
\b
R
\x04
name
\x12
3
\n
"
+
"
\x04
name
\x18\x01
\x01
(
\t
B
\x06\xe0
A
\x03\xe0
A
\b
R
\x04
name
\x12
3
\n
"
+
"
\a
creator
\x18\x02
\x01
(
\t
B
\x19\xe0
A
\x03\xfa
A
\x13\n
"
+
"
\a
creator
\x18\x02
\x01
(
\t
B
\x19\xe0
A
\x03\xfa
A
\x13\n
"
+
...
@@ -1809,8 +1809,8 @@ const file_api_v1_memo_service_proto_rawDesc = "" +
...
@@ -1809,8 +1809,8 @@ const file_api_v1_memo_service_proto_rawDesc = "" +
"
\x11
memos.api.v1/MemoR
\t
contentId
\x12
(
\n
"
+
"
\x11
memos.api.v1/MemoR
\t
contentId
\x12
(
\n
"
+
"
\r
reaction_type
\x18\x04
\x01
(
\t
B
\x03\xe0
A
\x02
R
\f
reactionType
\x12
@
\n
"
+
"
\r
reaction_type
\x18\x04
\x01
(
\t
B
\x03\xe0
A
\x02
R
\f
reactionType
\x12
@
\n
"
+
"
\v
create_time
\x18\x05
\x01
(
\v
2
\x1a
.google.protobuf.TimestampB
\x03\xe0
A
\x03
R
\n
"
+
"
\v
create_time
\x18\x05
\x01
(
\v
2
\x1a
.google.protobuf.TimestampB
\x03\xe0
A
\x03
R
\n
"
+
"createTime:
K
\xea
AH
\n
"
+
"createTime:
X
\xea
AU
\n
"
+
"
\x15
memos.api.v1/Reaction
\x12
\x14
reactions/{reaction}
\x1a\x04
name*
\t
reactions2
\b
reaction
\"\xd8\b\n
"
+
"
\x15
memos.api.v1/Reaction
\x12
!memos/{memo}/
reactions/{reaction}
\x1a\x04
name*
\t
reactions2
\b
reaction
\"\xd8\b\n
"
+
"
\x04
Memo
\x12\x17\n
"
+
"
\x04
Memo
\x12\x17\n
"
+
"
\x04
name
\x18\x01
\x01
(
\t
B
\x03\xe0
A
\b
R
\x04
name
\x12
.
\n
"
+
"
\x04
name
\x18\x01
\x01
(
\t
B
\x03\xe0
A
\b
R
\x04
name
\x12
.
\n
"
+
"
\x05
state
\x18\x02
\x01
(
\x0e
2
\x13
.memos.api.v1.StateB
\x03\xe0
A
\x02
R
\x05
state
\x12
3
\n
"
+
"
\x05
state
\x18\x02
\x01
(
\x0e
2
\x13
.memos.api.v1.StateB
\x03\xe0
A
\x02
R
\x05
state
\x12
3
\n
"
+
...
@@ -1953,7 +1953,7 @@ const file_api_v1_memo_service_proto_rawDesc = "" +
...
@@ -1953,7 +1953,7 @@ const file_api_v1_memo_service_proto_rawDesc = "" +
"
\a
PRIVATE
\x10\x01\x12\r\n
"
+
"
\a
PRIVATE
\x10\x01\x12\r\n
"
+
"
\t
PROTECTED
\x10\x02\x12\n
"
+
"
\t
PROTECTED
\x10\x02\x12\n
"
+
"
\n
"
+
"
\n
"
+
"
\x06
PUBLIC
\x10\x03
2
\x
cb
\x0e\n
"
+
"
\x06
PUBLIC
\x10\x03
2
\x
d3
\x0e\n
"
+
"
\v
MemoService
\x12
e
\n
"
+
"
\v
MemoService
\x12
e
\n
"
+
"
\n
"
+
"
\n
"
+
"CreateMemo
\x12\x1f
.memos.api.v1.CreateMemoRequest
\x1a\x12
.memos.api.v1.Memo
\"\"\xda
A
\x04
memo
\x82\xd3\xe4\x93\x02\x15
:
\x04
memo
\"\r
/api/v1/memos
\x12
f
\n
"
+
"CreateMemo
\x12\x1f
.memos.api.v1.CreateMemoRequest
\x1a\x12
.memos.api.v1.Memo
\"\"\xda
A
\x04
memo
\x82\xd3\xe4\x93\x02\x15
:
\x04
memo
\"\r
/api/v1/memos
\x12
f
\n
"
+
...
@@ -1970,8 +1970,8 @@ const file_api_v1_memo_service_proto_rawDesc = "" +
...
@@ -1970,8 +1970,8 @@ const file_api_v1_memo_service_proto_rawDesc = "" +
"
\x11
CreateMemoComment
\x12
&.memos.api.v1.CreateMemoCommentRequest
\x1a\x12
.memos.api.v1.Memo
\"
?
\xda
A
\f
name,comment
\x82\xd3\xe4\x93\x02
*:
\a
comment
\"\x1f
/api/v1/{name=memos/*}/comments
\x12\x91\x01\n
"
+
"
\x11
CreateMemoComment
\x12
&.memos.api.v1.CreateMemoCommentRequest
\x1a\x12
.memos.api.v1.Memo
\"
?
\xda
A
\f
name,comment
\x82\xd3\xe4\x93\x02
*:
\a
comment
\"\x1f
/api/v1/{name=memos/*}/comments
\x12\x91\x01\n
"
+
"
\x10
ListMemoComments
\x12
%.memos.api.v1.ListMemoCommentsRequest
\x1a
&.memos.api.v1.ListMemoCommentsResponse
\"
.
\xda
A
\x04
name
\x82\xd3\xe4\x93\x02
!
\x12\x1f
/api/v1/{name=memos/*}/comments
\x12\x95\x01\n
"
+
"
\x10
ListMemoComments
\x12
%.memos.api.v1.ListMemoCommentsRequest
\x1a
&.memos.api.v1.ListMemoCommentsResponse
\"
.
\xda
A
\x04
name
\x82\xd3\xe4\x93\x02
!
\x12\x1f
/api/v1/{name=memos/*}/comments
\x12\x95\x01\n
"
+
"
\x11
ListMemoReactions
\x12
&.memos.api.v1.ListMemoReactionsRequest
\x1a
'.memos.api.v1.ListMemoReactionsResponse
\"
/
\xda
A
\x04
name
\x82\xd3\xe4\x93\x02\"\x12
/api/v1/{name=memos/*}/reactions
\x12\x89\x01\n
"
+
"
\x11
ListMemoReactions
\x12
&.memos.api.v1.ListMemoReactionsRequest
\x1a
'.memos.api.v1.ListMemoReactionsResponse
\"
/
\xda
A
\x04
name
\x82\xd3\xe4\x93\x02\"\x12
/api/v1/{name=memos/*}/reactions
\x12\x89\x01\n
"
+
"
\x12
UpsertMemoReaction
\x12
'.memos.api.v1.UpsertMemoReactionRequest
\x1a\x16
.memos.api.v1.Reaction
\"
2
\xda
A
\x04
name
\x82\xd3\xe4\x93\x02
%:
\x01
*
\"
/api/v1/{name=memos/*}/reactions
\x12\x8
0
\x01\n
"
+
"
\x12
UpsertMemoReaction
\x12
'.memos.api.v1.UpsertMemoReactionRequest
\x1a\x16
.memos.api.v1.Reaction
\"
2
\xda
A
\x04
name
\x82\xd3\xe4\x93\x02
%:
\x01
*
\"
/api/v1/{name=memos/*}/reactions
\x12\x8
8
\x01\n
"
+
"
\x12
DeleteMemoReaction
\x12
'.memos.api.v1.DeleteMemoReactionRequest
\x1a\x16
.google.protobuf.Empty
\"
)
\xda
A
\x04
name
\x82\xd3\xe4\x93\x02\x1c
*
\x1a
/api/v1/{name=
reactions/*}B
\xa8\x01\n
"
+
"
\x12
DeleteMemoReaction
\x12
'.memos.api.v1.DeleteMemoReactionRequest
\x1a\x16
.google.protobuf.Empty
\"
1
\xda
A
\x04
name
\x82\xd3\xe4\x93\x02
$*
\"
/api/v1/{name=memos/*/
reactions/*}B
\xa8\x01\n
"
+
"
\x10
com.memos.api.v1B
\x10
MemoServiceProtoP
\x01
Z0github.com/usememos/memos/proto/gen/api/v1;apiv1
\xa2\x02\x03
MAX
\xaa\x02\f
Memos.Api.V1
\xca\x02\f
Memos
\\
Api
\\
V1
\xe2\x02\x18
Memos
\\
Api
\\
V1
\\
GPBMetadata
\xea\x02\x0e
Memos::Api::V1b
\x06
proto3"
"
\x10
com.memos.api.v1B
\x10
MemoServiceProtoP
\x01
Z0github.com/usememos/memos/proto/gen/api/v1;apiv1
\xa2\x02\x03
MAX
\xaa\x02\f
Memos.Api.V1
\xca\x02\f
Memos
\\
Api
\\
V1
\xe2\x02\x18
Memos
\\
Api
\\
V1
\\
GPBMetadata
\xea\x02\x0e
Memos::Api::V1b
\x06
proto3"
var
(
var
(
...
...
proto/gen/api/v1/memo_service.pb.gw.go
View file @
d7284fe8
...
@@ -1001,7 +1001,7 @@ func RegisterMemoServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
...
@@ -1001,7 +1001,7 @@ func RegisterMemoServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
var
stream
runtime
.
ServerTransportStream
var
stream
runtime
.
ServerTransportStream
ctx
=
grpc
.
NewContextWithServerTransportStream
(
ctx
,
&
stream
)
ctx
=
grpc
.
NewContextWithServerTransportStream
(
ctx
,
&
stream
)
inboundMarshaler
,
outboundMarshaler
:=
runtime
.
MarshalerForRequest
(
mux
,
req
)
inboundMarshaler
,
outboundMarshaler
:=
runtime
.
MarshalerForRequest
(
mux
,
req
)
annotatedContext
,
err
:=
runtime
.
AnnotateIncomingContext
(
ctx
,
mux
,
req
,
"/memos.api.v1.MemoService/DeleteMemoReaction"
,
runtime
.
WithHTTPPathPattern
(
"/api/v1/{name=reactions/*}"
))
annotatedContext
,
err
:=
runtime
.
AnnotateIncomingContext
(
ctx
,
mux
,
req
,
"/memos.api.v1.MemoService/DeleteMemoReaction"
,
runtime
.
WithHTTPPathPattern
(
"/api/v1/{name=
memos/*/
reactions/*}"
))
if
err
!=
nil
{
if
err
!=
nil
{
runtime
.
HTTPError
(
ctx
,
mux
,
outboundMarshaler
,
w
,
req
,
err
)
runtime
.
HTTPError
(
ctx
,
mux
,
outboundMarshaler
,
w
,
req
,
err
)
return
return
...
@@ -1280,7 +1280,7 @@ func RegisterMemoServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
...
@@ -1280,7 +1280,7 @@ func RegisterMemoServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
ctx
,
cancel
:=
context
.
WithCancel
(
req
.
Context
())
ctx
,
cancel
:=
context
.
WithCancel
(
req
.
Context
())
defer
cancel
()
defer
cancel
()
inboundMarshaler
,
outboundMarshaler
:=
runtime
.
MarshalerForRequest
(
mux
,
req
)
inboundMarshaler
,
outboundMarshaler
:=
runtime
.
MarshalerForRequest
(
mux
,
req
)
annotatedContext
,
err
:=
runtime
.
AnnotateContext
(
ctx
,
mux
,
req
,
"/memos.api.v1.MemoService/DeleteMemoReaction"
,
runtime
.
WithHTTPPathPattern
(
"/api/v1/{name=reactions/*}"
))
annotatedContext
,
err
:=
runtime
.
AnnotateContext
(
ctx
,
mux
,
req
,
"/memos.api.v1.MemoService/DeleteMemoReaction"
,
runtime
.
WithHTTPPathPattern
(
"/api/v1/{name=
memos/*/
reactions/*}"
))
if
err
!=
nil
{
if
err
!=
nil
{
runtime
.
HTTPError
(
ctx
,
mux
,
outboundMarshaler
,
w
,
req
,
err
)
runtime
.
HTTPError
(
ctx
,
mux
,
outboundMarshaler
,
w
,
req
,
err
)
return
return
...
@@ -1310,7 +1310,7 @@ var (
...
@@ -1310,7 +1310,7 @@ var (
pattern_MemoService_ListMemoComments_0
=
runtime
.
MustPattern
(
runtime
.
NewPattern
(
1
,
[]
int
{
2
,
0
,
2
,
1
,
2
,
2
,
1
,
0
,
4
,
2
,
5
,
3
,
2
,
4
},
[]
string
{
"api"
,
"v1"
,
"memos"
,
"name"
,
"comments"
},
""
))
pattern_MemoService_ListMemoComments_0
=
runtime
.
MustPattern
(
runtime
.
NewPattern
(
1
,
[]
int
{
2
,
0
,
2
,
1
,
2
,
2
,
1
,
0
,
4
,
2
,
5
,
3
,
2
,
4
},
[]
string
{
"api"
,
"v1"
,
"memos"
,
"name"
,
"comments"
},
""
))
pattern_MemoService_ListMemoReactions_0
=
runtime
.
MustPattern
(
runtime
.
NewPattern
(
1
,
[]
int
{
2
,
0
,
2
,
1
,
2
,
2
,
1
,
0
,
4
,
2
,
5
,
3
,
2
,
4
},
[]
string
{
"api"
,
"v1"
,
"memos"
,
"name"
,
"reactions"
},
""
))
pattern_MemoService_ListMemoReactions_0
=
runtime
.
MustPattern
(
runtime
.
NewPattern
(
1
,
[]
int
{
2
,
0
,
2
,
1
,
2
,
2
,
1
,
0
,
4
,
2
,
5
,
3
,
2
,
4
},
[]
string
{
"api"
,
"v1"
,
"memos"
,
"name"
,
"reactions"
},
""
))
pattern_MemoService_UpsertMemoReaction_0
=
runtime
.
MustPattern
(
runtime
.
NewPattern
(
1
,
[]
int
{
2
,
0
,
2
,
1
,
2
,
2
,
1
,
0
,
4
,
2
,
5
,
3
,
2
,
4
},
[]
string
{
"api"
,
"v1"
,
"memos"
,
"name"
,
"reactions"
},
""
))
pattern_MemoService_UpsertMemoReaction_0
=
runtime
.
MustPattern
(
runtime
.
NewPattern
(
1
,
[]
int
{
2
,
0
,
2
,
1
,
2
,
2
,
1
,
0
,
4
,
2
,
5
,
3
,
2
,
4
},
[]
string
{
"api"
,
"v1"
,
"memos"
,
"name"
,
"reactions"
},
""
))
pattern_MemoService_DeleteMemoReaction_0
=
runtime
.
MustPattern
(
runtime
.
NewPattern
(
1
,
[]
int
{
2
,
0
,
2
,
1
,
2
,
2
,
1
,
0
,
4
,
2
,
5
,
3
},
[]
string
{
"api"
,
"v1
"
,
"reactions"
,
"name"
},
""
))
pattern_MemoService_DeleteMemoReaction_0
=
runtime
.
MustPattern
(
runtime
.
NewPattern
(
1
,
[]
int
{
2
,
0
,
2
,
1
,
2
,
2
,
1
,
0
,
2
,
3
,
1
,
0
,
4
,
4
,
5
,
4
},
[]
string
{
"api"
,
"v1"
,
"memos
"
,
"reactions"
,
"name"
},
""
))
)
)
var
(
var
(
...
...
proto/gen/openapi.yaml
View file @
d7284fe8
...
@@ -960,6 +960,35 @@ paths:
...
@@ -960,6 +960,35 @@ paths:
application/json
:
application/json
:
schema
:
schema
:
$ref
:
'
#/components/schemas/Status'
$ref
:
'
#/components/schemas/Status'
/api/v1/memos/{memo}/reactions/{reaction}
:
delete
:
tags
:
-
MemoService
description
:
DeleteMemoReaction deletes a reaction for a memo.
operationId
:
MemoService_DeleteMemoReaction
parameters
:
-
name
:
memo
in
:
path
description
:
The memo id.
required
:
true
schema
:
type
:
string
-
name
:
reaction
in
:
path
description
:
The reaction id.
required
:
true
schema
:
type
:
string
responses
:
"
200"
:
description
:
OK
content
:
{}
default
:
description
:
Default error response
content
:
application/json
:
schema
:
$ref
:
'
#/components/schemas/Status'
/api/v1/memos/{memo}/relations
:
/api/v1/memos/{memo}/relations
:
get
:
get
:
tags
:
tags
:
...
@@ -1025,29 +1054,6 @@ paths:
...
@@ -1025,29 +1054,6 @@ paths:
application/json
:
application/json
:
schema
:
schema
:
$ref
:
'
#/components/schemas/Status'
$ref
:
'
#/components/schemas/Status'
/api/v1/reactions/{reaction}
:
delete
:
tags
:
-
MemoService
description
:
DeleteMemoReaction deletes a reaction for a memo.
operationId
:
MemoService_DeleteMemoReaction
parameters
:
-
name
:
reaction
in
:
path
description
:
The reaction id.
required
:
true
schema
:
type
:
string
responses
:
"
200"
:
description
:
OK
content
:
{}
default
:
description
:
Default error response
content
:
application/json
:
schema
:
$ref
:
'
#/components/schemas/Status'
/api/v1/users
:
/api/v1/users
:
get
:
get
:
tags
:
tags
:
...
@@ -2640,7 +2646,7 @@ components:
...
@@ -2640,7 +2646,7 @@ components:
type
:
string
type
:
string
description
:
|-
description
:
|-
The resource name of the reaction.
The resource name of the reaction.
Format: reactions/{reaction}
Format:
memos/{memo}/
reactions/{reaction}
creator
:
creator
:
readOnly
:
true
readOnly
:
true
type
:
string
type
:
string
...
...
server/router/api/v1/reaction_service.go
View file @
d7284fe8
...
@@ -63,7 +63,7 @@ func (s *APIV1Service) DeleteMemoReaction(ctx context.Context, request *v1pb.Del
...
@@ -63,7 +63,7 @@ func (s *APIV1Service) DeleteMemoReaction(ctx context.Context, request *v1pb.Del
return
nil
,
status
.
Errorf
(
codes
.
Unauthenticated
,
"user not authenticated"
)
return
nil
,
status
.
Errorf
(
codes
.
Unauthenticated
,
"user not authenticated"
)
}
}
reactionID
,
err
:=
Extract
ReactionIDFromName
(
request
.
Name
)
_
,
reactionID
,
err
:=
ExtractMemo
ReactionIDFromName
(
request
.
Name
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"invalid reaction name: %v"
,
err
)
return
nil
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"invalid reaction name: %v"
,
err
)
}
}
...
@@ -95,8 +95,10 @@ func (s *APIV1Service) DeleteMemoReaction(ctx context.Context, request *v1pb.Del
...
@@ -95,8 +95,10 @@ func (s *APIV1Service) DeleteMemoReaction(ctx context.Context, request *v1pb.Del
func
convertReactionFromStore
(
reaction
*
store
.
Reaction
)
*
v1pb
.
Reaction
{
func
convertReactionFromStore
(
reaction
*
store
.
Reaction
)
*
v1pb
.
Reaction
{
reactionUID
:=
fmt
.
Sprintf
(
"%d"
,
reaction
.
ID
)
reactionUID
:=
fmt
.
Sprintf
(
"%d"
,
reaction
.
ID
)
// Generate nested resource name: memos/{memo}/reactions/{reaction}
// reaction.ContentID already contains "memos/{memo}"
return
&
v1pb
.
Reaction
{
return
&
v1pb
.
Reaction
{
Name
:
fmt
.
Sprintf
(
"%s
%s"
,
ReactionNamePrefix
,
reactionUID
),
Name
:
fmt
.
Sprintf
(
"%s
/%s%s"
,
reaction
.
ContentID
,
ReactionNamePrefix
,
reactionUID
),
Creator
:
fmt
.
Sprintf
(
"%s%d"
,
UserNamePrefix
,
reaction
.
CreatorID
),
Creator
:
fmt
.
Sprintf
(
"%s%d"
,
UserNamePrefix
,
reaction
.
CreatorID
),
ContentId
:
reaction
.
ContentID
,
ContentId
:
reaction
.
ContentID
,
ReactionType
:
reaction
.
ReactionType
,
ReactionType
:
reaction
.
ReactionType
,
...
...
server/router/api/v1/resource_name.go
View file @
d7284fe8
...
@@ -105,18 +105,19 @@ func ExtractAttachmentUIDFromName(name string) (string, error) {
...
@@ -105,18 +105,19 @@ func ExtractAttachmentUIDFromName(name string) (string, error) {
return
id
,
nil
return
id
,
nil
}
}
// Extract
ReactionIDFromName returns the
reaction ID from a resource name.
// Extract
MemoReactionIDFromName returns the memo UID and
reaction ID from a resource name.
// e.g., "
reactions/123" -> 123
.
// e.g., "
memos/abc/reactions/123" -> ("abc", 123)
.
func
Extract
ReactionIDFromName
(
name
string
)
(
int32
,
error
)
{
func
Extract
MemoReactionIDFromName
(
name
string
)
(
string
,
int32
,
error
)
{
tokens
,
err
:=
GetNameParentTokens
(
name
,
ReactionNamePrefix
)
tokens
,
err
:=
GetNameParentTokens
(
name
,
MemoNamePrefix
,
ReactionNamePrefix
)
if
err
!=
nil
{
if
err
!=
nil
{
return
0
,
err
return
""
,
0
,
err
}
}
id
,
err
:=
util
.
ConvertStringToInt32
(
tokens
[
0
])
memoUID
:=
tokens
[
0
]
reactionID
,
err
:=
util
.
ConvertStringToInt32
(
tokens
[
1
])
if
err
!=
nil
{
if
err
!=
nil
{
return
0
,
errors
.
Errorf
(
"invalid reaction ID %q"
,
tokens
[
0
])
return
""
,
0
,
errors
.
Errorf
(
"invalid reaction ID %q"
,
tokens
[
1
])
}
}
return
id
,
nil
return
memoUID
,
reactionID
,
nil
}
}
// ExtractInboxIDFromName returns the inbox ID from a resource name.
// ExtractInboxIDFromName returns the inbox ID from a resource name.
...
...
server/router/api/v1/test/reaction_service_test.go
View file @
d7284fe8
...
@@ -183,8 +183,9 @@ func TestDeleteMemoReaction(t *testing.T) {
...
@@ -183,8 +183,9 @@ func TestDeleteMemoReaction(t *testing.T) {
// Try to delete non-existent reaction - should fail with permission denied
// Try to delete non-existent reaction - should fail with permission denied
// (not "not found" to avoid information disclosure)
// (not "not found" to avoid information disclosure)
// Use new nested resource format: memos/{memo}/reactions/{reaction}
_
,
err
=
ts
.
Service
.
DeleteMemoReaction
(
userCtx
,
&
apiv1
.
DeleteMemoReactionRequest
{
_
,
err
=
ts
.
Service
.
DeleteMemoReaction
(
userCtx
,
&
apiv1
.
DeleteMemoReactionRequest
{
Name
:
"reactions/99999"
,
Name
:
"
memos/nonexistent/
reactions/99999"
,
})
})
require
.
Error
(
t
,
err
)
require
.
Error
(
t
,
err
)
require
.
Contains
(
t
,
err
.
Error
(),
"permission denied"
)
require
.
Contains
(
t
,
err
.
Error
(),
"permission denied"
)
...
...
web/src/types/proto/api/v1/memo_service_pb.ts
View file @
d7284fe8
...
@@ -20,7 +20,7 @@ import type { Message } from "@bufbuild/protobuf";
...
@@ -20,7 +20,7 @@ import type { Message } from "@bufbuild/protobuf";
* Describes the file api/v1/memo_service.proto.
* Describes the file api/v1/memo_service.proto.
*/
*/
export
const
file_api_v1_memo_service
:
GenFile
=
/*@__PURE__*/
export
const
file_api_v1_memo_service
:
GenFile
=
/*@__PURE__*/
fileDesc
(
"ChlhcGkvdjEvbWVtb19zZXJ2aWNlLnByb3RvEgxtZW1vcy5hcGkudjEi
mgIKCFJlYWN0aW9uEhQKBG5hbWUYASABKAlCBuBBA+BBCBIqCgdjcmVhdG9yGAIgASgJQhngQQP6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEi0KCmNvbnRlbnRfaWQYAyABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SGgoNcmVhY3Rpb25fdHlwZRgEIAEoCUID4EECEjQKC2NyZWF0ZV90aW1lGAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEDOkvqQUgKFW1lbW9zLmFwaS52MS9SZWFjdGlvbhIUcmVhY3Rpb25zL3tyZWFjdGlvbn0aBG5hbWUqCXJlYWN0aW9uczIIcmVhY3Rpb24i/gYKBE1lbW8SEQoEbmFtZRgBIAEoCUID4EEIEicKBXN0YXRlGAIgASgOMhMubWVtb3MuYXBpLnYxLlN0YXRlQgPgQQISKgoHY3JlYXRvchgDIAEoCUIZ4EED+kETChFtZW1vcy5hcGkudjEvVXNlchI0CgtjcmVhdGVfdGltZRgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAxI0Cgt1cGRhdGVfdGltZRgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAxI1CgxkaXNwbGF5X3RpbWUYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQESFAoHY29udGVudBgHIAEoCUID4EECEjEKCnZpc2liaWxpdHkYCSABKA4yGC5tZW1vcy5hcGkudjEuVmlzaWJpbGl0eUID4EECEhEKBHRhZ3MYCiADKAlCA+BBAxITCgZwaW5uZWQYCyABKAhCA+BBARIyCgthdHRhY2htZW50cxgMIAMoCzIYLm1lbW9zLmFwaS52MS5BdHRhY2htZW50QgPgQQESMgoJcmVsYXRpb25zGA0gAygLMhoubWVtb3MuYXBpLnYxLk1lbW9SZWxhdGlvbkID4EEBEi4KCXJlYWN0aW9ucxgOIAMoCzIWLm1lbW9zLmFwaS52MS5SZWFjdGlvbkID4EEDEjIKCHByb3BlcnR5GA8gASgLMhsubWVtb3MuYXBpLnYxLk1lbW8uUHJvcGVydHlCA+BBAxIuCgZwYXJlbnQYECABKAlCGeBBA/pBEwoRbWVtb3MuYXBpLnYxL01lbW9IAIgBARIUCgdzbmlwcGV0GBEgASgJQgPgQQMSMgoIbG9jYXRpb24YEiABKAsyFi5tZW1vcy5hcGkudjEuTG9jYXRpb25CA+BBAUgBiAEBGmMKCFByb3BlcnR5EhAKCGhhc19saW5rGAEgASgIEhUKDWhhc190YXNrX2xpc3QYAiABKAgSEAoIaGFzX2NvZGUYAyABKAgSHAoUaGFzX2luY29tcGxldGVfdGFza3MYBCABKAg6N+pBNAoRbWVtb3MuYXBpLnYxL01lbW8SDG1lbW9zL3ttZW1vfRoEbmFtZSoFbWVtb3MyBG1lbW9CCQoHX3BhcmVudEILCglfbG9jYXRpb24iUwoITG9jYXRpb24SGAoLcGxhY2Vob2xkZXIYASABKAlCA+BBARIVCghsYXRpdHVkZRgCIAEoAUID4EEBEhYKCWxvbmdpdHVkZRgDIAEoAUID4EEBIlAKEUNyZWF0ZU1lbW9SZXF1ZXN0EiUKBG1lbW8YASABKAsyEi5tZW1vcy5hcGkudjEuTWVtb0ID4EECEhQKB21lbW9faWQYAiABKAlCA+BBASKzAQoQTGlzdE1lbW9zUmVxdWVzdBIWCglwYWdlX3NpemUYASABKAVCA+BBARIXCgpwYWdlX3Rva2VuGAIgASgJQgPgQQESJwoFc3RhdGUYAyABKA4yEy5tZW1vcy5hcGkudjEuU3RhdGVCA+BBARIVCghvcmRlcl9ieRgEIAEoCUID4EEBEhMKBmZpbHRlchgFIAEoCUID4EEBEhkKDHNob3dfZGVsZXRlZBgGIAEoCEID4EEBIk8KEUxpc3RNZW1vc1Jlc3BvbnNlEiEKBW1lbW9zGAEgAygLMhIubWVtb3MuYXBpLnYxLk1lbW8SFwoPbmV4dF9wYWdlX3Rva2VuGAIgASgJIjkKDkdldE1lbW9SZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8icAoRVXBkYXRlTWVtb1JlcXVlc3QSJQoEbWVtbxgBIAEoCzISLm1lbW9zLmFwaS52MS5NZW1vQgPgQQISNAoLdXBkYXRlX21hc2sYAiABKAsyGi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrQgPgQQIiUAoRRGVsZXRlTWVtb1JlcXVlc3QSJwoEbmFtZRgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvTWVtbxISCgVmb3JjZRgCIAEoCEID4EEBIngKGVNldE1lbW9BdHRhY2htZW50c1JlcXVlc3QSJwoEbmFtZRgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvTWVtbxIyCgthdHRhY2htZW50cxgCIAMoCzIYLm1lbW9zLmFwaS52MS5BdHRhY2htZW50QgPgQQIidgoaTGlzdE1lbW9BdHRhY2htZW50c1JlcXVlc3QSJwoEbmFtZRgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvTWVtbxIWCglwYWdlX3NpemUYAiABKAVCA+BBARIXCgpwYWdlX3Rva2VuGAMgASgJQgPgQQEiZQobTGlzdE1lbW9BdHRhY2htZW50c1Jlc3BvbnNlEi0KC2F0dGFjaG1lbnRzGAEgAygLMhgubWVtb3MuYXBpLnYxLkF0dGFjaG1lbnQSFwoPbmV4dF9wYWdlX3Rva2VuGAIgASgJIrMCCgxNZW1vUmVsYXRpb24SMgoEbWVtbxgBIAEoCzIfLm1lbW9zLmFwaS52MS5NZW1vUmVsYXRpb24uTWVtb0ID4EECEjoKDHJlbGF0ZWRfbWVtbxgCIAEoCzIfLm1lbW9zLmFwaS52MS5NZW1vUmVsYXRpb24uTWVtb0ID4EECEjIKBHR5cGUYAyABKA4yHy5tZW1vcy5hcGkudjEuTWVtb1JlbGF0aW9uLlR5cGVCA+BBAhpFCgRNZW1vEicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SFAoHc25pcHBldBgCIAEoCUID4EEDIjgKBFR5cGUSFAoQVFlQRV9VTlNQRUNJRklFRBAAEg0KCVJFRkVSRU5DRRABEgsKB0NPTU1FTlQQAiJ2ChdTZXRNZW1vUmVsYXRpb25zUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9NZW1vEjIKCXJlbGF0aW9ucxgCIAMoCzIaLm1lbW9zLmFwaS52MS5NZW1vUmVsYXRpb25CA+BBAiJ0ChhMaXN0TWVtb1JlbGF0aW9uc1JlcXVlc3QSJwoEbmFtZRgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvTWVtbxIWCglwYWdlX3NpemUYAiABKAVCA+BBARIXCgpwYWdlX3Rva2VuGAMgASgJQgPgQQEiYwoZTGlzdE1lbW9SZWxhdGlvbnNSZXNwb25zZRItCglyZWxhdGlvbnMYASADKAsyGi5tZW1vcy5hcGkudjEuTWVtb1JlbGF0aW9uEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCSKGAQoYQ3JlYXRlTWVtb0NvbW1lbnRSZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SKAoHY29tbWVudBgCIAEoCzISLm1lbW9zLmFwaS52MS5NZW1vQgPgQQISFwoKY29tbWVudF9pZBgDIAEoCUID4EEBIooBChdMaXN0TWVtb0NvbW1lbnRzUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9NZW1vEhYKCXBhZ2Vfc2l6ZRgCIAEoBUID4EEBEhcKCnBhZ2VfdG9rZW4YAyABKAlCA+BBARIVCghvcmRlcl9ieRgEIAEoCUID4EEBImoKGExpc3RNZW1vQ29tbWVudHNSZXNwb25zZRIhCgVtZW1vcxgBIAMoCzISLm1lbW9zLmFwaS52MS5NZW1vEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCRISCgp0b3RhbF9zaXplGAMgASgFInQKGExpc3RNZW1vUmVhY3Rpb25zUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9NZW1vEhYKCXBhZ2Vfc2l6ZRgCIAEoBUID4EEBEhcKCnBhZ2VfdG9rZW4YAyABKAlCA+BBASJzChlMaXN0TWVtb1JlYWN0aW9uc1Jlc3BvbnNlEikKCXJlYWN0aW9ucxgBIAMoCzIWLm1lbW9zLmFwaS52MS5SZWFjdGlvbhIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkSEgoKdG90YWxfc2l6ZRgDIAEoBSJzChlVcHNlcnRNZW1vUmVhY3Rpb25SZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SLQoIcmVhY3Rpb24YAiABKAsyFi5tZW1vcy5hcGkudjEuUmVhY3Rpb25CA+BBAiJIChlEZWxldGVNZW1vUmVhY3Rpb25SZXF1ZXN0EisKBG5hbWUYASABKAlCHeBBAvpBFwoVbWVtb3MuYXBpLnYxL1JlYWN0aW9uKlAKClZpc2liaWxpdHkSGgoWVklTSUJJTElUWV9VTlNQRUNJRklFRBAAEgsKB1BSSVZBVEUQARINCglQUk9URUNURUQQAhIKCgZQVUJMSUMQAzLLDgoLTWVtb1NlcnZpY2USZQoKQ3JlYXRlTWVtbxIfLm1lbW9zLmFwaS52MS5DcmVhdGVNZW1vUmVxdWVzdBoSLm1lbW9zLmFwaS52MS5NZW1vIiLaQQRtZW1vgtPkkwIVOgRtZW1vIg0vYXBpL3YxL21lbW9zEmYKCUxpc3RNZW1vcxIeLm1lbW9zLmFwaS52MS5MaXN0TWVtb3NSZXF1ZXN0Gh8ubWVtb3MuYXBpLnYxLkxpc3RNZW1vc1Jlc3BvbnNlIhjaQQCC0+STAg8SDS9hcGkvdjEvbWVtb3MSYgoHR2V0TWVtbxIcLm1lbW9zLmFwaS52MS5HZXRNZW1vUmVxdWVzdBoSLm1lbW9zLmFwaS52MS5NZW1vIiXaQQRuYW1lgtPkkwIYEhYvYXBpL3YxL3tuYW1lPW1lbW9zLyp9En8KClVwZGF0ZU1lbW8SHy5tZW1vcy5hcGkudjEuVXBkYXRlTWVtb1JlcXVlc3QaEi5tZW1vcy5hcGkudjEuTWVtbyI82kEQbWVtbyx1cGRhdGVfbWFza4LT5JMCIzoEbWVtbzIbL2FwaS92MS97bWVtby5uYW1lPW1lbW9zLyp9EmwKCkRlbGV0ZU1lbW8SHy5tZW1vcy5hcGkudjEuRGVsZXRlTWVtb1JlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiJdpBBG5hbWWC0+STAhgqFi9hcGkvdjEve25hbWU9bWVtb3MvKn0SiwEKElNldE1lbW9BdHRhY2htZW50cxInLm1lbW9zLmFwaS52MS5TZXRNZW1vQXR0YWNobWVudHNSZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IjTaQQRuYW1lgtPkkwInOgEqMiIvYXBpL3YxL3tuYW1lPW1lbW9zLyp9L2F0dGFjaG1lbnRzEp0BChNMaXN0TWVtb0F0dGFjaG1lbnRzEigubWVtb3MuYXBpLnYxLkxpc3RNZW1vQXR0YWNobWVudHNSZXF1ZXN0GikubWVtb3MuYXBpLnYxLkxpc3RNZW1vQXR0YWNobWVudHNSZXNwb25zZSIx2kEEbmFtZYLT5JMCJBIiL2FwaS92MS97bmFtZT1tZW1vcy8qfS9hdHRhY2htZW50cxKFAQoQU2V0TWVtb1JlbGF0aW9ucxIlLm1lbW9zLmFwaS52MS5TZXRNZW1vUmVsYXRpb25zUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIy2kEEbmFtZYLT5JMCJToBKjIgL2FwaS92MS97bmFtZT1tZW1vcy8qfS9yZWxhdGlvbnMSlQEKEUxpc3RNZW1vUmVsYXRpb25zEiYubWVtb3MuYXBpLnYxLkxpc3RNZW1vUmVsYXRpb25zUmVxdWVzdBonLm1lbW9zLmFwaS52MS5MaXN0TWVtb1JlbGF0aW9uc1Jlc3BvbnNlIi/aQQRuYW1lgtPkkwIiEiAvYXBpL3YxL3tuYW1lPW1lbW9zLyp9L3JlbGF0aW9ucxKQAQoRQ3JlYXRlTWVtb0NvbW1lbnQSJi5tZW1vcy5hcGkudjEuQ3JlYXRlTWVtb0NvbW1lbnRSZXF1ZXN0GhIubWVtb3MuYXBpLnYxLk1lbW8iP9pBDG5hbWUsY29tbWVudILT5JMCKjoHY29tbWVudCIfL2FwaS92MS97bmFtZT1tZW1vcy8qfS9jb21tZW50cxKRAQoQTGlzdE1lbW9Db21tZW50cxIlLm1lbW9zLmFwaS52MS5MaXN0TWVtb0NvbW1lbnRzUmVxdWVzdBomLm1lbW9zLmFwaS52MS5MaXN0TWVtb0NvbW1lbnRzUmVzcG9uc2UiLtpBBG5hbWWC0+STAiESHy9hcGkvdjEve25hbWU9bWVtb3MvKn0vY29tbWVudHMSlQEKEUxpc3RNZW1vUmVhY3Rpb25zEiYubWVtb3MuYXBpLnYxLkxpc3RNZW1vUmVhY3Rpb25zUmVxdWVzdBonLm1lbW9zLmFwaS52MS5MaXN0TWVtb1JlYWN0aW9uc1Jlc3BvbnNlIi/aQQRuYW1lgtPkkwIiEiAvYXBpL3YxL3tuYW1lPW1lbW9zLyp9L3JlYWN0aW9ucxKJAQoSVXBzZXJ0TWVtb1JlYWN0aW9uEicubWVtb3MuYXBpLnYxLlVwc2VydE1lbW9SZWFjdGlvblJlcXVlc3QaFi5tZW1vcy5hcGkudjEuUmVhY3Rpb24iMtpBBG5hbWWC0+STAiU6ASoiIC9hcGkvdjEve25hbWU9bWVtb3MvKn0vcmVhY3Rpb25zEoABChJEZWxldGVNZW1vUmVhY3Rpb24SJy5tZW1vcy5hcGkudjEuRGVsZXRlTWVtb1JlYWN0aW9uUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIp2kEEbmFtZYLT5JMCHCoaL2FwaS92MS97bmFtZT1
yZWFjdGlvbnMvKn1CqAEKEGNvbS5tZW1vcy5hcGkudjFCEE1lbW9TZXJ2aWNlUHJvdG9QAVowZ2l0aHViLmNvbS91c2VtZW1vcy9tZW1vcy9wcm90by9nZW4vYXBpL3YxO2FwaXYxogIDTUFYqgIMTWVtb3MuQXBpLlYxygIMTWVtb3NcQXBpXFYx4gIYTWVtb3NcQXBpXFYxXEdQQk1ldGFkYXRh6gIOTWVtb3M6OkFwaTo6VjFiBnByb3RvMw"
,
[
file_api_v1_attachment_service
,
file_api_v1_common
,
file_google_api_annotations
,
file_google_api_client
,
file_google_api_field_behavior
,
file_google_api_resource
,
file_google_protobuf_empty
,
file_google_protobuf_field_mask
,
file_google_protobuf_timestamp
]);
fileDesc
(
"ChlhcGkvdjEvbWVtb19zZXJ2aWNlLnByb3RvEgxtZW1vcy5hcGkudjEi
pwIKCFJlYWN0aW9uEhQKBG5hbWUYASABKAlCBuBBA+BBCBIqCgdjcmVhdG9yGAIgASgJQhngQQP6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEi0KCmNvbnRlbnRfaWQYAyABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SGgoNcmVhY3Rpb25fdHlwZRgEIAEoCUID4EECEjQKC2NyZWF0ZV90aW1lGAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEDOljqQVUKFW1lbW9zLmFwaS52MS9SZWFjdGlvbhIhbWVtb3Mve21lbW99L3JlYWN0aW9ucy97cmVhY3Rpb259GgRuYW1lKglyZWFjdGlvbnMyCHJlYWN0aW9uIv4GCgRNZW1vEhEKBG5hbWUYASABKAlCA+BBCBInCgVzdGF0ZRgCIAEoDjITLm1lbW9zLmFwaS52MS5TdGF0ZUID4EECEioKB2NyZWF0b3IYAyABKAlCGeBBA/pBEwoRbWVtb3MuYXBpLnYxL1VzZXISNAoLY3JlYXRlX3RpbWUYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQMSNAoLdXBkYXRlX3RpbWUYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQMSNQoMZGlzcGxheV90aW1lGAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEBEhQKB2NvbnRlbnQYByABKAlCA+BBAhIxCgp2aXNpYmlsaXR5GAkgASgOMhgubWVtb3MuYXBpLnYxLlZpc2liaWxpdHlCA+BBAhIRCgR0YWdzGAogAygJQgPgQQMSEwoGcGlubmVkGAsgASgIQgPgQQESMgoLYXR0YWNobWVudHMYDCADKAsyGC5tZW1vcy5hcGkudjEuQXR0YWNobWVudEID4EEBEjIKCXJlbGF0aW9ucxgNIAMoCzIaLm1lbW9zLmFwaS52MS5NZW1vUmVsYXRpb25CA+BBARIuCglyZWFjdGlvbnMYDiADKAsyFi5tZW1vcy5hcGkudjEuUmVhY3Rpb25CA+BBAxIyCghwcm9wZXJ0eRgPIAEoCzIbLm1lbW9zLmFwaS52MS5NZW1vLlByb3BlcnR5QgPgQQMSLgoGcGFyZW50GBAgASgJQhngQQP6QRMKEW1lbW9zLmFwaS52MS9NZW1vSACIAQESFAoHc25pcHBldBgRIAEoCUID4EEDEjIKCGxvY2F0aW9uGBIgASgLMhYubWVtb3MuYXBpLnYxLkxvY2F0aW9uQgPgQQFIAYgBARpjCghQcm9wZXJ0eRIQCghoYXNfbGluaxgBIAEoCBIVCg1oYXNfdGFza19saXN0GAIgASgIEhAKCGhhc19jb2RlGAMgASgIEhwKFGhhc19pbmNvbXBsZXRlX3Rhc2tzGAQgASgIOjfqQTQKEW1lbW9zLmFwaS52MS9NZW1vEgxtZW1vcy97bWVtb30aBG5hbWUqBW1lbW9zMgRtZW1vQgkKB19wYXJlbnRCCwoJX2xvY2F0aW9uIlMKCExvY2F0aW9uEhgKC3BsYWNlaG9sZGVyGAEgASgJQgPgQQESFQoIbGF0aXR1ZGUYAiABKAFCA+BBARIWCglsb25naXR1ZGUYAyABKAFCA+BBASJQChFDcmVhdGVNZW1vUmVxdWVzdBIlCgRtZW1vGAEgASgLMhIubWVtb3MuYXBpLnYxLk1lbW9CA+BBAhIUCgdtZW1vX2lkGAIgASgJQgPgQQEiswEKEExpc3RNZW1vc1JlcXVlc3QSFgoJcGFnZV9zaXplGAEgASgFQgPgQQESFwoKcGFnZV90b2tlbhgCIAEoCUID4EEBEicKBXN0YXRlGAMgASgOMhMubWVtb3MuYXBpLnYxLlN0YXRlQgPgQQESFQoIb3JkZXJfYnkYBCABKAlCA+BBARITCgZmaWx0ZXIYBSABKAlCA+BBARIZCgxzaG93X2RlbGV0ZWQYBiABKAhCA+BBASJPChFMaXN0TWVtb3NSZXNwb25zZRIhCgVtZW1vcxgBIAMoCzISLm1lbW9zLmFwaS52MS5NZW1vEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCSI5Cg5HZXRNZW1vUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9NZW1vInAKEVVwZGF0ZU1lbW9SZXF1ZXN0EiUKBG1lbW8YASABKAsyEi5tZW1vcy5hcGkudjEuTWVtb0ID4EECEjQKC3VwZGF0ZV9tYXNrGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza0ID4EECIlAKEURlbGV0ZU1lbW9SZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SEgoFZm9yY2UYAiABKAhCA+BBASJ4ChlTZXRNZW1vQXR0YWNobWVudHNSZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SMgoLYXR0YWNobWVudHMYAiADKAsyGC5tZW1vcy5hcGkudjEuQXR0YWNobWVudEID4EECInYKGkxpc3RNZW1vQXR0YWNobWVudHNSZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SFgoJcGFnZV9zaXplGAIgASgFQgPgQQESFwoKcGFnZV90b2tlbhgDIAEoCUID4EEBImUKG0xpc3RNZW1vQXR0YWNobWVudHNSZXNwb25zZRItCgthdHRhY2htZW50cxgBIAMoCzIYLm1lbW9zLmFwaS52MS5BdHRhY2htZW50EhcKD25leHRfcGFnZV90b2tlbhgCIAEoCSKzAgoMTWVtb1JlbGF0aW9uEjIKBG1lbW8YASABKAsyHy5tZW1vcy5hcGkudjEuTWVtb1JlbGF0aW9uLk1lbW9CA+BBAhI6CgxyZWxhdGVkX21lbW8YAiABKAsyHy5tZW1vcy5hcGkudjEuTWVtb1JlbGF0aW9uLk1lbW9CA+BBAhIyCgR0eXBlGAMgASgOMh8ubWVtb3MuYXBpLnYxLk1lbW9SZWxhdGlvbi5UeXBlQgPgQQIaRQoETWVtbxInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9NZW1vEhQKB3NuaXBwZXQYAiABKAlCA+BBAyI4CgRUeXBlEhQKEFRZUEVfVU5TUEVDSUZJRUQQABINCglSRUZFUkVOQ0UQARILCgdDT01NRU5UEAIidgoXU2V0TWVtb1JlbGF0aW9uc1JlcXVlc3QSJwoEbmFtZRgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvTWVtbxIyCglyZWxhdGlvbnMYAiADKAsyGi5tZW1vcy5hcGkudjEuTWVtb1JlbGF0aW9uQgPgQQIidAoYTGlzdE1lbW9SZWxhdGlvbnNSZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SFgoJcGFnZV9zaXplGAIgASgFQgPgQQESFwoKcGFnZV90b2tlbhgDIAEoCUID4EEBImMKGUxpc3RNZW1vUmVsYXRpb25zUmVzcG9uc2USLQoJcmVsYXRpb25zGAEgAygLMhoubWVtb3MuYXBpLnYxLk1lbW9SZWxhdGlvbhIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkihgEKGENyZWF0ZU1lbW9Db21tZW50UmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9NZW1vEigKB2NvbW1lbnQYAiABKAsyEi5tZW1vcy5hcGkudjEuTWVtb0ID4EECEhcKCmNvbW1lbnRfaWQYAyABKAlCA+BBASKKAQoXTGlzdE1lbW9Db21tZW50c1JlcXVlc3QSJwoEbmFtZRgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvTWVtbxIWCglwYWdlX3NpemUYAiABKAVCA+BBARIXCgpwYWdlX3Rva2VuGAMgASgJQgPgQQESFQoIb3JkZXJfYnkYBCABKAlCA+BBASJqChhMaXN0TWVtb0NvbW1lbnRzUmVzcG9uc2USIQoFbWVtb3MYASADKAsyEi5tZW1vcy5hcGkudjEuTWVtbxIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkSEgoKdG90YWxfc2l6ZRgDIAEoBSJ0ChhMaXN0TWVtb1JlYWN0aW9uc1JlcXVlc3QSJwoEbmFtZRgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvTWVtbxIWCglwYWdlX3NpemUYAiABKAVCA+BBARIXCgpwYWdlX3Rva2VuGAMgASgJQgPgQQEicwoZTGlzdE1lbW9SZWFjdGlvbnNSZXNwb25zZRIpCglyZWFjdGlvbnMYASADKAsyFi5tZW1vcy5hcGkudjEuUmVhY3Rpb24SFwoPbmV4dF9wYWdlX3Rva2VuGAIgASgJEhIKCnRvdGFsX3NpemUYAyABKAUicwoZVXBzZXJ0TWVtb1JlYWN0aW9uUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9NZW1vEi0KCHJlYWN0aW9uGAIgASgLMhYubWVtb3MuYXBpLnYxLlJlYWN0aW9uQgPgQQIiSAoZRGVsZXRlTWVtb1JlYWN0aW9uUmVxdWVzdBIrCgRuYW1lGAEgASgJQh3gQQL6QRcKFW1lbW9zLmFwaS52MS9SZWFjdGlvbipQCgpWaXNpYmlsaXR5EhoKFlZJU0lCSUxJVFlfVU5TUEVDSUZJRUQQABILCgdQUklWQVRFEAESDQoJUFJPVEVDVEVEEAISCgoGUFVCTElDEAMy0w4KC01lbW9TZXJ2aWNlEmUKCkNyZWF0ZU1lbW8SHy5tZW1vcy5hcGkudjEuQ3JlYXRlTWVtb1JlcXVlc3QaEi5tZW1vcy5hcGkudjEuTWVtbyIi2kEEbWVtb4LT5JMCFToEbWVtbyINL2FwaS92MS9tZW1vcxJmCglMaXN0TWVtb3MSHi5tZW1vcy5hcGkudjEuTGlzdE1lbW9zUmVxdWVzdBofLm1lbW9zLmFwaS52MS5MaXN0TWVtb3NSZXNwb25zZSIY2kEAgtPkkwIPEg0vYXBpL3YxL21lbW9zEmIKB0dldE1lbW8SHC5tZW1vcy5hcGkudjEuR2V0TWVtb1JlcXVlc3QaEi5tZW1vcy5hcGkudjEuTWVtbyIl2kEEbmFtZYLT5JMCGBIWL2FwaS92MS97bmFtZT1tZW1vcy8qfRJ/CgpVcGRhdGVNZW1vEh8ubWVtb3MuYXBpLnYxLlVwZGF0ZU1lbW9SZXF1ZXN0GhIubWVtb3MuYXBpLnYxLk1lbW8iPNpBEG1lbW8sdXBkYXRlX21hc2uC0+STAiM6BG1lbW8yGy9hcGkvdjEve21lbW8ubmFtZT1tZW1vcy8qfRJsCgpEZWxldGVNZW1vEh8ubWVtb3MuYXBpLnYxLkRlbGV0ZU1lbW9SZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IiXaQQRuYW1lgtPkkwIYKhYvYXBpL3YxL3tuYW1lPW1lbW9zLyp9EosBChJTZXRNZW1vQXR0YWNobWVudHMSJy5tZW1vcy5hcGkudjEuU2V0TWVtb0F0dGFjaG1lbnRzUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSI02kEEbmFtZYLT5JMCJzoBKjIiL2FwaS92MS97bmFtZT1tZW1vcy8qfS9hdHRhY2htZW50cxKdAQoTTGlzdE1lbW9BdHRhY2htZW50cxIoLm1lbW9zLmFwaS52MS5MaXN0TWVtb0F0dGFjaG1lbnRzUmVxdWVzdBopLm1lbW9zLmFwaS52MS5MaXN0TWVtb0F0dGFjaG1lbnRzUmVzcG9uc2UiMdpBBG5hbWWC0+STAiQSIi9hcGkvdjEve25hbWU9bWVtb3MvKn0vYXR0YWNobWVudHMShQEKEFNldE1lbW9SZWxhdGlvbnMSJS5tZW1vcy5hcGkudjEuU2V0TWVtb1JlbGF0aW9uc1JlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiMtpBBG5hbWWC0+STAiU6ASoyIC9hcGkvdjEve25hbWU9bWVtb3MvKn0vcmVsYXRpb25zEpUBChFMaXN0TWVtb1JlbGF0aW9ucxImLm1lbW9zLmFwaS52MS5MaXN0TWVtb1JlbGF0aW9uc1JlcXVlc3QaJy5tZW1vcy5hcGkudjEuTGlzdE1lbW9SZWxhdGlvbnNSZXNwb25zZSIv2kEEbmFtZYLT5JMCIhIgL2FwaS92MS97bmFtZT1tZW1vcy8qfS9yZWxhdGlvbnMSkAEKEUNyZWF0ZU1lbW9Db21tZW50EiYubWVtb3MuYXBpLnYxLkNyZWF0ZU1lbW9Db21tZW50UmVxdWVzdBoSLm1lbW9zLmFwaS52MS5NZW1vIj/aQQxuYW1lLGNvbW1lbnSC0+STAio6B2NvbW1lbnQiHy9hcGkvdjEve25hbWU9bWVtb3MvKn0vY29tbWVudHMSkQEKEExpc3RNZW1vQ29tbWVudHMSJS5tZW1vcy5hcGkudjEuTGlzdE1lbW9Db21tZW50c1JlcXVlc3QaJi5tZW1vcy5hcGkudjEuTGlzdE1lbW9Db21tZW50c1Jlc3BvbnNlIi7aQQRuYW1lgtPkkwIhEh8vYXBpL3YxL3tuYW1lPW1lbW9zLyp9L2NvbW1lbnRzEpUBChFMaXN0TWVtb1JlYWN0aW9ucxImLm1lbW9zLmFwaS52MS5MaXN0TWVtb1JlYWN0aW9uc1JlcXVlc3QaJy5tZW1vcy5hcGkudjEuTGlzdE1lbW9SZWFjdGlvbnNSZXNwb25zZSIv2kEEbmFtZYLT5JMCIhIgL2FwaS92MS97bmFtZT1tZW1vcy8qfS9yZWFjdGlvbnMSiQEKElVwc2VydE1lbW9SZWFjdGlvbhInLm1lbW9zLmFwaS52MS5VcHNlcnRNZW1vUmVhY3Rpb25SZXF1ZXN0GhYubWVtb3MuYXBpLnYxLlJlYWN0aW9uIjLaQQRuYW1lgtPkkwIlOgEqIiAvYXBpL3YxL3tuYW1lPW1lbW9zLyp9L3JlYWN0aW9ucxKIAQoSRGVsZXRlTWVtb1JlYWN0aW9uEicubWVtb3MuYXBpLnYxLkRlbGV0ZU1lbW9SZWFjdGlvblJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiMdpBBG5hbWWC0+STAiQqIi9hcGkvdjEve25hbWU9bWVtb3MvKi9
yZWFjdGlvbnMvKn1CqAEKEGNvbS5tZW1vcy5hcGkudjFCEE1lbW9TZXJ2aWNlUHJvdG9QAVowZ2l0aHViLmNvbS91c2VtZW1vcy9tZW1vcy9wcm90by9nZW4vYXBpL3YxO2FwaXYxogIDTUFYqgIMTWVtb3MuQXBpLlYxygIMTWVtb3NcQXBpXFYx4gIYTWVtb3NcQXBpXFYxXEdQQk1ldGFkYXRh6gIOTWVtb3M6OkFwaTo6VjFiBnByb3RvMw"
,
[
file_api_v1_attachment_service
,
file_api_v1_common
,
file_google_api_annotations
,
file_google_api_client
,
file_google_api_field_behavior
,
file_google_api_resource
,
file_google_protobuf_empty
,
file_google_protobuf_field_mask
,
file_google_protobuf_timestamp
]);
/**
/**
* @generated from message memos.api.v1.Reaction
* @generated from message memos.api.v1.Reaction
...
@@ -28,7 +28,7 @@ export const file_api_v1_memo_service: GenFile = /*@__PURE__*/
...
@@ -28,7 +28,7 @@ export const file_api_v1_memo_service: GenFile = /*@__PURE__*/
export
type
Reaction
=
Message
<
"memos.api.v1.Reaction"
>
&
{
export
type
Reaction
=
Message
<
"memos.api.v1.Reaction"
>
&
{
/**
/**
* The resource name of the reaction.
* The resource name of the reaction.
* Format: reactions/{reaction}
* Format:
memos/{memo}/
reactions/{reaction}
*
*
* @generated from field: string name = 1;
* @generated from field: string name = 1;
*/
*/
...
@@ -937,7 +937,7 @@ export const UpsertMemoReactionRequestSchema: GenMessage<UpsertMemoReactionReque
...
@@ -937,7 +937,7 @@ export const UpsertMemoReactionRequestSchema: GenMessage<UpsertMemoReactionReque
export
type
DeleteMemoReactionRequest
=
Message
<
"memos.api.v1.DeleteMemoReactionRequest"
>
&
{
export
type
DeleteMemoReactionRequest
=
Message
<
"memos.api.v1.DeleteMemoReactionRequest"
>
&
{
/**
/**
* Required. The resource name of the reaction to delete.
* Required. The resource name of the reaction to delete.
* Format: reactions/{reaction}
* Format:
memos/{memo}/
reactions/{reaction}
*
*
* @generated from field: string name = 1;
* @generated from field: string name = 1;
*/
*/
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment