refactor: attachment service

pull/4778/head
Steven 2 weeks ago
parent 174b1a0361
commit bb5809cae4

@ -0,0 +1,173 @@
syntax = "proto3";
package memos.api.v1;
import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/httpbody.proto";
import "google/api/resource.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";
option go_package = "gen/api/v1";
service AttachmentService {
// CreateAttachment creates a new attachment.
rpc CreateAttachment(CreateAttachmentRequest) returns (Attachment) {
option (google.api.http) = {
post: "/api/v1/attachments"
body: "attachment"
};
option (google.api.method_signature) = "attachment";
}
// ListAttachments lists all attachments.
rpc ListAttachments(ListAttachmentsRequest) returns (ListAttachmentsResponse) {
option (google.api.http) = {get: "/api/v1/attachments"};
}
// GetAttachment returns a attachment by name.
rpc GetAttachment(GetAttachmentRequest) returns (Attachment) {
option (google.api.http) = {get: "/api/v1/{name=attachments/*}"};
option (google.api.method_signature) = "name";
}
// GetAttachmentBinary returns a attachment binary by name.
rpc GetAttachmentBinary(GetAttachmentBinaryRequest) returns (google.api.HttpBody) {
option (google.api.http) = {get: "/file/{name=attachments/*}/{filename}"};
option (google.api.method_signature) = "name,filename";
}
// UpdateAttachment updates a attachment.
rpc UpdateAttachment(UpdateAttachmentRequest) returns (Attachment) {
option (google.api.http) = {
patch: "/api/v1/{attachment.name=attachments/*}"
body: "attachment"
};
option (google.api.method_signature) = "attachment,update_mask";
}
// DeleteAttachment deletes a attachment by name.
rpc DeleteAttachment(DeleteAttachmentRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {delete: "/api/v1/{name=attachments/*}"};
option (google.api.method_signature) = "name";
}
}
message Attachment {
option (google.api.resource) = {
type: "memos.api.v1/Attachment"
pattern: "attachments/{attachment}"
singular: "attachment"
plural: "attachments"
};
reserved 2;
// The name of the attachment.
// Format: attachments/{attachment}
string name = 1 [(google.api.field_behavior) = IDENTIFIER];
// Output only. The creation timestamp.
google.protobuf.Timestamp create_time = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
// The filename of the attachment.
string filename = 4 [(google.api.field_behavior) = REQUIRED];
// Input only. The content of the attachment.
bytes content = 5 [(google.api.field_behavior) = INPUT_ONLY];
// Optional. The external link of the attachment.
string external_link = 6 [(google.api.field_behavior) = OPTIONAL];
// The MIME type of the attachment.
string type = 7 [(google.api.field_behavior) = REQUIRED];
// Output only. The size of the attachment in bytes.
int64 size = 8 [(google.api.field_behavior) = OUTPUT_ONLY];
// Optional. The related memo. Refer to `Memo.name`.
// Format: memos/{memo}
optional string memo = 9 [(google.api.field_behavior) = OPTIONAL];
}
message CreateAttachmentRequest {
// Required. The attachment to create.
Attachment attachment = 1 [(google.api.field_behavior) = REQUIRED];
// Optional. The attachment ID to use for this attachment.
// If empty, a unique ID will be generated.
string attachment_id = 2 [(google.api.field_behavior) = OPTIONAL];
}
message ListAttachmentsRequest {
// Optional. The maximum number of attachments to return.
// The service may return fewer than this value.
// If unspecified, at most 50 attachments will be returned.
// The maximum value is 1000; values above 1000 will be coerced to 1000.
int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];
// Optional. A page token, received from a previous `ListAttachments` call.
// Provide this to retrieve the subsequent page.
string page_token = 2 [(google.api.field_behavior) = OPTIONAL];
// Optional. Filter to apply to the list results.
// Example: "type=image/png" or "filename:*.jpg"
// Supported operators: =, !=, <, <=, >, >=, :
// Supported fields: filename, type, size, create_time, memo
string filter = 3 [(google.api.field_behavior) = OPTIONAL];
// Optional. The order to sort results by.
// Example: "create_time desc" or "filename asc"
string order_by = 4 [(google.api.field_behavior) = OPTIONAL];
}
message ListAttachmentsResponse {
// The list of attachments.
repeated Attachment attachments = 1;
// A token that can be sent as `page_token` to retrieve the next page.
// If this field is omitted, there are no subsequent pages.
string next_page_token = 2;
// The total count of attachments (may be approximate).
int32 total_size = 3;
}
message GetAttachmentRequest {
// Required. The attachment name of the attachment to retrieve.
// Format: attachments/{attachment}
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {type: "memos.api.v1/Attachment"}
];
}
message GetAttachmentBinaryRequest {
// Required. The attachment name of the attachment.
// Format: attachments/{attachment}
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {type: "memos.api.v1/Attachment"}
];
// The filename of the attachment. Mainly used for downloading.
string filename = 2 [(google.api.field_behavior) = REQUIRED];
// Optional. A flag indicating if the thumbnail version of the attachment should be returned.
bool thumbnail = 3 [(google.api.field_behavior) = OPTIONAL];
}
message UpdateAttachmentRequest {
// Required. The attachment which replaces the attachment on the server.
Attachment attachment = 1 [(google.api.field_behavior) = REQUIRED];
// Required. The list of fields to update.
google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED];
}
message DeleteAttachmentRequest {
// Required. The attachment name of the attachment to delete.
// Format: attachments/{attachment}
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {type: "memos.api.v1/Attachment"}
];
}

@ -2,10 +2,10 @@ syntax = "proto3";
package memos.api.v1;
import "api/v1/attachment_service.proto";
import "api/v1/common.proto";
import "api/v1/markdown_service.proto";
import "api/v1/reaction_service.proto";
import "api/v1/resource_service.proto";
import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
@ -59,17 +59,17 @@ service MemoService {
rpc DeleteMemoTag(DeleteMemoTagRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {delete: "/api/v1/{parent=memos/*}/tags/{tag}"};
}
// SetMemoResources sets resources for a memo.
rpc SetMemoResources(SetMemoResourcesRequest) returns (google.protobuf.Empty) {
// SetMemoAttachments sets attachments for a memo.
rpc SetMemoAttachments(SetMemoAttachmentsRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {
patch: "/api/v1/{name=memos/*}/resources"
patch: "/api/v1/{name=memos/*}/attachments"
body: "*"
};
option (google.api.method_signature) = "name";
}
// ListMemoResources lists resources for a memo.
rpc ListMemoResources(ListMemoResourcesRequest) returns (ListMemoResourcesResponse) {
option (google.api.http) = {get: "/api/v1/{name=memos/*}/resources"};
// ListMemoAttachments lists attachments for a memo.
rpc ListMemoAttachments(ListMemoAttachmentsRequest) returns (ListMemoAttachmentsResponse) {
option (google.api.http) = {get: "/api/v1/{name=memos/*}/attachments"};
option (google.api.method_signature) = "name";
}
// SetMemoRelations sets relations for a memo.
@ -157,7 +157,7 @@ message Memo {
bool pinned = 12;
repeated Resource resources = 14;
repeated Attachment attachments = 14;
repeated MemoRelation relations = 15;
@ -269,20 +269,20 @@ message DeleteMemoTagRequest {
bool delete_related_memos = 3;
}
message SetMemoResourcesRequest {
message SetMemoAttachmentsRequest {
// The name of the memo.
string name = 1;
repeated Resource resources = 2;
repeated Attachment attachments = 2;
}
message ListMemoResourcesRequest {
message ListMemoAttachmentsRequest {
// The name of the memo.
string name = 1;
}
message ListMemoResourcesResponse {
repeated Resource resources = 1;
message ListMemoAttachmentsResponse {
repeated Attachment attachments = 1;
}
message MemoRelation {

@ -1,113 +0,0 @@
syntax = "proto3";
package memos.api.v1;
import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/httpbody.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";
option go_package = "gen/api/v1";
service ResourceService {
// CreateResource creates a new resource.
rpc CreateResource(CreateResourceRequest) returns (Resource) {
option (google.api.http) = {
post: "/api/v1/resources"
body: "resource"
};
}
// ListResources lists all resources.
rpc ListResources(ListResourcesRequest) returns (ListResourcesResponse) {
option (google.api.http) = {get: "/api/v1/resources"};
}
// GetResource returns a resource by name.
rpc GetResource(GetResourceRequest) returns (Resource) {
option (google.api.http) = {get: "/api/v1/{name=resources/*}"};
option (google.api.method_signature) = "name";
}
// GetResourceBinary returns a resource binary by name.
rpc GetResourceBinary(GetResourceBinaryRequest) returns (google.api.HttpBody) {
option (google.api.http) = {get: "/file/{name=resources/*}/{filename}"};
option (google.api.method_signature) = "name,filename";
}
// UpdateResource updates a resource.
rpc UpdateResource(UpdateResourceRequest) returns (Resource) {
option (google.api.http) = {
patch: "/api/v1/{resource.name=resources/*}"
body: "resource"
};
option (google.api.method_signature) = "resource,update_mask";
}
// DeleteResource deletes a resource by name.
rpc DeleteResource(DeleteResourceRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {delete: "/api/v1/{name=resources/*}"};
option (google.api.method_signature) = "name";
}
}
message Resource {
reserved 2;
// The name of the resource.
// Format: resources/{resource}, resource is the user defined if or uuid.
string name = 1 [
(google.api.field_behavior) = OUTPUT_ONLY,
(google.api.field_behavior) = IDENTIFIER
];
google.protobuf.Timestamp create_time = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
string filename = 4;
bytes content = 5 [(google.api.field_behavior) = INPUT_ONLY];
string external_link = 6;
string type = 7;
int64 size = 8;
// The related memo. Refer to `Memo.name`.
optional string memo = 9;
}
message CreateResourceRequest {
Resource resource = 1;
}
message ListResourcesRequest {}
message ListResourcesResponse {
repeated Resource resources = 1;
}
message GetResourceRequest {
// The name of the resource.
string name = 1;
}
message GetResourceBinaryRequest {
// The name of the resource.
string name = 1;
// The filename of the resource. Mainly used for downloading.
string filename = 2;
// A flag indicating if the thumbnail version of the resource should be returned
bool thumbnail = 3;
}
message UpdateResourceRequest {
Resource resource = 1;
google.protobuf.FieldMask update_mask = 2;
}
message DeleteResourceRequest {
// The name of the resource.
string name = 1;
}

@ -0,0 +1,687 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc (unknown)
// source: api/v1/attachment_service.proto
package apiv1
import (
_ "google.golang.org/genproto/googleapis/api/annotations"
httpbody "google.golang.org/genproto/googleapis/api/httpbody"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
emptypb "google.golang.org/protobuf/types/known/emptypb"
fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb"
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 Attachment struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The name of the attachment.
// Format: attachments/{attachment}
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
// Output only. The creation timestamp.
CreateTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"`
// The filename of the attachment.
Filename string `protobuf:"bytes,4,opt,name=filename,proto3" json:"filename,omitempty"`
// Input only. The content of the attachment.
Content []byte `protobuf:"bytes,5,opt,name=content,proto3" json:"content,omitempty"`
// Optional. The external link of the attachment.
ExternalLink string `protobuf:"bytes,6,opt,name=external_link,json=externalLink,proto3" json:"external_link,omitempty"`
// The MIME type of the attachment.
Type string `protobuf:"bytes,7,opt,name=type,proto3" json:"type,omitempty"`
// Output only. The size of the attachment in bytes.
Size int64 `protobuf:"varint,8,opt,name=size,proto3" json:"size,omitempty"`
// Optional. The related memo. Refer to `Memo.name`.
// Format: memos/{memo}
Memo *string `protobuf:"bytes,9,opt,name=memo,proto3,oneof" json:"memo,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Attachment) Reset() {
*x = Attachment{}
mi := &file_api_v1_attachment_service_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Attachment) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Attachment) ProtoMessage() {}
func (x *Attachment) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_attachment_service_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 Attachment.ProtoReflect.Descriptor instead.
func (*Attachment) Descriptor() ([]byte, []int) {
return file_api_v1_attachment_service_proto_rawDescGZIP(), []int{0}
}
func (x *Attachment) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *Attachment) GetCreateTime() *timestamppb.Timestamp {
if x != nil {
return x.CreateTime
}
return nil
}
func (x *Attachment) GetFilename() string {
if x != nil {
return x.Filename
}
return ""
}
func (x *Attachment) GetContent() []byte {
if x != nil {
return x.Content
}
return nil
}
func (x *Attachment) GetExternalLink() string {
if x != nil {
return x.ExternalLink
}
return ""
}
func (x *Attachment) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *Attachment) GetSize() int64 {
if x != nil {
return x.Size
}
return 0
}
func (x *Attachment) GetMemo() string {
if x != nil && x.Memo != nil {
return *x.Memo
}
return ""
}
type CreateAttachmentRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Required. The attachment to create.
Attachment *Attachment `protobuf:"bytes,1,opt,name=attachment,proto3" json:"attachment,omitempty"`
// Optional. The attachment ID to use for this attachment.
// If empty, a unique ID will be generated.
AttachmentId string `protobuf:"bytes,2,opt,name=attachment_id,json=attachmentId,proto3" json:"attachment_id,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *CreateAttachmentRequest) Reset() {
*x = CreateAttachmentRequest{}
mi := &file_api_v1_attachment_service_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CreateAttachmentRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateAttachmentRequest) ProtoMessage() {}
func (x *CreateAttachmentRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_attachment_service_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 CreateAttachmentRequest.ProtoReflect.Descriptor instead.
func (*CreateAttachmentRequest) Descriptor() ([]byte, []int) {
return file_api_v1_attachment_service_proto_rawDescGZIP(), []int{1}
}
func (x *CreateAttachmentRequest) GetAttachment() *Attachment {
if x != nil {
return x.Attachment
}
return nil
}
func (x *CreateAttachmentRequest) GetAttachmentId() string {
if x != nil {
return x.AttachmentId
}
return ""
}
type ListAttachmentsRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Optional. The maximum number of attachments to return.
// The service may return fewer than this value.
// If unspecified, at most 50 attachments will be returned.
// The maximum value is 1000; values above 1000 will be coerced to 1000.
PageSize int32 `protobuf:"varint,1,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"`
// Optional. A page token, received from a previous `ListAttachments` call.
// Provide this to retrieve the subsequent page.
PageToken string `protobuf:"bytes,2,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"`
// Optional. Filter to apply to the list results.
// Example: "type=image/png" or "filename:*.jpg"
// Supported operators: =, !=, <, <=, >, >=, :
// Supported fields: filename, type, size, create_time, memo
Filter string `protobuf:"bytes,3,opt,name=filter,proto3" json:"filter,omitempty"`
// Optional. The order to sort results by.
// Example: "create_time desc" or "filename asc"
OrderBy string `protobuf:"bytes,4,opt,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ListAttachmentsRequest) Reset() {
*x = ListAttachmentsRequest{}
mi := &file_api_v1_attachment_service_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListAttachmentsRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListAttachmentsRequest) ProtoMessage() {}
func (x *ListAttachmentsRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_attachment_service_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 ListAttachmentsRequest.ProtoReflect.Descriptor instead.
func (*ListAttachmentsRequest) Descriptor() ([]byte, []int) {
return file_api_v1_attachment_service_proto_rawDescGZIP(), []int{2}
}
func (x *ListAttachmentsRequest) GetPageSize() int32 {
if x != nil {
return x.PageSize
}
return 0
}
func (x *ListAttachmentsRequest) GetPageToken() string {
if x != nil {
return x.PageToken
}
return ""
}
func (x *ListAttachmentsRequest) GetFilter() string {
if x != nil {
return x.Filter
}
return ""
}
func (x *ListAttachmentsRequest) GetOrderBy() string {
if x != nil {
return x.OrderBy
}
return ""
}
type ListAttachmentsResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The list of attachments.
Attachments []*Attachment `protobuf:"bytes,1,rep,name=attachments,proto3" json:"attachments,omitempty"`
// A token that can be sent as `page_token` to retrieve the next page.
// If this field is omitted, there are no subsequent pages.
NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"`
// The total count of attachments (may be approximate).
TotalSize int32 `protobuf:"varint,3,opt,name=total_size,json=totalSize,proto3" json:"total_size,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ListAttachmentsResponse) Reset() {
*x = ListAttachmentsResponse{}
mi := &file_api_v1_attachment_service_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListAttachmentsResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListAttachmentsResponse) ProtoMessage() {}
func (x *ListAttachmentsResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_attachment_service_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 ListAttachmentsResponse.ProtoReflect.Descriptor instead.
func (*ListAttachmentsResponse) Descriptor() ([]byte, []int) {
return file_api_v1_attachment_service_proto_rawDescGZIP(), []int{3}
}
func (x *ListAttachmentsResponse) GetAttachments() []*Attachment {
if x != nil {
return x.Attachments
}
return nil
}
func (x *ListAttachmentsResponse) GetNextPageToken() string {
if x != nil {
return x.NextPageToken
}
return ""
}
func (x *ListAttachmentsResponse) GetTotalSize() int32 {
if x != nil {
return x.TotalSize
}
return 0
}
type GetAttachmentRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Required. The attachment name of the attachment to retrieve.
// Format: attachments/{attachment}
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetAttachmentRequest) Reset() {
*x = GetAttachmentRequest{}
mi := &file_api_v1_attachment_service_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetAttachmentRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetAttachmentRequest) ProtoMessage() {}
func (x *GetAttachmentRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_attachment_service_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 GetAttachmentRequest.ProtoReflect.Descriptor instead.
func (*GetAttachmentRequest) Descriptor() ([]byte, []int) {
return file_api_v1_attachment_service_proto_rawDescGZIP(), []int{4}
}
func (x *GetAttachmentRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
type GetAttachmentBinaryRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Required. The attachment name of the attachment.
// Format: attachments/{attachment}
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
// The filename of the attachment. Mainly used for downloading.
Filename string `protobuf:"bytes,2,opt,name=filename,proto3" json:"filename,omitempty"`
// Optional. A flag indicating if the thumbnail version of the attachment should be returned.
Thumbnail bool `protobuf:"varint,3,opt,name=thumbnail,proto3" json:"thumbnail,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetAttachmentBinaryRequest) Reset() {
*x = GetAttachmentBinaryRequest{}
mi := &file_api_v1_attachment_service_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetAttachmentBinaryRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetAttachmentBinaryRequest) ProtoMessage() {}
func (x *GetAttachmentBinaryRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_attachment_service_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 GetAttachmentBinaryRequest.ProtoReflect.Descriptor instead.
func (*GetAttachmentBinaryRequest) Descriptor() ([]byte, []int) {
return file_api_v1_attachment_service_proto_rawDescGZIP(), []int{5}
}
func (x *GetAttachmentBinaryRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *GetAttachmentBinaryRequest) GetFilename() string {
if x != nil {
return x.Filename
}
return ""
}
func (x *GetAttachmentBinaryRequest) GetThumbnail() bool {
if x != nil {
return x.Thumbnail
}
return false
}
type UpdateAttachmentRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Required. The attachment which replaces the attachment on the server.
Attachment *Attachment `protobuf:"bytes,1,opt,name=attachment,proto3" json:"attachment,omitempty"`
// Required. The list of fields to update.
UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *UpdateAttachmentRequest) Reset() {
*x = UpdateAttachmentRequest{}
mi := &file_api_v1_attachment_service_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *UpdateAttachmentRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateAttachmentRequest) ProtoMessage() {}
func (x *UpdateAttachmentRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_attachment_service_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 UpdateAttachmentRequest.ProtoReflect.Descriptor instead.
func (*UpdateAttachmentRequest) Descriptor() ([]byte, []int) {
return file_api_v1_attachment_service_proto_rawDescGZIP(), []int{6}
}
func (x *UpdateAttachmentRequest) GetAttachment() *Attachment {
if x != nil {
return x.Attachment
}
return nil
}
func (x *UpdateAttachmentRequest) GetUpdateMask() *fieldmaskpb.FieldMask {
if x != nil {
return x.UpdateMask
}
return nil
}
type DeleteAttachmentRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Required. The attachment name of the attachment to delete.
// Format: attachments/{attachment}
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *DeleteAttachmentRequest) Reset() {
*x = DeleteAttachmentRequest{}
mi := &file_api_v1_attachment_service_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *DeleteAttachmentRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DeleteAttachmentRequest) ProtoMessage() {}
func (x *DeleteAttachmentRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_attachment_service_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 DeleteAttachmentRequest.ProtoReflect.Descriptor instead.
func (*DeleteAttachmentRequest) Descriptor() ([]byte, []int) {
return file_api_v1_attachment_service_proto_rawDescGZIP(), []int{7}
}
func (x *DeleteAttachmentRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
var File_api_v1_attachment_service_proto protoreflect.FileDescriptor
const file_api_v1_attachment_service_proto_rawDesc = "" +
"\n" +
"\x1fapi/v1/attachment_service.proto\x12\fmemos.api.v1\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/api/httpbody.proto\x1a\x19google/api/resource.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a google/protobuf/field_mask.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x81\x03\n" +
"\n" +
"Attachment\x12\x17\n" +
"\x04name\x18\x01 \x01(\tB\x03\xe0A\bR\x04name\x12@\n" +
"\vcreate_time\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampB\x03\xe0A\x03R\n" +
"createTime\x12\x1f\n" +
"\bfilename\x18\x04 \x01(\tB\x03\xe0A\x02R\bfilename\x12\x1d\n" +
"\acontent\x18\x05 \x01(\fB\x03\xe0A\x04R\acontent\x12(\n" +
"\rexternal_link\x18\x06 \x01(\tB\x03\xe0A\x01R\fexternalLink\x12\x17\n" +
"\x04type\x18\a \x01(\tB\x03\xe0A\x02R\x04type\x12\x17\n" +
"\x04size\x18\b \x01(\x03B\x03\xe0A\x03R\x04size\x12\x1c\n" +
"\x04memo\x18\t \x01(\tB\x03\xe0A\x01H\x00R\x04memo\x88\x01\x01:O\xeaAL\n" +
"\x17memos.api.v1/Attachment\x12\x18attachments/{attachment}*\vattachments2\n" +
"attachmentB\a\n" +
"\x05_memoJ\x04\b\x02\x10\x03\"\x82\x01\n" +
"\x17CreateAttachmentRequest\x12=\n" +
"\n" +
"attachment\x18\x01 \x01(\v2\x18.memos.api.v1.AttachmentB\x03\xe0A\x02R\n" +
"attachment\x12(\n" +
"\rattachment_id\x18\x02 \x01(\tB\x03\xe0A\x01R\fattachmentId\"\x9b\x01\n" +
"\x16ListAttachmentsRequest\x12 \n" +
"\tpage_size\x18\x01 \x01(\x05B\x03\xe0A\x01R\bpageSize\x12\"\n" +
"\n" +
"page_token\x18\x02 \x01(\tB\x03\xe0A\x01R\tpageToken\x12\x1b\n" +
"\x06filter\x18\x03 \x01(\tB\x03\xe0A\x01R\x06filter\x12\x1e\n" +
"\border_by\x18\x04 \x01(\tB\x03\xe0A\x01R\aorderBy\"\x9c\x01\n" +
"\x17ListAttachmentsResponse\x12:\n" +
"\vattachments\x18\x01 \x03(\v2\x18.memos.api.v1.AttachmentR\vattachments\x12&\n" +
"\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\x12\x1d\n" +
"\n" +
"total_size\x18\x03 \x01(\x05R\ttotalSize\"K\n" +
"\x14GetAttachmentRequest\x123\n" +
"\x04name\x18\x01 \x01(\tB\x1f\xe0A\x02\xfaA\x19\n" +
"\x17memos.api.v1/AttachmentR\x04name\"\x95\x01\n" +
"\x1aGetAttachmentBinaryRequest\x123\n" +
"\x04name\x18\x01 \x01(\tB\x1f\xe0A\x02\xfaA\x19\n" +
"\x17memos.api.v1/AttachmentR\x04name\x12\x1f\n" +
"\bfilename\x18\x02 \x01(\tB\x03\xe0A\x02R\bfilename\x12!\n" +
"\tthumbnail\x18\x03 \x01(\bB\x03\xe0A\x01R\tthumbnail\"\x9a\x01\n" +
"\x17UpdateAttachmentRequest\x12=\n" +
"\n" +
"attachment\x18\x01 \x01(\v2\x18.memos.api.v1.AttachmentB\x03\xe0A\x02R\n" +
"attachment\x12@\n" +
"\vupdate_mask\x18\x02 \x01(\v2\x1a.google.protobuf.FieldMaskB\x03\xe0A\x02R\n" +
"updateMask\"N\n" +
"\x17DeleteAttachmentRequest\x123\n" +
"\x04name\x18\x01 \x01(\tB\x1f\xe0A\x02\xfaA\x19\n" +
"\x17memos.api.v1/AttachmentR\x04name2\xdb\x06\n" +
"\x11AttachmentService\x12\x89\x01\n" +
"\x10CreateAttachment\x12%.memos.api.v1.CreateAttachmentRequest\x1a\x18.memos.api.v1.Attachment\"4\xdaA\n" +
"attachment\x82\xd3\xe4\x93\x02!:\n" +
"attachment\"\x13/api/v1/attachments\x12{\n" +
"\x0fListAttachments\x12$.memos.api.v1.ListAttachmentsRequest\x1a%.memos.api.v1.ListAttachmentsResponse\"\x1b\x82\xd3\xe4\x93\x02\x15\x12\x13/api/v1/attachments\x12z\n" +
"\rGetAttachment\x12\".memos.api.v1.GetAttachmentRequest\x1a\x18.memos.api.v1.Attachment\"+\xdaA\x04name\x82\xd3\xe4\x93\x02\x1e\x12\x1c/api/v1/{name=attachments/*}\x12\x94\x01\n" +
"\x13GetAttachmentBinary\x12(.memos.api.v1.GetAttachmentBinaryRequest\x1a\x14.google.api.HttpBody\"=\xdaA\rname,filename\x82\xd3\xe4\x93\x02'\x12%/file/{name=attachments/*}/{filename}\x12\xa9\x01\n" +
"\x10UpdateAttachment\x12%.memos.api.v1.UpdateAttachmentRequest\x1a\x18.memos.api.v1.Attachment\"T\xdaA\x16attachment,update_mask\x82\xd3\xe4\x93\x025:\n" +
"attachment2'/api/v1/{attachment.name=attachments/*}\x12~\n" +
"\x10DeleteAttachment\x12%.memos.api.v1.DeleteAttachmentRequest\x1a\x16.google.protobuf.Empty\"+\xdaA\x04name\x82\xd3\xe4\x93\x02\x1e*\x1c/api/v1/{name=attachments/*}B\xae\x01\n" +
"\x10com.memos.api.v1B\x16AttachmentServiceProtoP\x01Z0github.com/usememos/memos/proto/gen/api/v1;apiv1\xa2\x02\x03MAX\xaa\x02\fMemos.Api.V1\xca\x02\fMemos\\Api\\V1\xe2\x02\x18Memos\\Api\\V1\\GPBMetadata\xea\x02\x0eMemos::Api::V1b\x06proto3"
var (
file_api_v1_attachment_service_proto_rawDescOnce sync.Once
file_api_v1_attachment_service_proto_rawDescData []byte
)
func file_api_v1_attachment_service_proto_rawDescGZIP() []byte {
file_api_v1_attachment_service_proto_rawDescOnce.Do(func() {
file_api_v1_attachment_service_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_api_v1_attachment_service_proto_rawDesc), len(file_api_v1_attachment_service_proto_rawDesc)))
})
return file_api_v1_attachment_service_proto_rawDescData
}
var file_api_v1_attachment_service_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
var file_api_v1_attachment_service_proto_goTypes = []any{
(*Attachment)(nil), // 0: memos.api.v1.Attachment
(*CreateAttachmentRequest)(nil), // 1: memos.api.v1.CreateAttachmentRequest
(*ListAttachmentsRequest)(nil), // 2: memos.api.v1.ListAttachmentsRequest
(*ListAttachmentsResponse)(nil), // 3: memos.api.v1.ListAttachmentsResponse
(*GetAttachmentRequest)(nil), // 4: memos.api.v1.GetAttachmentRequest
(*GetAttachmentBinaryRequest)(nil), // 5: memos.api.v1.GetAttachmentBinaryRequest
(*UpdateAttachmentRequest)(nil), // 6: memos.api.v1.UpdateAttachmentRequest
(*DeleteAttachmentRequest)(nil), // 7: memos.api.v1.DeleteAttachmentRequest
(*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp
(*fieldmaskpb.FieldMask)(nil), // 9: google.protobuf.FieldMask
(*httpbody.HttpBody)(nil), // 10: google.api.HttpBody
(*emptypb.Empty)(nil), // 11: google.protobuf.Empty
}
var file_api_v1_attachment_service_proto_depIdxs = []int32{
8, // 0: memos.api.v1.Attachment.create_time:type_name -> google.protobuf.Timestamp
0, // 1: memos.api.v1.CreateAttachmentRequest.attachment:type_name -> memos.api.v1.Attachment
0, // 2: memos.api.v1.ListAttachmentsResponse.attachments:type_name -> memos.api.v1.Attachment
0, // 3: memos.api.v1.UpdateAttachmentRequest.attachment:type_name -> memos.api.v1.Attachment
9, // 4: memos.api.v1.UpdateAttachmentRequest.update_mask:type_name -> google.protobuf.FieldMask
1, // 5: memos.api.v1.AttachmentService.CreateAttachment:input_type -> memos.api.v1.CreateAttachmentRequest
2, // 6: memos.api.v1.AttachmentService.ListAttachments:input_type -> memos.api.v1.ListAttachmentsRequest
4, // 7: memos.api.v1.AttachmentService.GetAttachment:input_type -> memos.api.v1.GetAttachmentRequest
5, // 8: memos.api.v1.AttachmentService.GetAttachmentBinary:input_type -> memos.api.v1.GetAttachmentBinaryRequest
6, // 9: memos.api.v1.AttachmentService.UpdateAttachment:input_type -> memos.api.v1.UpdateAttachmentRequest
7, // 10: memos.api.v1.AttachmentService.DeleteAttachment:input_type -> memos.api.v1.DeleteAttachmentRequest
0, // 11: memos.api.v1.AttachmentService.CreateAttachment:output_type -> memos.api.v1.Attachment
3, // 12: memos.api.v1.AttachmentService.ListAttachments:output_type -> memos.api.v1.ListAttachmentsResponse
0, // 13: memos.api.v1.AttachmentService.GetAttachment:output_type -> memos.api.v1.Attachment
10, // 14: memos.api.v1.AttachmentService.GetAttachmentBinary:output_type -> google.api.HttpBody
0, // 15: memos.api.v1.AttachmentService.UpdateAttachment:output_type -> memos.api.v1.Attachment
11, // 16: memos.api.v1.AttachmentService.DeleteAttachment:output_type -> google.protobuf.Empty
11, // [11:17] is the sub-list for method output_type
5, // [5:11] is the sub-list for method input_type
5, // [5:5] is the sub-list for extension type_name
5, // [5:5] is the sub-list for extension extendee
0, // [0:5] is the sub-list for field type_name
}
func init() { file_api_v1_attachment_service_proto_init() }
func file_api_v1_attachment_service_proto_init() {
if File_api_v1_attachment_service_proto != nil {
return
}
file_api_v1_attachment_service_proto_msgTypes[0].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_v1_attachment_service_proto_rawDesc), len(file_api_v1_attachment_service_proto_rawDesc)),
NumEnums: 0,
NumMessages: 8,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_api_v1_attachment_service_proto_goTypes,
DependencyIndexes: file_api_v1_attachment_service_proto_depIdxs,
MessageInfos: file_api_v1_attachment_service_proto_msgTypes,
}.Build()
File_api_v1_attachment_service_proto = out.File
file_api_v1_attachment_service_proto_goTypes = nil
file_api_v1_attachment_service_proto_depIdxs = nil
}

@ -0,0 +1,615 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: api/v1/attachment_service.proto
/*
Package apiv1 is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package apiv1
import (
"context"
"errors"
"io"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
)
// Suppress "imported and not used" errors
var (
_ codes.Code
_ io.Reader
_ status.Status
_ = errors.New
_ = runtime.String
_ = utilities.NewDoubleArray
_ = metadata.Join
)
var filter_AttachmentService_CreateAttachment_0 = &utilities.DoubleArray{Encoding: map[string]int{"attachment": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
func request_AttachmentService_CreateAttachment_0(ctx context.Context, marshaler runtime.Marshaler, client AttachmentServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq CreateAttachmentRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq.Attachment); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AttachmentService_CreateAttachment_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.CreateAttachment(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_AttachmentService_CreateAttachment_0(ctx context.Context, marshaler runtime.Marshaler, server AttachmentServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq CreateAttachmentRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq.Attachment); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AttachmentService_CreateAttachment_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.CreateAttachment(ctx, &protoReq)
return msg, metadata, err
}
var filter_AttachmentService_ListAttachments_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
func request_AttachmentService_ListAttachments_0(ctx context.Context, marshaler runtime.Marshaler, client AttachmentServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq ListAttachmentsRequest
metadata runtime.ServerMetadata
)
io.Copy(io.Discard, req.Body)
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AttachmentService_ListAttachments_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.ListAttachments(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_AttachmentService_ListAttachments_0(ctx context.Context, marshaler runtime.Marshaler, server AttachmentServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq ListAttachmentsRequest
metadata runtime.ServerMetadata
)
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AttachmentService_ListAttachments_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.ListAttachments(ctx, &protoReq)
return msg, metadata, err
}
func request_AttachmentService_GetAttachment_0(ctx context.Context, marshaler runtime.Marshaler, client AttachmentServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq GetAttachmentRequest
metadata runtime.ServerMetadata
err error
)
io.Copy(io.Discard, req.Body)
val, ok := pathParams["name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
}
protoReq.Name, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
msg, err := client.GetAttachment(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_AttachmentService_GetAttachment_0(ctx context.Context, marshaler runtime.Marshaler, server AttachmentServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq GetAttachmentRequest
metadata runtime.ServerMetadata
err error
)
val, ok := pathParams["name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
}
protoReq.Name, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
msg, err := server.GetAttachment(ctx, &protoReq)
return msg, metadata, err
}
var filter_AttachmentService_GetAttachmentBinary_0 = &utilities.DoubleArray{Encoding: map[string]int{"name": 0, "filename": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}}
func request_AttachmentService_GetAttachmentBinary_0(ctx context.Context, marshaler runtime.Marshaler, client AttachmentServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq GetAttachmentBinaryRequest
metadata runtime.ServerMetadata
err error
)
io.Copy(io.Discard, req.Body)
val, ok := pathParams["name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
}
protoReq.Name, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
val, ok = pathParams["filename"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "filename")
}
protoReq.Filename, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "filename", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AttachmentService_GetAttachmentBinary_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.GetAttachmentBinary(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_AttachmentService_GetAttachmentBinary_0(ctx context.Context, marshaler runtime.Marshaler, server AttachmentServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq GetAttachmentBinaryRequest
metadata runtime.ServerMetadata
err error
)
val, ok := pathParams["name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
}
protoReq.Name, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
val, ok = pathParams["filename"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "filename")
}
protoReq.Filename, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "filename", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AttachmentService_GetAttachmentBinary_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.GetAttachmentBinary(ctx, &protoReq)
return msg, metadata, err
}
var filter_AttachmentService_UpdateAttachment_0 = &utilities.DoubleArray{Encoding: map[string]int{"attachment": 0, "name": 1}, Base: []int{1, 2, 1, 0, 0}, Check: []int{0, 1, 2, 3, 2}}
func request_AttachmentService_UpdateAttachment_0(ctx context.Context, marshaler runtime.Marshaler, client AttachmentServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq UpdateAttachmentRequest
metadata runtime.ServerMetadata
err error
)
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Attachment); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if protoReq.UpdateMask == nil || len(protoReq.UpdateMask.GetPaths()) == 0 {
if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), protoReq.Attachment); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} else {
protoReq.UpdateMask = fieldMask
}
}
val, ok := pathParams["attachment.name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "attachment.name")
}
err = runtime.PopulateFieldFromPath(&protoReq, "attachment.name", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "attachment.name", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AttachmentService_UpdateAttachment_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.UpdateAttachment(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_AttachmentService_UpdateAttachment_0(ctx context.Context, marshaler runtime.Marshaler, server AttachmentServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq UpdateAttachmentRequest
metadata runtime.ServerMetadata
err error
)
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Attachment); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if protoReq.UpdateMask == nil || len(protoReq.UpdateMask.GetPaths()) == 0 {
if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), protoReq.Attachment); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} else {
protoReq.UpdateMask = fieldMask
}
}
val, ok := pathParams["attachment.name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "attachment.name")
}
err = runtime.PopulateFieldFromPath(&protoReq, "attachment.name", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "attachment.name", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AttachmentService_UpdateAttachment_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.UpdateAttachment(ctx, &protoReq)
return msg, metadata, err
}
func request_AttachmentService_DeleteAttachment_0(ctx context.Context, marshaler runtime.Marshaler, client AttachmentServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq DeleteAttachmentRequest
metadata runtime.ServerMetadata
err error
)
io.Copy(io.Discard, req.Body)
val, ok := pathParams["name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
}
protoReq.Name, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
msg, err := client.DeleteAttachment(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_AttachmentService_DeleteAttachment_0(ctx context.Context, marshaler runtime.Marshaler, server AttachmentServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq DeleteAttachmentRequest
metadata runtime.ServerMetadata
err error
)
val, ok := pathParams["name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
}
protoReq.Name, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
msg, err := server.DeleteAttachment(ctx, &protoReq)
return msg, metadata, err
}
// RegisterAttachmentServiceHandlerServer registers the http handlers for service AttachmentService to "mux".
// UnaryRPC :call AttachmentServiceServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterAttachmentServiceHandlerFromEndpoint instead.
// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call.
func RegisterAttachmentServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server AttachmentServiceServer) error {
mux.Handle(http.MethodPost, pattern_AttachmentService_CreateAttachment_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.AttachmentService/CreateAttachment", runtime.WithHTTPPathPattern("/api/v1/attachments"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AttachmentService_CreateAttachment_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_AttachmentService_CreateAttachment_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodGet, pattern_AttachmentService_ListAttachments_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.AttachmentService/ListAttachments", runtime.WithHTTPPathPattern("/api/v1/attachments"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AttachmentService_ListAttachments_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_AttachmentService_ListAttachments_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodGet, pattern_AttachmentService_GetAttachment_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.AttachmentService/GetAttachment", runtime.WithHTTPPathPattern("/api/v1/{name=attachments/*}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AttachmentService_GetAttachment_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_AttachmentService_GetAttachment_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodGet, pattern_AttachmentService_GetAttachmentBinary_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.AttachmentService/GetAttachmentBinary", runtime.WithHTTPPathPattern("/file/{name=attachments/*}/{filename}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AttachmentService_GetAttachmentBinary_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_AttachmentService_GetAttachmentBinary_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPatch, pattern_AttachmentService_UpdateAttachment_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.AttachmentService/UpdateAttachment", runtime.WithHTTPPathPattern("/api/v1/{attachment.name=attachments/*}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AttachmentService_UpdateAttachment_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_AttachmentService_UpdateAttachment_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodDelete, pattern_AttachmentService_DeleteAttachment_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.AttachmentService/DeleteAttachment", runtime.WithHTTPPathPattern("/api/v1/{name=attachments/*}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AttachmentService_DeleteAttachment_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_AttachmentService_DeleteAttachment_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterAttachmentServiceHandlerFromEndpoint is same as RegisterAttachmentServiceHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterAttachmentServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.NewClient(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterAttachmentServiceHandler(ctx, mux, conn)
}
// RegisterAttachmentServiceHandler registers the http handlers for service AttachmentService to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterAttachmentServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterAttachmentServiceHandlerClient(ctx, mux, NewAttachmentServiceClient(conn))
}
// RegisterAttachmentServiceHandlerClient registers the http handlers for service AttachmentService
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "AttachmentServiceClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "AttachmentServiceClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "AttachmentServiceClient" to call the correct interceptors. This client ignores the HTTP middlewares.
func RegisterAttachmentServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client AttachmentServiceClient) error {
mux.Handle(http.MethodPost, pattern_AttachmentService_CreateAttachment_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.AttachmentService/CreateAttachment", runtime.WithHTTPPathPattern("/api/v1/attachments"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_AttachmentService_CreateAttachment_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_AttachmentService_CreateAttachment_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodGet, pattern_AttachmentService_ListAttachments_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.AttachmentService/ListAttachments", runtime.WithHTTPPathPattern("/api/v1/attachments"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_AttachmentService_ListAttachments_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_AttachmentService_ListAttachments_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodGet, pattern_AttachmentService_GetAttachment_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.AttachmentService/GetAttachment", runtime.WithHTTPPathPattern("/api/v1/{name=attachments/*}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_AttachmentService_GetAttachment_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_AttachmentService_GetAttachment_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodGet, pattern_AttachmentService_GetAttachmentBinary_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.AttachmentService/GetAttachmentBinary", runtime.WithHTTPPathPattern("/file/{name=attachments/*}/{filename}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_AttachmentService_GetAttachmentBinary_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_AttachmentService_GetAttachmentBinary_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPatch, pattern_AttachmentService_UpdateAttachment_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.AttachmentService/UpdateAttachment", runtime.WithHTTPPathPattern("/api/v1/{attachment.name=attachments/*}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_AttachmentService_UpdateAttachment_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_AttachmentService_UpdateAttachment_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodDelete, pattern_AttachmentService_DeleteAttachment_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.AttachmentService/DeleteAttachment", runtime.WithHTTPPathPattern("/api/v1/{name=attachments/*}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_AttachmentService_DeleteAttachment_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_AttachmentService_DeleteAttachment_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_AttachmentService_CreateAttachment_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "attachments"}, ""))
pattern_AttachmentService_ListAttachments_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "attachments"}, ""))
pattern_AttachmentService_GetAttachment_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "attachments", "name"}, ""))
pattern_AttachmentService_GetAttachmentBinary_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 2, 5, 2, 1, 0, 4, 1, 5, 3}, []string{"file", "attachments", "name", "filename"}, ""))
pattern_AttachmentService_UpdateAttachment_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "attachments", "attachment.name"}, ""))
pattern_AttachmentService_DeleteAttachment_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "attachments", "name"}, ""))
)
var (
forward_AttachmentService_CreateAttachment_0 = runtime.ForwardResponseMessage
forward_AttachmentService_ListAttachments_0 = runtime.ForwardResponseMessage
forward_AttachmentService_GetAttachment_0 = runtime.ForwardResponseMessage
forward_AttachmentService_GetAttachmentBinary_0 = runtime.ForwardResponseMessage
forward_AttachmentService_UpdateAttachment_0 = runtime.ForwardResponseMessage
forward_AttachmentService_DeleteAttachment_0 = runtime.ForwardResponseMessage
)

@ -0,0 +1,325 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc (unknown)
// source: api/v1/attachment_service.proto
package apiv1
import (
context "context"
httpbody "google.golang.org/genproto/googleapis/api/httpbody"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
emptypb "google.golang.org/protobuf/types/known/emptypb"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
AttachmentService_CreateAttachment_FullMethodName = "/memos.api.v1.AttachmentService/CreateAttachment"
AttachmentService_ListAttachments_FullMethodName = "/memos.api.v1.AttachmentService/ListAttachments"
AttachmentService_GetAttachment_FullMethodName = "/memos.api.v1.AttachmentService/GetAttachment"
AttachmentService_GetAttachmentBinary_FullMethodName = "/memos.api.v1.AttachmentService/GetAttachmentBinary"
AttachmentService_UpdateAttachment_FullMethodName = "/memos.api.v1.AttachmentService/UpdateAttachment"
AttachmentService_DeleteAttachment_FullMethodName = "/memos.api.v1.AttachmentService/DeleteAttachment"
)
// AttachmentServiceClient is the client API for AttachmentService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type AttachmentServiceClient interface {
// CreateAttachment creates a new attachment.
CreateAttachment(ctx context.Context, in *CreateAttachmentRequest, opts ...grpc.CallOption) (*Attachment, error)
// ListAttachments lists all attachments.
ListAttachments(ctx context.Context, in *ListAttachmentsRequest, opts ...grpc.CallOption) (*ListAttachmentsResponse, error)
// GetAttachment returns a attachment by name.
GetAttachment(ctx context.Context, in *GetAttachmentRequest, opts ...grpc.CallOption) (*Attachment, error)
// GetAttachmentBinary returns a attachment binary by name.
GetAttachmentBinary(ctx context.Context, in *GetAttachmentBinaryRequest, opts ...grpc.CallOption) (*httpbody.HttpBody, error)
// UpdateAttachment updates a attachment.
UpdateAttachment(ctx context.Context, in *UpdateAttachmentRequest, opts ...grpc.CallOption) (*Attachment, error)
// DeleteAttachment deletes a attachment by name.
DeleteAttachment(ctx context.Context, in *DeleteAttachmentRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
}
type attachmentServiceClient struct {
cc grpc.ClientConnInterface
}
func NewAttachmentServiceClient(cc grpc.ClientConnInterface) AttachmentServiceClient {
return &attachmentServiceClient{cc}
}
func (c *attachmentServiceClient) CreateAttachment(ctx context.Context, in *CreateAttachmentRequest, opts ...grpc.CallOption) (*Attachment, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(Attachment)
err := c.cc.Invoke(ctx, AttachmentService_CreateAttachment_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *attachmentServiceClient) ListAttachments(ctx context.Context, in *ListAttachmentsRequest, opts ...grpc.CallOption) (*ListAttachmentsResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ListAttachmentsResponse)
err := c.cc.Invoke(ctx, AttachmentService_ListAttachments_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *attachmentServiceClient) GetAttachment(ctx context.Context, in *GetAttachmentRequest, opts ...grpc.CallOption) (*Attachment, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(Attachment)
err := c.cc.Invoke(ctx, AttachmentService_GetAttachment_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *attachmentServiceClient) GetAttachmentBinary(ctx context.Context, in *GetAttachmentBinaryRequest, opts ...grpc.CallOption) (*httpbody.HttpBody, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(httpbody.HttpBody)
err := c.cc.Invoke(ctx, AttachmentService_GetAttachmentBinary_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *attachmentServiceClient) UpdateAttachment(ctx context.Context, in *UpdateAttachmentRequest, opts ...grpc.CallOption) (*Attachment, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(Attachment)
err := c.cc.Invoke(ctx, AttachmentService_UpdateAttachment_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *attachmentServiceClient) DeleteAttachment(ctx context.Context, in *DeleteAttachmentRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, AttachmentService_DeleteAttachment_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// AttachmentServiceServer is the server API for AttachmentService service.
// All implementations must embed UnimplementedAttachmentServiceServer
// for forward compatibility.
type AttachmentServiceServer interface {
// CreateAttachment creates a new attachment.
CreateAttachment(context.Context, *CreateAttachmentRequest) (*Attachment, error)
// ListAttachments lists all attachments.
ListAttachments(context.Context, *ListAttachmentsRequest) (*ListAttachmentsResponse, error)
// GetAttachment returns a attachment by name.
GetAttachment(context.Context, *GetAttachmentRequest) (*Attachment, error)
// GetAttachmentBinary returns a attachment binary by name.
GetAttachmentBinary(context.Context, *GetAttachmentBinaryRequest) (*httpbody.HttpBody, error)
// UpdateAttachment updates a attachment.
UpdateAttachment(context.Context, *UpdateAttachmentRequest) (*Attachment, error)
// DeleteAttachment deletes a attachment by name.
DeleteAttachment(context.Context, *DeleteAttachmentRequest) (*emptypb.Empty, error)
mustEmbedUnimplementedAttachmentServiceServer()
}
// UnimplementedAttachmentServiceServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedAttachmentServiceServer struct{}
func (UnimplementedAttachmentServiceServer) CreateAttachment(context.Context, *CreateAttachmentRequest) (*Attachment, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateAttachment not implemented")
}
func (UnimplementedAttachmentServiceServer) ListAttachments(context.Context, *ListAttachmentsRequest) (*ListAttachmentsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListAttachments not implemented")
}
func (UnimplementedAttachmentServiceServer) GetAttachment(context.Context, *GetAttachmentRequest) (*Attachment, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetAttachment not implemented")
}
func (UnimplementedAttachmentServiceServer) GetAttachmentBinary(context.Context, *GetAttachmentBinaryRequest) (*httpbody.HttpBody, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetAttachmentBinary not implemented")
}
func (UnimplementedAttachmentServiceServer) UpdateAttachment(context.Context, *UpdateAttachmentRequest) (*Attachment, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateAttachment not implemented")
}
func (UnimplementedAttachmentServiceServer) DeleteAttachment(context.Context, *DeleteAttachmentRequest) (*emptypb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteAttachment not implemented")
}
func (UnimplementedAttachmentServiceServer) mustEmbedUnimplementedAttachmentServiceServer() {}
func (UnimplementedAttachmentServiceServer) testEmbeddedByValue() {}
// UnsafeAttachmentServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to AttachmentServiceServer will
// result in compilation errors.
type UnsafeAttachmentServiceServer interface {
mustEmbedUnimplementedAttachmentServiceServer()
}
func RegisterAttachmentServiceServer(s grpc.ServiceRegistrar, srv AttachmentServiceServer) {
// If the following call pancis, it indicates UnimplementedAttachmentServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&AttachmentService_ServiceDesc, srv)
}
func _AttachmentService_CreateAttachment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateAttachmentRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AttachmentServiceServer).CreateAttachment(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: AttachmentService_CreateAttachment_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AttachmentServiceServer).CreateAttachment(ctx, req.(*CreateAttachmentRequest))
}
return interceptor(ctx, in, info, handler)
}
func _AttachmentService_ListAttachments_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListAttachmentsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AttachmentServiceServer).ListAttachments(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: AttachmentService_ListAttachments_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AttachmentServiceServer).ListAttachments(ctx, req.(*ListAttachmentsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _AttachmentService_GetAttachment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetAttachmentRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AttachmentServiceServer).GetAttachment(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: AttachmentService_GetAttachment_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AttachmentServiceServer).GetAttachment(ctx, req.(*GetAttachmentRequest))
}
return interceptor(ctx, in, info, handler)
}
func _AttachmentService_GetAttachmentBinary_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetAttachmentBinaryRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AttachmentServiceServer).GetAttachmentBinary(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: AttachmentService_GetAttachmentBinary_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AttachmentServiceServer).GetAttachmentBinary(ctx, req.(*GetAttachmentBinaryRequest))
}
return interceptor(ctx, in, info, handler)
}
func _AttachmentService_UpdateAttachment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdateAttachmentRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AttachmentServiceServer).UpdateAttachment(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: AttachmentService_UpdateAttachment_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AttachmentServiceServer).UpdateAttachment(ctx, req.(*UpdateAttachmentRequest))
}
return interceptor(ctx, in, info, handler)
}
func _AttachmentService_DeleteAttachment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteAttachmentRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AttachmentServiceServer).DeleteAttachment(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: AttachmentService_DeleteAttachment_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AttachmentServiceServer).DeleteAttachment(ctx, req.(*DeleteAttachmentRequest))
}
return interceptor(ctx, in, info, handler)
}
// AttachmentService_ServiceDesc is the grpc.ServiceDesc for AttachmentService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var AttachmentService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "memos.api.v1.AttachmentService",
HandlerType: (*AttachmentServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "CreateAttachment",
Handler: _AttachmentService_CreateAttachment_Handler,
},
{
MethodName: "ListAttachments",
Handler: _AttachmentService_ListAttachments_Handler,
},
{
MethodName: "GetAttachment",
Handler: _AttachmentService_GetAttachment_Handler,
},
{
MethodName: "GetAttachmentBinary",
Handler: _AttachmentService_GetAttachmentBinary_Handler,
},
{
MethodName: "UpdateAttachment",
Handler: _AttachmentService_UpdateAttachment_Handler,
},
{
MethodName: "DeleteAttachment",
Handler: _AttachmentService_DeleteAttachment_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "api/v1/attachment_service.proto",
}

@ -143,7 +143,7 @@ type Memo struct {
Visibility Visibility `protobuf:"varint,10,opt,name=visibility,proto3,enum=memos.api.v1.Visibility" json:"visibility,omitempty"`
Tags []string `protobuf:"bytes,11,rep,name=tags,proto3" json:"tags,omitempty"`
Pinned bool `protobuf:"varint,12,opt,name=pinned,proto3" json:"pinned,omitempty"`
Resources []*Resource `protobuf:"bytes,14,rep,name=resources,proto3" json:"resources,omitempty"`
Attachments []*Attachment `protobuf:"bytes,14,rep,name=attachments,proto3" json:"attachments,omitempty"`
Relations []*MemoRelation `protobuf:"bytes,15,rep,name=relations,proto3" json:"relations,omitempty"`
Reactions []*Reaction `protobuf:"bytes,16,rep,name=reactions,proto3" json:"reactions,omitempty"`
Property *Memo_Property `protobuf:"bytes,17,opt,name=property,proto3" json:"property,omitempty"`
@ -265,9 +265,9 @@ func (x *Memo) GetPinned() bool {
return false
}
func (x *Memo) GetResources() []*Resource {
func (x *Memo) GetAttachments() []*Attachment {
if x != nil {
return x.Resources
return x.Attachments
}
return nil
}
@ -856,29 +856,29 @@ func (x *DeleteMemoTagRequest) GetDeleteRelatedMemos() bool {
return false
}
type SetMemoResourcesRequest struct {
type SetMemoAttachmentsRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The name of the memo.
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Resources []*Resource `protobuf:"bytes,2,rep,name=resources,proto3" json:"resources,omitempty"`
Attachments []*Attachment `protobuf:"bytes,2,rep,name=attachments,proto3" json:"attachments,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SetMemoResourcesRequest) Reset() {
*x = SetMemoResourcesRequest{}
func (x *SetMemoAttachmentsRequest) Reset() {
*x = SetMemoAttachmentsRequest{}
mi := &file_api_v1_memo_service_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SetMemoResourcesRequest) String() string {
func (x *SetMemoAttachmentsRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SetMemoResourcesRequest) ProtoMessage() {}
func (*SetMemoAttachmentsRequest) ProtoMessage() {}
func (x *SetMemoResourcesRequest) ProtoReflect() protoreflect.Message {
func (x *SetMemoAttachmentsRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_memo_service_proto_msgTypes[10]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -890,26 +890,26 @@ func (x *SetMemoResourcesRequest) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use SetMemoResourcesRequest.ProtoReflect.Descriptor instead.
func (*SetMemoResourcesRequest) Descriptor() ([]byte, []int) {
// Deprecated: Use SetMemoAttachmentsRequest.ProtoReflect.Descriptor instead.
func (*SetMemoAttachmentsRequest) Descriptor() ([]byte, []int) {
return file_api_v1_memo_service_proto_rawDescGZIP(), []int{10}
}
func (x *SetMemoResourcesRequest) GetName() string {
func (x *SetMemoAttachmentsRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *SetMemoResourcesRequest) GetResources() []*Resource {
func (x *SetMemoAttachmentsRequest) GetAttachments() []*Attachment {
if x != nil {
return x.Resources
return x.Attachments
}
return nil
}
type ListMemoResourcesRequest struct {
type ListMemoAttachmentsRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The name of the memo.
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
@ -917,20 +917,20 @@ type ListMemoResourcesRequest struct {
sizeCache protoimpl.SizeCache
}
func (x *ListMemoResourcesRequest) Reset() {
*x = ListMemoResourcesRequest{}
func (x *ListMemoAttachmentsRequest) Reset() {
*x = ListMemoAttachmentsRequest{}
mi := &file_api_v1_memo_service_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListMemoResourcesRequest) String() string {
func (x *ListMemoAttachmentsRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListMemoResourcesRequest) ProtoMessage() {}
func (*ListMemoAttachmentsRequest) ProtoMessage() {}
func (x *ListMemoResourcesRequest) ProtoReflect() protoreflect.Message {
func (x *ListMemoAttachmentsRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_memo_service_proto_msgTypes[11]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -942,39 +942,39 @@ func (x *ListMemoResourcesRequest) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use ListMemoResourcesRequest.ProtoReflect.Descriptor instead.
func (*ListMemoResourcesRequest) Descriptor() ([]byte, []int) {
// Deprecated: Use ListMemoAttachmentsRequest.ProtoReflect.Descriptor instead.
func (*ListMemoAttachmentsRequest) Descriptor() ([]byte, []int) {
return file_api_v1_memo_service_proto_rawDescGZIP(), []int{11}
}
func (x *ListMemoResourcesRequest) GetName() string {
func (x *ListMemoAttachmentsRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
type ListMemoResourcesResponse struct {
type ListMemoAttachmentsResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Resources []*Resource `protobuf:"bytes,1,rep,name=resources,proto3" json:"resources,omitempty"`
Attachments []*Attachment `protobuf:"bytes,1,rep,name=attachments,proto3" json:"attachments,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ListMemoResourcesResponse) Reset() {
*x = ListMemoResourcesResponse{}
func (x *ListMemoAttachmentsResponse) Reset() {
*x = ListMemoAttachmentsResponse{}
mi := &file_api_v1_memo_service_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListMemoResourcesResponse) String() string {
func (x *ListMemoAttachmentsResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListMemoResourcesResponse) ProtoMessage() {}
func (*ListMemoAttachmentsResponse) ProtoMessage() {}
func (x *ListMemoResourcesResponse) ProtoReflect() protoreflect.Message {
func (x *ListMemoAttachmentsResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_memo_service_proto_msgTypes[12]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -986,14 +986,14 @@ func (x *ListMemoResourcesResponse) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use ListMemoResourcesResponse.ProtoReflect.Descriptor instead.
func (*ListMemoResourcesResponse) Descriptor() ([]byte, []int) {
// Deprecated: Use ListMemoAttachmentsResponse.ProtoReflect.Descriptor instead.
func (*ListMemoAttachmentsResponse) Descriptor() ([]byte, []int) {
return file_api_v1_memo_service_proto_rawDescGZIP(), []int{12}
}
func (x *ListMemoResourcesResponse) GetResources() []*Resource {
func (x *ListMemoAttachmentsResponse) GetAttachments() []*Attachment {
if x != nil {
return x.Resources
return x.Attachments
}
return nil
}
@ -1666,7 +1666,7 @@ var File_api_v1_memo_service_proto protoreflect.FileDescriptor
const file_api_v1_memo_service_proto_rawDesc = "" +
"\n" +
"\x19api/v1/memo_service.proto\x12\fmemos.api.v1\x1a\x13api/v1/common.proto\x1a\x1dapi/v1/markdown_service.proto\x1a\x1dapi/v1/reaction_service.proto\x1a\x1dapi/v1/resource_service.proto\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a google/protobuf/field_mask.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xee\a\n" +
"\x19api/v1/memo_service.proto\x12\fmemos.api.v1\x1a\x1fapi/v1/attachment_service.proto\x1a\x13api/v1/common.proto\x1a\x1dapi/v1/markdown_service.proto\x1a\x1dapi/v1/reaction_service.proto\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a google/protobuf/field_mask.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xf4\a\n" +
"\x04Memo\x12\x1a\n" +
"\x04name\x18\x01 \x01(\tB\x06\xe0A\x03\xe0A\bR\x04name\x12)\n" +
"\x05state\x18\x03 \x01(\x0e2\x13.memos.api.v1.StateR\x05state\x12\x18\n" +
@ -1683,8 +1683,8 @@ const file_api_v1_memo_service_proto_rawDesc = "" +
" \x01(\x0e2\x18.memos.api.v1.VisibilityR\n" +
"visibility\x12\x17\n" +
"\x04tags\x18\v \x03(\tB\x03\xe0A\x03R\x04tags\x12\x16\n" +
"\x06pinned\x18\f \x01(\bR\x06pinned\x124\n" +
"\tresources\x18\x0e \x03(\v2\x16.memos.api.v1.ResourceR\tresources\x128\n" +
"\x06pinned\x18\f \x01(\bR\x06pinned\x12:\n" +
"\vattachments\x18\x0e \x03(\v2\x18.memos.api.v1.AttachmentR\vattachments\x128\n" +
"\trelations\x18\x0f \x03(\v2\x1a.memos.api.v1.MemoRelationR\trelations\x129\n" +
"\treactions\x18\x10 \x03(\v2\x16.memos.api.v1.ReactionB\x03\xe0A\x03R\treactions\x12<\n" +
"\bproperty\x18\x11 \x01(\v2\x1b.memos.api.v1.Memo.PropertyB\x03\xe0A\x03R\bproperty\x12 \n" +
@ -1733,14 +1733,14 @@ const file_api_v1_memo_service_proto_rawDesc = "" +
"\x14DeleteMemoTagRequest\x12\x16\n" +
"\x06parent\x18\x01 \x01(\tR\x06parent\x12\x10\n" +
"\x03tag\x18\x02 \x01(\tR\x03tag\x120\n" +
"\x14delete_related_memos\x18\x03 \x01(\bR\x12deleteRelatedMemos\"c\n" +
"\x17SetMemoResourcesRequest\x12\x12\n" +
"\x04name\x18\x01 \x01(\tR\x04name\x124\n" +
"\tresources\x18\x02 \x03(\v2\x16.memos.api.v1.ResourceR\tresources\".\n" +
"\x18ListMemoResourcesRequest\x12\x12\n" +
"\x04name\x18\x01 \x01(\tR\x04name\"Q\n" +
"\x19ListMemoResourcesResponse\x124\n" +
"\tresources\x18\x01 \x03(\v2\x16.memos.api.v1.ResourceR\tresources\"\xc3\x02\n" +
"\x14delete_related_memos\x18\x03 \x01(\bR\x12deleteRelatedMemos\"k\n" +
"\x19SetMemoAttachmentsRequest\x12\x12\n" +
"\x04name\x18\x01 \x01(\tR\x04name\x12:\n" +
"\vattachments\x18\x02 \x03(\v2\x18.memos.api.v1.AttachmentR\vattachments\"0\n" +
"\x1aListMemoAttachmentsRequest\x12\x12\n" +
"\x04name\x18\x01 \x01(\tR\x04name\"Y\n" +
"\x1bListMemoAttachmentsResponse\x12:\n" +
"\vattachments\x18\x01 \x03(\v2\x18.memos.api.v1.AttachmentR\vattachments\"\xc3\x02\n" +
"\fMemoRelation\x123\n" +
"\x04memo\x18\x01 \x01(\v2\x1f.memos.api.v1.MemoRelation.MemoR\x04memo\x12B\n" +
"\frelated_memo\x18\x02 \x01(\v2\x1f.memos.api.v1.MemoRelation.MemoR\vrelatedMemo\x123\n" +
@ -1782,7 +1782,7 @@ const file_api_v1_memo_service_proto_rawDesc = "" +
"\aPRIVATE\x10\x01\x12\r\n" +
"\tPROTECTED\x10\x02\x12\n" +
"\n" +
"\x06PUBLIC\x10\x032\xbf\x10\n" +
"\x06PUBLIC\x10\x032\xcd\x10\n" +
"\vMemoService\x12^\n" +
"\n" +
"CreateMemo\x12\x1f.memos.api.v1.CreateMemoRequest\x1a\x12.memos.api.v1.Memo\"\x1b\x82\xd3\xe4\x93\x02\x15:\x04memo\"\r/api/v1/memos\x12\x85\x01\n" +
@ -1793,9 +1793,9 @@ const file_api_v1_memo_service_proto_rawDesc = "" +
"\n" +
"DeleteMemo\x12\x1f.memos.api.v1.DeleteMemoRequest\x1a\x16.google.protobuf.Empty\"%\xdaA\x04name\x82\xd3\xe4\x93\x02\x18*\x16/api/v1/{name=memos/*}\x12|\n" +
"\rRenameMemoTag\x12\".memos.api.v1.RenameMemoTagRequest\x1a\x16.google.protobuf.Empty\"/\x82\xd3\xe4\x93\x02):\x01*2$/api/v1/{parent=memos/*}/tags:rename\x12x\n" +
"\rDeleteMemoTag\x12\".memos.api.v1.DeleteMemoTagRequest\x1a\x16.google.protobuf.Empty\"+\x82\xd3\xe4\x93\x02%*#/api/v1/{parent=memos/*}/tags/{tag}\x12\x85\x01\n" +
"\x10SetMemoResources\x12%.memos.api.v1.SetMemoResourcesRequest\x1a\x16.google.protobuf.Empty\"2\xdaA\x04name\x82\xd3\xe4\x93\x02%:\x01*2 /api/v1/{name=memos/*}/resources\x12\x95\x01\n" +
"\x11ListMemoResources\x12&.memos.api.v1.ListMemoResourcesRequest\x1a'.memos.api.v1.ListMemoResourcesResponse\"/\xdaA\x04name\x82\xd3\xe4\x93\x02\"\x12 /api/v1/{name=memos/*}/resources\x12\x85\x01\n" +
"\rDeleteMemoTag\x12\".memos.api.v1.DeleteMemoTagRequest\x1a\x16.google.protobuf.Empty\"+\x82\xd3\xe4\x93\x02%*#/api/v1/{parent=memos/*}/tags/{tag}\x12\x8b\x01\n" +
"\x12SetMemoAttachments\x12'.memos.api.v1.SetMemoAttachmentsRequest\x1a\x16.google.protobuf.Empty\"4\xdaA\x04name\x82\xd3\xe4\x93\x02':\x01*2\"/api/v1/{name=memos/*}/attachments\x12\x9d\x01\n" +
"\x13ListMemoAttachments\x12(.memos.api.v1.ListMemoAttachmentsRequest\x1a).memos.api.v1.ListMemoAttachmentsResponse\"1\xdaA\x04name\x82\xd3\xe4\x93\x02$\x12\"/api/v1/{name=memos/*}/attachments\x12\x85\x01\n" +
"\x10SetMemoRelations\x12%.memos.api.v1.SetMemoRelationsRequest\x1a\x16.google.protobuf.Empty\"2\xdaA\x04name\x82\xd3\xe4\x93\x02%:\x01*2 /api/v1/{name=memos/*}/relations\x12\x95\x01\n" +
"\x11ListMemoRelations\x12&.memos.api.v1.ListMemoRelationsRequest\x1a'.memos.api.v1.ListMemoRelationsResponse\"/\xdaA\x04name\x82\xd3\xe4\x93\x02\"\x12 /api/v1/{name=memos/*}/relations\x12\x88\x01\n" +
"\x11CreateMemoComment\x12&.memos.api.v1.CreateMemoCommentRequest\x1a\x12.memos.api.v1.Memo\"7\xdaA\x04name\x82\xd3\xe4\x93\x02*:\acomment\"\x1f/api/v1/{name=memos/*}/comments\x12\x91\x01\n" +
@ -1832,9 +1832,9 @@ var file_api_v1_memo_service_proto_goTypes = []any{
(*DeleteMemoRequest)(nil), // 9: memos.api.v1.DeleteMemoRequest
(*RenameMemoTagRequest)(nil), // 10: memos.api.v1.RenameMemoTagRequest
(*DeleteMemoTagRequest)(nil), // 11: memos.api.v1.DeleteMemoTagRequest
(*SetMemoResourcesRequest)(nil), // 12: memos.api.v1.SetMemoResourcesRequest
(*ListMemoResourcesRequest)(nil), // 13: memos.api.v1.ListMemoResourcesRequest
(*ListMemoResourcesResponse)(nil), // 14: memos.api.v1.ListMemoResourcesResponse
(*SetMemoAttachmentsRequest)(nil), // 12: memos.api.v1.SetMemoAttachmentsRequest
(*ListMemoAttachmentsRequest)(nil), // 13: memos.api.v1.ListMemoAttachmentsRequest
(*ListMemoAttachmentsResponse)(nil), // 14: memos.api.v1.ListMemoAttachmentsResponse
(*MemoRelation)(nil), // 15: memos.api.v1.MemoRelation
(*SetMemoRelationsRequest)(nil), // 16: memos.api.v1.SetMemoRelationsRequest
(*ListMemoRelationsRequest)(nil), // 17: memos.api.v1.ListMemoRelationsRequest
@ -1851,7 +1851,7 @@ var file_api_v1_memo_service_proto_goTypes = []any{
(State)(0), // 28: memos.api.v1.State
(*timestamppb.Timestamp)(nil), // 29: google.protobuf.Timestamp
(*Node)(nil), // 30: memos.api.v1.Node
(*Resource)(nil), // 31: memos.api.v1.Resource
(*Attachment)(nil), // 31: memos.api.v1.Attachment
(*Reaction)(nil), // 32: memos.api.v1.Reaction
(Direction)(0), // 33: memos.api.v1.Direction
(*fieldmaskpb.FieldMask)(nil), // 34: google.protobuf.FieldMask
@ -1864,7 +1864,7 @@ var file_api_v1_memo_service_proto_depIdxs = []int32{
29, // 3: memos.api.v1.Memo.display_time:type_name -> google.protobuf.Timestamp
30, // 4: memos.api.v1.Memo.nodes:type_name -> memos.api.v1.Node
0, // 5: memos.api.v1.Memo.visibility:type_name -> memos.api.v1.Visibility
31, // 6: memos.api.v1.Memo.resources:type_name -> memos.api.v1.Resource
31, // 6: memos.api.v1.Memo.attachments:type_name -> memos.api.v1.Attachment
15, // 7: memos.api.v1.Memo.relations:type_name -> memos.api.v1.MemoRelation
32, // 8: memos.api.v1.Memo.reactions:type_name -> memos.api.v1.Reaction
26, // 9: memos.api.v1.Memo.property:type_name -> memos.api.v1.Memo.Property
@ -1875,8 +1875,8 @@ var file_api_v1_memo_service_proto_depIdxs = []int32{
2, // 14: memos.api.v1.ListMemosResponse.memos:type_name -> memos.api.v1.Memo
2, // 15: memos.api.v1.UpdateMemoRequest.memo:type_name -> memos.api.v1.Memo
34, // 16: memos.api.v1.UpdateMemoRequest.update_mask:type_name -> google.protobuf.FieldMask
31, // 17: memos.api.v1.SetMemoResourcesRequest.resources:type_name -> memos.api.v1.Resource
31, // 18: memos.api.v1.ListMemoResourcesResponse.resources:type_name -> memos.api.v1.Resource
31, // 17: memos.api.v1.SetMemoAttachmentsRequest.attachments:type_name -> memos.api.v1.Attachment
31, // 18: memos.api.v1.ListMemoAttachmentsResponse.attachments:type_name -> memos.api.v1.Attachment
27, // 19: memos.api.v1.MemoRelation.memo:type_name -> memos.api.v1.MemoRelation.Memo
27, // 20: memos.api.v1.MemoRelation.related_memo:type_name -> memos.api.v1.MemoRelation.Memo
1, // 21: memos.api.v1.MemoRelation.type:type_name -> memos.api.v1.MemoRelation.Type
@ -1893,8 +1893,8 @@ var file_api_v1_memo_service_proto_depIdxs = []int32{
9, // 32: memos.api.v1.MemoService.DeleteMemo:input_type -> memos.api.v1.DeleteMemoRequest
10, // 33: memos.api.v1.MemoService.RenameMemoTag:input_type -> memos.api.v1.RenameMemoTagRequest
11, // 34: memos.api.v1.MemoService.DeleteMemoTag:input_type -> memos.api.v1.DeleteMemoTagRequest
12, // 35: memos.api.v1.MemoService.SetMemoResources:input_type -> memos.api.v1.SetMemoResourcesRequest
13, // 36: memos.api.v1.MemoService.ListMemoResources:input_type -> memos.api.v1.ListMemoResourcesRequest
12, // 35: memos.api.v1.MemoService.SetMemoAttachments:input_type -> memos.api.v1.SetMemoAttachmentsRequest
13, // 36: memos.api.v1.MemoService.ListMemoAttachments:input_type -> memos.api.v1.ListMemoAttachmentsRequest
16, // 37: memos.api.v1.MemoService.SetMemoRelations:input_type -> memos.api.v1.SetMemoRelationsRequest
17, // 38: memos.api.v1.MemoService.ListMemoRelations:input_type -> memos.api.v1.ListMemoRelationsRequest
19, // 39: memos.api.v1.MemoService.CreateMemoComment:input_type -> memos.api.v1.CreateMemoCommentRequest
@ -1909,8 +1909,8 @@ var file_api_v1_memo_service_proto_depIdxs = []int32{
35, // 48: memos.api.v1.MemoService.DeleteMemo:output_type -> google.protobuf.Empty
35, // 49: memos.api.v1.MemoService.RenameMemoTag:output_type -> google.protobuf.Empty
35, // 50: memos.api.v1.MemoService.DeleteMemoTag:output_type -> google.protobuf.Empty
35, // 51: memos.api.v1.MemoService.SetMemoResources:output_type -> google.protobuf.Empty
14, // 52: memos.api.v1.MemoService.ListMemoResources:output_type -> memos.api.v1.ListMemoResourcesResponse
35, // 51: memos.api.v1.MemoService.SetMemoAttachments:output_type -> google.protobuf.Empty
14, // 52: memos.api.v1.MemoService.ListMemoAttachments:output_type -> memos.api.v1.ListMemoAttachmentsResponse
35, // 53: memos.api.v1.MemoService.SetMemoRelations:output_type -> google.protobuf.Empty
18, // 54: memos.api.v1.MemoService.ListMemoRelations:output_type -> memos.api.v1.ListMemoRelationsResponse
2, // 55: memos.api.v1.MemoService.CreateMemoComment:output_type -> memos.api.v1.Memo
@ -1930,10 +1930,10 @@ func file_api_v1_memo_service_proto_init() {
if File_api_v1_memo_service_proto != nil {
return
}
file_api_v1_attachment_service_proto_init()
file_api_v1_common_proto_init()
file_api_v1_markdown_service_proto_init()
file_api_v1_reaction_service_proto_init()
file_api_v1_resource_service_proto_init()
file_api_v1_memo_service_proto_msgTypes[0].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{

@ -404,9 +404,9 @@ func local_request_MemoService_DeleteMemoTag_0(ctx context.Context, marshaler ru
return msg, metadata, err
}
func request_MemoService_SetMemoResources_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
func request_MemoService_SetMemoAttachments_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq SetMemoResourcesRequest
protoReq SetMemoAttachmentsRequest
metadata runtime.ServerMetadata
err error
)
@ -421,13 +421,13 @@ func request_MemoService_SetMemoResources_0(ctx context.Context, marshaler runti
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
msg, err := client.SetMemoResources(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
msg, err := client.SetMemoAttachments(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_MemoService_SetMemoResources_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
func local_request_MemoService_SetMemoAttachments_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq SetMemoResourcesRequest
protoReq SetMemoAttachmentsRequest
metadata runtime.ServerMetadata
err error
)
@ -442,13 +442,13 @@ func local_request_MemoService_SetMemoResources_0(ctx context.Context, marshaler
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
msg, err := server.SetMemoResources(ctx, &protoReq)
msg, err := server.SetMemoAttachments(ctx, &protoReq)
return msg, metadata, err
}
func request_MemoService_ListMemoResources_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
func request_MemoService_ListMemoAttachments_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq ListMemoResourcesRequest
protoReq ListMemoAttachmentsRequest
metadata runtime.ServerMetadata
err error
)
@ -461,13 +461,13 @@ func request_MemoService_ListMemoResources_0(ctx context.Context, marshaler runt
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
msg, err := client.ListMemoResources(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
msg, err := client.ListMemoAttachments(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_MemoService_ListMemoResources_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
func local_request_MemoService_ListMemoAttachments_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq ListMemoResourcesRequest
protoReq ListMemoAttachmentsRequest
metadata runtime.ServerMetadata
err error
)
@ -479,7 +479,7 @@ func local_request_MemoService_ListMemoResources_0(ctx context.Context, marshale
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
msg, err := server.ListMemoResources(ctx, &protoReq)
msg, err := server.ListMemoAttachments(ctx, &protoReq)
return msg, metadata, err
}
@ -923,45 +923,45 @@ func RegisterMemoServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
}
forward_MemoService_DeleteMemoTag_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPatch, pattern_MemoService_SetMemoResources_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
mux.Handle(http.MethodPatch, pattern_MemoService_SetMemoAttachments_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.MemoService/SetMemoResources", runtime.WithHTTPPathPattern("/api/v1/{name=memos/*}/resources"))
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.MemoService/SetMemoAttachments", runtime.WithHTTPPathPattern("/api/v1/{name=memos/*}/attachments"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_MemoService_SetMemoResources_0(annotatedContext, inboundMarshaler, server, req, pathParams)
resp, md, err := local_request_MemoService_SetMemoAttachments_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_MemoService_SetMemoResources_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
forward_MemoService_SetMemoAttachments_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodGet, pattern_MemoService_ListMemoResources_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
mux.Handle(http.MethodGet, pattern_MemoService_ListMemoAttachments_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.MemoService/ListMemoResources", runtime.WithHTTPPathPattern("/api/v1/{name=memos/*}/resources"))
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.MemoService/ListMemoAttachments", runtime.WithHTTPPathPattern("/api/v1/{name=memos/*}/attachments"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_MemoService_ListMemoResources_0(annotatedContext, inboundMarshaler, server, req, pathParams)
resp, md, err := local_request_MemoService_ListMemoAttachments_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_MemoService_ListMemoResources_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
forward_MemoService_ListMemoAttachments_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPatch, pattern_MemoService_SetMemoRelations_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
@ -1279,39 +1279,39 @@ func RegisterMemoServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
}
forward_MemoService_DeleteMemoTag_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPatch, pattern_MemoService_SetMemoResources_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
mux.Handle(http.MethodPatch, pattern_MemoService_SetMemoAttachments_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.MemoService/SetMemoResources", runtime.WithHTTPPathPattern("/api/v1/{name=memos/*}/resources"))
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.MemoService/SetMemoAttachments", runtime.WithHTTPPathPattern("/api/v1/{name=memos/*}/attachments"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_MemoService_SetMemoResources_0(annotatedContext, inboundMarshaler, client, req, pathParams)
resp, md, err := request_MemoService_SetMemoAttachments_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_MemoService_SetMemoResources_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
forward_MemoService_SetMemoAttachments_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodGet, pattern_MemoService_ListMemoResources_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
mux.Handle(http.MethodGet, pattern_MemoService_ListMemoAttachments_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.MemoService/ListMemoResources", runtime.WithHTTPPathPattern("/api/v1/{name=memos/*}/resources"))
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.MemoService/ListMemoAttachments", runtime.WithHTTPPathPattern("/api/v1/{name=memos/*}/attachments"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_MemoService_ListMemoResources_0(annotatedContext, inboundMarshaler, client, req, pathParams)
resp, md, err := request_MemoService_ListMemoAttachments_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_MemoService_ListMemoResources_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
forward_MemoService_ListMemoAttachments_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPatch, pattern_MemoService_SetMemoRelations_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
@ -1444,8 +1444,8 @@ var (
pattern_MemoService_DeleteMemo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "memos", "name"}, ""))
pattern_MemoService_RenameMemoTag_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", "parent", "tags"}, "rename"))
pattern_MemoService_DeleteMemoTag_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"api", "v1", "memos", "parent", "tags", "tag"}, ""))
pattern_MemoService_SetMemoResources_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", "resources"}, ""))
pattern_MemoService_ListMemoResources_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", "resources"}, ""))
pattern_MemoService_SetMemoAttachments_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", "attachments"}, ""))
pattern_MemoService_ListMemoAttachments_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", "attachments"}, ""))
pattern_MemoService_SetMemoRelations_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", "relations"}, ""))
pattern_MemoService_ListMemoRelations_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", "relations"}, ""))
pattern_MemoService_CreateMemoComment_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"}, ""))
@ -1464,8 +1464,8 @@ var (
forward_MemoService_DeleteMemo_0 = runtime.ForwardResponseMessage
forward_MemoService_RenameMemoTag_0 = runtime.ForwardResponseMessage
forward_MemoService_DeleteMemoTag_0 = runtime.ForwardResponseMessage
forward_MemoService_SetMemoResources_0 = runtime.ForwardResponseMessage
forward_MemoService_ListMemoResources_0 = runtime.ForwardResponseMessage
forward_MemoService_SetMemoAttachments_0 = runtime.ForwardResponseMessage
forward_MemoService_ListMemoAttachments_0 = runtime.ForwardResponseMessage
forward_MemoService_SetMemoRelations_0 = runtime.ForwardResponseMessage
forward_MemoService_ListMemoRelations_0 = runtime.ForwardResponseMessage
forward_MemoService_CreateMemoComment_0 = runtime.ForwardResponseMessage

@ -27,8 +27,8 @@ const (
MemoService_DeleteMemo_FullMethodName = "/memos.api.v1.MemoService/DeleteMemo"
MemoService_RenameMemoTag_FullMethodName = "/memos.api.v1.MemoService/RenameMemoTag"
MemoService_DeleteMemoTag_FullMethodName = "/memos.api.v1.MemoService/DeleteMemoTag"
MemoService_SetMemoResources_FullMethodName = "/memos.api.v1.MemoService/SetMemoResources"
MemoService_ListMemoResources_FullMethodName = "/memos.api.v1.MemoService/ListMemoResources"
MemoService_SetMemoAttachments_FullMethodName = "/memos.api.v1.MemoService/SetMemoAttachments"
MemoService_ListMemoAttachments_FullMethodName = "/memos.api.v1.MemoService/ListMemoAttachments"
MemoService_SetMemoRelations_FullMethodName = "/memos.api.v1.MemoService/SetMemoRelations"
MemoService_ListMemoRelations_FullMethodName = "/memos.api.v1.MemoService/ListMemoRelations"
MemoService_CreateMemoComment_FullMethodName = "/memos.api.v1.MemoService/CreateMemoComment"
@ -56,10 +56,10 @@ type MemoServiceClient interface {
RenameMemoTag(ctx context.Context, in *RenameMemoTagRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
// DeleteMemoTag deletes a tag for a memo.
DeleteMemoTag(ctx context.Context, in *DeleteMemoTagRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
// SetMemoResources sets resources for a memo.
SetMemoResources(ctx context.Context, in *SetMemoResourcesRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
// ListMemoResources lists resources for a memo.
ListMemoResources(ctx context.Context, in *ListMemoResourcesRequest, opts ...grpc.CallOption) (*ListMemoResourcesResponse, error)
// SetMemoAttachments sets attachments for a memo.
SetMemoAttachments(ctx context.Context, in *SetMemoAttachmentsRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
// ListMemoAttachments lists attachments for a memo.
ListMemoAttachments(ctx context.Context, in *ListMemoAttachmentsRequest, opts ...grpc.CallOption) (*ListMemoAttachmentsResponse, error)
// SetMemoRelations sets relations for a memo.
SetMemoRelations(ctx context.Context, in *SetMemoRelationsRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
// ListMemoRelations lists relations for a memo.
@ -154,20 +154,20 @@ func (c *memoServiceClient) DeleteMemoTag(ctx context.Context, in *DeleteMemoTag
return out, nil
}
func (c *memoServiceClient) SetMemoResources(ctx context.Context, in *SetMemoResourcesRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
func (c *memoServiceClient) SetMemoAttachments(ctx context.Context, in *SetMemoAttachmentsRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, MemoService_SetMemoResources_FullMethodName, in, out, cOpts...)
err := c.cc.Invoke(ctx, MemoService_SetMemoAttachments_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *memoServiceClient) ListMemoResources(ctx context.Context, in *ListMemoResourcesRequest, opts ...grpc.CallOption) (*ListMemoResourcesResponse, error) {
func (c *memoServiceClient) ListMemoAttachments(ctx context.Context, in *ListMemoAttachmentsRequest, opts ...grpc.CallOption) (*ListMemoAttachmentsResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ListMemoResourcesResponse)
err := c.cc.Invoke(ctx, MemoService_ListMemoResources_FullMethodName, in, out, cOpts...)
out := new(ListMemoAttachmentsResponse)
err := c.cc.Invoke(ctx, MemoService_ListMemoAttachments_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
@ -262,10 +262,10 @@ type MemoServiceServer interface {
RenameMemoTag(context.Context, *RenameMemoTagRequest) (*emptypb.Empty, error)
// DeleteMemoTag deletes a tag for a memo.
DeleteMemoTag(context.Context, *DeleteMemoTagRequest) (*emptypb.Empty, error)
// SetMemoResources sets resources for a memo.
SetMemoResources(context.Context, *SetMemoResourcesRequest) (*emptypb.Empty, error)
// ListMemoResources lists resources for a memo.
ListMemoResources(context.Context, *ListMemoResourcesRequest) (*ListMemoResourcesResponse, error)
// SetMemoAttachments sets attachments for a memo.
SetMemoAttachments(context.Context, *SetMemoAttachmentsRequest) (*emptypb.Empty, error)
// ListMemoAttachments lists attachments for a memo.
ListMemoAttachments(context.Context, *ListMemoAttachmentsRequest) (*ListMemoAttachmentsResponse, error)
// SetMemoRelations sets relations for a memo.
SetMemoRelations(context.Context, *SetMemoRelationsRequest) (*emptypb.Empty, error)
// ListMemoRelations lists relations for a memo.
@ -311,11 +311,11 @@ func (UnimplementedMemoServiceServer) RenameMemoTag(context.Context, *RenameMemo
func (UnimplementedMemoServiceServer) DeleteMemoTag(context.Context, *DeleteMemoTagRequest) (*emptypb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteMemoTag not implemented")
}
func (UnimplementedMemoServiceServer) SetMemoResources(context.Context, *SetMemoResourcesRequest) (*emptypb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method SetMemoResources not implemented")
func (UnimplementedMemoServiceServer) SetMemoAttachments(context.Context, *SetMemoAttachmentsRequest) (*emptypb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method SetMemoAttachments not implemented")
}
func (UnimplementedMemoServiceServer) ListMemoResources(context.Context, *ListMemoResourcesRequest) (*ListMemoResourcesResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListMemoResources not implemented")
func (UnimplementedMemoServiceServer) ListMemoAttachments(context.Context, *ListMemoAttachmentsRequest) (*ListMemoAttachmentsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListMemoAttachments not implemented")
}
func (UnimplementedMemoServiceServer) SetMemoRelations(context.Context, *SetMemoRelationsRequest) (*emptypb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method SetMemoRelations not implemented")
@ -485,38 +485,38 @@ func _MemoService_DeleteMemoTag_Handler(srv interface{}, ctx context.Context, de
return interceptor(ctx, in, info, handler)
}
func _MemoService_SetMemoResources_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SetMemoResourcesRequest)
func _MemoService_SetMemoAttachments_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SetMemoAttachmentsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MemoServiceServer).SetMemoResources(ctx, in)
return srv.(MemoServiceServer).SetMemoAttachments(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: MemoService_SetMemoResources_FullMethodName,
FullMethod: MemoService_SetMemoAttachments_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MemoServiceServer).SetMemoResources(ctx, req.(*SetMemoResourcesRequest))
return srv.(MemoServiceServer).SetMemoAttachments(ctx, req.(*SetMemoAttachmentsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MemoService_ListMemoResources_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListMemoResourcesRequest)
func _MemoService_ListMemoAttachments_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListMemoAttachmentsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MemoServiceServer).ListMemoResources(ctx, in)
return srv.(MemoServiceServer).ListMemoAttachments(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: MemoService_ListMemoResources_FullMethodName,
FullMethod: MemoService_ListMemoAttachments_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MemoServiceServer).ListMemoResources(ctx, req.(*ListMemoResourcesRequest))
return srv.(MemoServiceServer).ListMemoAttachments(ctx, req.(*ListMemoAttachmentsRequest))
}
return interceptor(ctx, in, info, handler)
}
@ -683,12 +683,12 @@ var MemoService_ServiceDesc = grpc.ServiceDesc{
Handler: _MemoService_DeleteMemoTag_Handler,
},
{
MethodName: "SetMemoResources",
Handler: _MemoService_SetMemoResources_Handler,
MethodName: "SetMemoAttachments",
Handler: _MemoService_SetMemoAttachments_Handler,
},
{
MethodName: "ListMemoResources",
Handler: _MemoService_ListMemoResources_Handler,
MethodName: "ListMemoAttachments",
Handler: _MemoService_ListMemoAttachments_Handler,
},
{
MethodName: "SetMemoRelations",

@ -1,578 +0,0 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc (unknown)
// source: api/v1/resource_service.proto
package apiv1
import (
_ "google.golang.org/genproto/googleapis/api/annotations"
httpbody "google.golang.org/genproto/googleapis/api/httpbody"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
emptypb "google.golang.org/protobuf/types/known/emptypb"
fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb"
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 Resource struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The name of the resource.
// Format: resources/{resource}, resource is the user defined if or uuid.
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
CreateTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"`
Filename string `protobuf:"bytes,4,opt,name=filename,proto3" json:"filename,omitempty"`
Content []byte `protobuf:"bytes,5,opt,name=content,proto3" json:"content,omitempty"`
ExternalLink string `protobuf:"bytes,6,opt,name=external_link,json=externalLink,proto3" json:"external_link,omitempty"`
Type string `protobuf:"bytes,7,opt,name=type,proto3" json:"type,omitempty"`
Size int64 `protobuf:"varint,8,opt,name=size,proto3" json:"size,omitempty"`
// The related memo. Refer to `Memo.name`.
Memo *string `protobuf:"bytes,9,opt,name=memo,proto3,oneof" json:"memo,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Resource) Reset() {
*x = Resource{}
mi := &file_api_v1_resource_service_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Resource) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Resource) ProtoMessage() {}
func (x *Resource) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_resource_service_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 Resource.ProtoReflect.Descriptor instead.
func (*Resource) Descriptor() ([]byte, []int) {
return file_api_v1_resource_service_proto_rawDescGZIP(), []int{0}
}
func (x *Resource) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *Resource) GetCreateTime() *timestamppb.Timestamp {
if x != nil {
return x.CreateTime
}
return nil
}
func (x *Resource) GetFilename() string {
if x != nil {
return x.Filename
}
return ""
}
func (x *Resource) GetContent() []byte {
if x != nil {
return x.Content
}
return nil
}
func (x *Resource) GetExternalLink() string {
if x != nil {
return x.ExternalLink
}
return ""
}
func (x *Resource) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *Resource) GetSize() int64 {
if x != nil {
return x.Size
}
return 0
}
func (x *Resource) GetMemo() string {
if x != nil && x.Memo != nil {
return *x.Memo
}
return ""
}
type CreateResourceRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Resource *Resource `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *CreateResourceRequest) Reset() {
*x = CreateResourceRequest{}
mi := &file_api_v1_resource_service_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CreateResourceRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateResourceRequest) ProtoMessage() {}
func (x *CreateResourceRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_resource_service_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 CreateResourceRequest.ProtoReflect.Descriptor instead.
func (*CreateResourceRequest) Descriptor() ([]byte, []int) {
return file_api_v1_resource_service_proto_rawDescGZIP(), []int{1}
}
func (x *CreateResourceRequest) GetResource() *Resource {
if x != nil {
return x.Resource
}
return nil
}
type ListResourcesRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ListResourcesRequest) Reset() {
*x = ListResourcesRequest{}
mi := &file_api_v1_resource_service_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListResourcesRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListResourcesRequest) ProtoMessage() {}
func (x *ListResourcesRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_resource_service_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 ListResourcesRequest.ProtoReflect.Descriptor instead.
func (*ListResourcesRequest) Descriptor() ([]byte, []int) {
return file_api_v1_resource_service_proto_rawDescGZIP(), []int{2}
}
type ListResourcesResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Resources []*Resource `protobuf:"bytes,1,rep,name=resources,proto3" json:"resources,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ListResourcesResponse) Reset() {
*x = ListResourcesResponse{}
mi := &file_api_v1_resource_service_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListResourcesResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListResourcesResponse) ProtoMessage() {}
func (x *ListResourcesResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_resource_service_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 ListResourcesResponse.ProtoReflect.Descriptor instead.
func (*ListResourcesResponse) Descriptor() ([]byte, []int) {
return file_api_v1_resource_service_proto_rawDescGZIP(), []int{3}
}
func (x *ListResourcesResponse) GetResources() []*Resource {
if x != nil {
return x.Resources
}
return nil
}
type GetResourceRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The name of the resource.
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetResourceRequest) Reset() {
*x = GetResourceRequest{}
mi := &file_api_v1_resource_service_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetResourceRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetResourceRequest) ProtoMessage() {}
func (x *GetResourceRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_resource_service_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 GetResourceRequest.ProtoReflect.Descriptor instead.
func (*GetResourceRequest) Descriptor() ([]byte, []int) {
return file_api_v1_resource_service_proto_rawDescGZIP(), []int{4}
}
func (x *GetResourceRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
type GetResourceBinaryRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The name of the resource.
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
// The filename of the resource. Mainly used for downloading.
Filename string `protobuf:"bytes,2,opt,name=filename,proto3" json:"filename,omitempty"`
// A flag indicating if the thumbnail version of the resource should be returned
Thumbnail bool `protobuf:"varint,3,opt,name=thumbnail,proto3" json:"thumbnail,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetResourceBinaryRequest) Reset() {
*x = GetResourceBinaryRequest{}
mi := &file_api_v1_resource_service_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetResourceBinaryRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetResourceBinaryRequest) ProtoMessage() {}
func (x *GetResourceBinaryRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_resource_service_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 GetResourceBinaryRequest.ProtoReflect.Descriptor instead.
func (*GetResourceBinaryRequest) Descriptor() ([]byte, []int) {
return file_api_v1_resource_service_proto_rawDescGZIP(), []int{5}
}
func (x *GetResourceBinaryRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *GetResourceBinaryRequest) GetFilename() string {
if x != nil {
return x.Filename
}
return ""
}
func (x *GetResourceBinaryRequest) GetThumbnail() bool {
if x != nil {
return x.Thumbnail
}
return false
}
type UpdateResourceRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Resource *Resource `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"`
UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *UpdateResourceRequest) Reset() {
*x = UpdateResourceRequest{}
mi := &file_api_v1_resource_service_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *UpdateResourceRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateResourceRequest) ProtoMessage() {}
func (x *UpdateResourceRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_resource_service_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 UpdateResourceRequest.ProtoReflect.Descriptor instead.
func (*UpdateResourceRequest) Descriptor() ([]byte, []int) {
return file_api_v1_resource_service_proto_rawDescGZIP(), []int{6}
}
func (x *UpdateResourceRequest) GetResource() *Resource {
if x != nil {
return x.Resource
}
return nil
}
func (x *UpdateResourceRequest) GetUpdateMask() *fieldmaskpb.FieldMask {
if x != nil {
return x.UpdateMask
}
return nil
}
type DeleteResourceRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The name of the resource.
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *DeleteResourceRequest) Reset() {
*x = DeleteResourceRequest{}
mi := &file_api_v1_resource_service_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *DeleteResourceRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DeleteResourceRequest) ProtoMessage() {}
func (x *DeleteResourceRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_resource_service_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 DeleteResourceRequest.ProtoReflect.Descriptor instead.
func (*DeleteResourceRequest) Descriptor() ([]byte, []int) {
return file_api_v1_resource_service_proto_rawDescGZIP(), []int{7}
}
func (x *DeleteResourceRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
var File_api_v1_resource_service_proto protoreflect.FileDescriptor
const file_api_v1_resource_service_proto_rawDesc = "" +
"\n" +
"\x1dapi/v1/resource_service.proto\x12\fmemos.api.v1\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/api/httpbody.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a google/protobuf/field_mask.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x98\x02\n" +
"\bResource\x12\x1a\n" +
"\x04name\x18\x01 \x01(\tB\x06\xe0A\x03\xe0A\bR\x04name\x12@\n" +
"\vcreate_time\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampB\x03\xe0A\x03R\n" +
"createTime\x12\x1a\n" +
"\bfilename\x18\x04 \x01(\tR\bfilename\x12\x1d\n" +
"\acontent\x18\x05 \x01(\fB\x03\xe0A\x04R\acontent\x12#\n" +
"\rexternal_link\x18\x06 \x01(\tR\fexternalLink\x12\x12\n" +
"\x04type\x18\a \x01(\tR\x04type\x12\x12\n" +
"\x04size\x18\b \x01(\x03R\x04size\x12\x17\n" +
"\x04memo\x18\t \x01(\tH\x00R\x04memo\x88\x01\x01B\a\n" +
"\x05_memoJ\x04\b\x02\x10\x03\"K\n" +
"\x15CreateResourceRequest\x122\n" +
"\bresource\x18\x01 \x01(\v2\x16.memos.api.v1.ResourceR\bresource\"\x16\n" +
"\x14ListResourcesRequest\"M\n" +
"\x15ListResourcesResponse\x124\n" +
"\tresources\x18\x01 \x03(\v2\x16.memos.api.v1.ResourceR\tresources\"(\n" +
"\x12GetResourceRequest\x12\x12\n" +
"\x04name\x18\x01 \x01(\tR\x04name\"h\n" +
"\x18GetResourceBinaryRequest\x12\x12\n" +
"\x04name\x18\x01 \x01(\tR\x04name\x12\x1a\n" +
"\bfilename\x18\x02 \x01(\tR\bfilename\x12\x1c\n" +
"\tthumbnail\x18\x03 \x01(\bR\tthumbnail\"\x88\x01\n" +
"\x15UpdateResourceRequest\x122\n" +
"\bresource\x18\x01 \x01(\v2\x16.memos.api.v1.ResourceR\bresource\x12;\n" +
"\vupdate_mask\x18\x02 \x01(\v2\x1a.google.protobuf.FieldMaskR\n" +
"updateMask\"+\n" +
"\x15DeleteResourceRequest\x12\x12\n" +
"\x04name\x18\x01 \x01(\tR\x04name2\x97\x06\n" +
"\x0fResourceService\x12r\n" +
"\x0eCreateResource\x12#.memos.api.v1.CreateResourceRequest\x1a\x16.memos.api.v1.Resource\"#\x82\xd3\xe4\x93\x02\x1d:\bresource\"\x11/api/v1/resources\x12s\n" +
"\rListResources\x12\".memos.api.v1.ListResourcesRequest\x1a#.memos.api.v1.ListResourcesResponse\"\x19\x82\xd3\xe4\x93\x02\x13\x12\x11/api/v1/resources\x12r\n" +
"\vGetResource\x12 .memos.api.v1.GetResourceRequest\x1a\x16.memos.api.v1.Resource\")\xdaA\x04name\x82\xd3\xe4\x93\x02\x1c\x12\x1a/api/v1/{name=resources/*}\x12\x8e\x01\n" +
"\x11GetResourceBinary\x12&.memos.api.v1.GetResourceBinaryRequest\x1a\x14.google.api.HttpBody\";\xdaA\rname,filename\x82\xd3\xe4\x93\x02%\x12#/file/{name=resources/*}/{filename}\x12\x9b\x01\n" +
"\x0eUpdateResource\x12#.memos.api.v1.UpdateResourceRequest\x1a\x16.memos.api.v1.Resource\"L\xdaA\x14resource,update_mask\x82\xd3\xe4\x93\x02/:\bresource2#/api/v1/{resource.name=resources/*}\x12x\n" +
"\x0eDeleteResource\x12#.memos.api.v1.DeleteResourceRequest\x1a\x16.google.protobuf.Empty\")\xdaA\x04name\x82\xd3\xe4\x93\x02\x1c*\x1a/api/v1/{name=resources/*}B\xac\x01\n" +
"\x10com.memos.api.v1B\x14ResourceServiceProtoP\x01Z0github.com/usememos/memos/proto/gen/api/v1;apiv1\xa2\x02\x03MAX\xaa\x02\fMemos.Api.V1\xca\x02\fMemos\\Api\\V1\xe2\x02\x18Memos\\Api\\V1\\GPBMetadata\xea\x02\x0eMemos::Api::V1b\x06proto3"
var (
file_api_v1_resource_service_proto_rawDescOnce sync.Once
file_api_v1_resource_service_proto_rawDescData []byte
)
func file_api_v1_resource_service_proto_rawDescGZIP() []byte {
file_api_v1_resource_service_proto_rawDescOnce.Do(func() {
file_api_v1_resource_service_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_api_v1_resource_service_proto_rawDesc), len(file_api_v1_resource_service_proto_rawDesc)))
})
return file_api_v1_resource_service_proto_rawDescData
}
var file_api_v1_resource_service_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
var file_api_v1_resource_service_proto_goTypes = []any{
(*Resource)(nil), // 0: memos.api.v1.Resource
(*CreateResourceRequest)(nil), // 1: memos.api.v1.CreateResourceRequest
(*ListResourcesRequest)(nil), // 2: memos.api.v1.ListResourcesRequest
(*ListResourcesResponse)(nil), // 3: memos.api.v1.ListResourcesResponse
(*GetResourceRequest)(nil), // 4: memos.api.v1.GetResourceRequest
(*GetResourceBinaryRequest)(nil), // 5: memos.api.v1.GetResourceBinaryRequest
(*UpdateResourceRequest)(nil), // 6: memos.api.v1.UpdateResourceRequest
(*DeleteResourceRequest)(nil), // 7: memos.api.v1.DeleteResourceRequest
(*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp
(*fieldmaskpb.FieldMask)(nil), // 9: google.protobuf.FieldMask
(*httpbody.HttpBody)(nil), // 10: google.api.HttpBody
(*emptypb.Empty)(nil), // 11: google.protobuf.Empty
}
var file_api_v1_resource_service_proto_depIdxs = []int32{
8, // 0: memos.api.v1.Resource.create_time:type_name -> google.protobuf.Timestamp
0, // 1: memos.api.v1.CreateResourceRequest.resource:type_name -> memos.api.v1.Resource
0, // 2: memos.api.v1.ListResourcesResponse.resources:type_name -> memos.api.v1.Resource
0, // 3: memos.api.v1.UpdateResourceRequest.resource:type_name -> memos.api.v1.Resource
9, // 4: memos.api.v1.UpdateResourceRequest.update_mask:type_name -> google.protobuf.FieldMask
1, // 5: memos.api.v1.ResourceService.CreateResource:input_type -> memos.api.v1.CreateResourceRequest
2, // 6: memos.api.v1.ResourceService.ListResources:input_type -> memos.api.v1.ListResourcesRequest
4, // 7: memos.api.v1.ResourceService.GetResource:input_type -> memos.api.v1.GetResourceRequest
5, // 8: memos.api.v1.ResourceService.GetResourceBinary:input_type -> memos.api.v1.GetResourceBinaryRequest
6, // 9: memos.api.v1.ResourceService.UpdateResource:input_type -> memos.api.v1.UpdateResourceRequest
7, // 10: memos.api.v1.ResourceService.DeleteResource:input_type -> memos.api.v1.DeleteResourceRequest
0, // 11: memos.api.v1.ResourceService.CreateResource:output_type -> memos.api.v1.Resource
3, // 12: memos.api.v1.ResourceService.ListResources:output_type -> memos.api.v1.ListResourcesResponse
0, // 13: memos.api.v1.ResourceService.GetResource:output_type -> memos.api.v1.Resource
10, // 14: memos.api.v1.ResourceService.GetResourceBinary:output_type -> google.api.HttpBody
0, // 15: memos.api.v1.ResourceService.UpdateResource:output_type -> memos.api.v1.Resource
11, // 16: memos.api.v1.ResourceService.DeleteResource:output_type -> google.protobuf.Empty
11, // [11:17] is the sub-list for method output_type
5, // [5:11] is the sub-list for method input_type
5, // [5:5] is the sub-list for extension type_name
5, // [5:5] is the sub-list for extension extendee
0, // [0:5] is the sub-list for field type_name
}
func init() { file_api_v1_resource_service_proto_init() }
func file_api_v1_resource_service_proto_init() {
if File_api_v1_resource_service_proto != nil {
return
}
file_api_v1_resource_service_proto_msgTypes[0].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_v1_resource_service_proto_rawDesc), len(file_api_v1_resource_service_proto_rawDesc)),
NumEnums: 0,
NumMessages: 8,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_api_v1_resource_service_proto_goTypes,
DependencyIndexes: file_api_v1_resource_service_proto_depIdxs,
MessageInfos: file_api_v1_resource_service_proto_msgTypes,
}.Build()
File_api_v1_resource_service_proto = out.File
file_api_v1_resource_service_proto_goTypes = nil
file_api_v1_resource_service_proto_depIdxs = nil
}

@ -1,587 +0,0 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: api/v1/resource_service.proto
/*
Package apiv1 is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package apiv1
import (
"context"
"errors"
"io"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
)
// Suppress "imported and not used" errors
var (
_ codes.Code
_ io.Reader
_ status.Status
_ = errors.New
_ = runtime.String
_ = utilities.NewDoubleArray
_ = metadata.Join
)
func request_ResourceService_CreateResource_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq CreateResourceRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq.Resource); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.CreateResource(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_ResourceService_CreateResource_0(ctx context.Context, marshaler runtime.Marshaler, server ResourceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq CreateResourceRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq.Resource); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.CreateResource(ctx, &protoReq)
return msg, metadata, err
}
func request_ResourceService_ListResources_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq ListResourcesRequest
metadata runtime.ServerMetadata
)
io.Copy(io.Discard, req.Body)
msg, err := client.ListResources(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_ResourceService_ListResources_0(ctx context.Context, marshaler runtime.Marshaler, server ResourceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq ListResourcesRequest
metadata runtime.ServerMetadata
)
msg, err := server.ListResources(ctx, &protoReq)
return msg, metadata, err
}
func request_ResourceService_GetResource_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq GetResourceRequest
metadata runtime.ServerMetadata
err error
)
io.Copy(io.Discard, req.Body)
val, ok := pathParams["name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
}
protoReq.Name, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
msg, err := client.GetResource(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_ResourceService_GetResource_0(ctx context.Context, marshaler runtime.Marshaler, server ResourceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq GetResourceRequest
metadata runtime.ServerMetadata
err error
)
val, ok := pathParams["name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
}
protoReq.Name, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
msg, err := server.GetResource(ctx, &protoReq)
return msg, metadata, err
}
var filter_ResourceService_GetResourceBinary_0 = &utilities.DoubleArray{Encoding: map[string]int{"name": 0, "filename": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}}
func request_ResourceService_GetResourceBinary_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq GetResourceBinaryRequest
metadata runtime.ServerMetadata
err error
)
io.Copy(io.Discard, req.Body)
val, ok := pathParams["name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
}
protoReq.Name, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
val, ok = pathParams["filename"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "filename")
}
protoReq.Filename, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "filename", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ResourceService_GetResourceBinary_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.GetResourceBinary(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_ResourceService_GetResourceBinary_0(ctx context.Context, marshaler runtime.Marshaler, server ResourceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq GetResourceBinaryRequest
metadata runtime.ServerMetadata
err error
)
val, ok := pathParams["name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
}
protoReq.Name, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
val, ok = pathParams["filename"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "filename")
}
protoReq.Filename, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "filename", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ResourceService_GetResourceBinary_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.GetResourceBinary(ctx, &protoReq)
return msg, metadata, err
}
var filter_ResourceService_UpdateResource_0 = &utilities.DoubleArray{Encoding: map[string]int{"resource": 0, "name": 1}, Base: []int{1, 2, 1, 0, 0}, Check: []int{0, 1, 2, 3, 2}}
func request_ResourceService_UpdateResource_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq UpdateResourceRequest
metadata runtime.ServerMetadata
err error
)
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Resource); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if protoReq.UpdateMask == nil || len(protoReq.UpdateMask.GetPaths()) == 0 {
if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), protoReq.Resource); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} else {
protoReq.UpdateMask = fieldMask
}
}
val, ok := pathParams["resource.name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "resource.name")
}
err = runtime.PopulateFieldFromPath(&protoReq, "resource.name", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "resource.name", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ResourceService_UpdateResource_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.UpdateResource(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_ResourceService_UpdateResource_0(ctx context.Context, marshaler runtime.Marshaler, server ResourceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq UpdateResourceRequest
metadata runtime.ServerMetadata
err error
)
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Resource); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if protoReq.UpdateMask == nil || len(protoReq.UpdateMask.GetPaths()) == 0 {
if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), protoReq.Resource); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} else {
protoReq.UpdateMask = fieldMask
}
}
val, ok := pathParams["resource.name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "resource.name")
}
err = runtime.PopulateFieldFromPath(&protoReq, "resource.name", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "resource.name", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ResourceService_UpdateResource_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.UpdateResource(ctx, &protoReq)
return msg, metadata, err
}
func request_ResourceService_DeleteResource_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq DeleteResourceRequest
metadata runtime.ServerMetadata
err error
)
io.Copy(io.Discard, req.Body)
val, ok := pathParams["name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
}
protoReq.Name, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
msg, err := client.DeleteResource(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_ResourceService_DeleteResource_0(ctx context.Context, marshaler runtime.Marshaler, server ResourceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq DeleteResourceRequest
metadata runtime.ServerMetadata
err error
)
val, ok := pathParams["name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
}
protoReq.Name, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
msg, err := server.DeleteResource(ctx, &protoReq)
return msg, metadata, err
}
// RegisterResourceServiceHandlerServer registers the http handlers for service ResourceService to "mux".
// UnaryRPC :call ResourceServiceServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterResourceServiceHandlerFromEndpoint instead.
// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call.
func RegisterResourceServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server ResourceServiceServer) error {
mux.Handle(http.MethodPost, pattern_ResourceService_CreateResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.ResourceService/CreateResource", runtime.WithHTTPPathPattern("/api/v1/resources"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_ResourceService_CreateResource_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ResourceService_CreateResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodGet, pattern_ResourceService_ListResources_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.ResourceService/ListResources", runtime.WithHTTPPathPattern("/api/v1/resources"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_ResourceService_ListResources_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ResourceService_ListResources_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodGet, pattern_ResourceService_GetResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.ResourceService/GetResource", runtime.WithHTTPPathPattern("/api/v1/{name=resources/*}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_ResourceService_GetResource_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ResourceService_GetResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodGet, pattern_ResourceService_GetResourceBinary_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.ResourceService/GetResourceBinary", runtime.WithHTTPPathPattern("/file/{name=resources/*}/{filename}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_ResourceService_GetResourceBinary_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ResourceService_GetResourceBinary_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPatch, pattern_ResourceService_UpdateResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.ResourceService/UpdateResource", runtime.WithHTTPPathPattern("/api/v1/{resource.name=resources/*}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_ResourceService_UpdateResource_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ResourceService_UpdateResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodDelete, pattern_ResourceService_DeleteResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.ResourceService/DeleteResource", runtime.WithHTTPPathPattern("/api/v1/{name=resources/*}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_ResourceService_DeleteResource_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ResourceService_DeleteResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterResourceServiceHandlerFromEndpoint is same as RegisterResourceServiceHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterResourceServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.NewClient(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterResourceServiceHandler(ctx, mux, conn)
}
// RegisterResourceServiceHandler registers the http handlers for service ResourceService to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterResourceServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterResourceServiceHandlerClient(ctx, mux, NewResourceServiceClient(conn))
}
// RegisterResourceServiceHandlerClient registers the http handlers for service ResourceService
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "ResourceServiceClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ResourceServiceClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "ResourceServiceClient" to call the correct interceptors. This client ignores the HTTP middlewares.
func RegisterResourceServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ResourceServiceClient) error {
mux.Handle(http.MethodPost, pattern_ResourceService_CreateResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.ResourceService/CreateResource", runtime.WithHTTPPathPattern("/api/v1/resources"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_ResourceService_CreateResource_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ResourceService_CreateResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodGet, pattern_ResourceService_ListResources_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.ResourceService/ListResources", runtime.WithHTTPPathPattern("/api/v1/resources"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_ResourceService_ListResources_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ResourceService_ListResources_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodGet, pattern_ResourceService_GetResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.ResourceService/GetResource", runtime.WithHTTPPathPattern("/api/v1/{name=resources/*}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_ResourceService_GetResource_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ResourceService_GetResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodGet, pattern_ResourceService_GetResourceBinary_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.ResourceService/GetResourceBinary", runtime.WithHTTPPathPattern("/file/{name=resources/*}/{filename}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_ResourceService_GetResourceBinary_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ResourceService_GetResourceBinary_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPatch, pattern_ResourceService_UpdateResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.ResourceService/UpdateResource", runtime.WithHTTPPathPattern("/api/v1/{resource.name=resources/*}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_ResourceService_UpdateResource_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ResourceService_UpdateResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodDelete, pattern_ResourceService_DeleteResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.ResourceService/DeleteResource", runtime.WithHTTPPathPattern("/api/v1/{name=resources/*}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_ResourceService_DeleteResource_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ResourceService_DeleteResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_ResourceService_CreateResource_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "resources"}, ""))
pattern_ResourceService_ListResources_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "resources"}, ""))
pattern_ResourceService_GetResource_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "resources", "name"}, ""))
pattern_ResourceService_GetResourceBinary_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 2, 5, 2, 1, 0, 4, 1, 5, 3}, []string{"file", "resources", "name", "filename"}, ""))
pattern_ResourceService_UpdateResource_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "resources", "resource.name"}, ""))
pattern_ResourceService_DeleteResource_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "resources", "name"}, ""))
)
var (
forward_ResourceService_CreateResource_0 = runtime.ForwardResponseMessage
forward_ResourceService_ListResources_0 = runtime.ForwardResponseMessage
forward_ResourceService_GetResource_0 = runtime.ForwardResponseMessage
forward_ResourceService_GetResourceBinary_0 = runtime.ForwardResponseMessage
forward_ResourceService_UpdateResource_0 = runtime.ForwardResponseMessage
forward_ResourceService_DeleteResource_0 = runtime.ForwardResponseMessage
)

@ -1,325 +0,0 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc (unknown)
// source: api/v1/resource_service.proto
package apiv1
import (
context "context"
httpbody "google.golang.org/genproto/googleapis/api/httpbody"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
emptypb "google.golang.org/protobuf/types/known/emptypb"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
ResourceService_CreateResource_FullMethodName = "/memos.api.v1.ResourceService/CreateResource"
ResourceService_ListResources_FullMethodName = "/memos.api.v1.ResourceService/ListResources"
ResourceService_GetResource_FullMethodName = "/memos.api.v1.ResourceService/GetResource"
ResourceService_GetResourceBinary_FullMethodName = "/memos.api.v1.ResourceService/GetResourceBinary"
ResourceService_UpdateResource_FullMethodName = "/memos.api.v1.ResourceService/UpdateResource"
ResourceService_DeleteResource_FullMethodName = "/memos.api.v1.ResourceService/DeleteResource"
)
// ResourceServiceClient is the client API for ResourceService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type ResourceServiceClient interface {
// CreateResource creates a new resource.
CreateResource(ctx context.Context, in *CreateResourceRequest, opts ...grpc.CallOption) (*Resource, error)
// ListResources lists all resources.
ListResources(ctx context.Context, in *ListResourcesRequest, opts ...grpc.CallOption) (*ListResourcesResponse, error)
// GetResource returns a resource by name.
GetResource(ctx context.Context, in *GetResourceRequest, opts ...grpc.CallOption) (*Resource, error)
// GetResourceBinary returns a resource binary by name.
GetResourceBinary(ctx context.Context, in *GetResourceBinaryRequest, opts ...grpc.CallOption) (*httpbody.HttpBody, error)
// UpdateResource updates a resource.
UpdateResource(ctx context.Context, in *UpdateResourceRequest, opts ...grpc.CallOption) (*Resource, error)
// DeleteResource deletes a resource by name.
DeleteResource(ctx context.Context, in *DeleteResourceRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
}
type resourceServiceClient struct {
cc grpc.ClientConnInterface
}
func NewResourceServiceClient(cc grpc.ClientConnInterface) ResourceServiceClient {
return &resourceServiceClient{cc}
}
func (c *resourceServiceClient) CreateResource(ctx context.Context, in *CreateResourceRequest, opts ...grpc.CallOption) (*Resource, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(Resource)
err := c.cc.Invoke(ctx, ResourceService_CreateResource_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *resourceServiceClient) ListResources(ctx context.Context, in *ListResourcesRequest, opts ...grpc.CallOption) (*ListResourcesResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ListResourcesResponse)
err := c.cc.Invoke(ctx, ResourceService_ListResources_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *resourceServiceClient) GetResource(ctx context.Context, in *GetResourceRequest, opts ...grpc.CallOption) (*Resource, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(Resource)
err := c.cc.Invoke(ctx, ResourceService_GetResource_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *resourceServiceClient) GetResourceBinary(ctx context.Context, in *GetResourceBinaryRequest, opts ...grpc.CallOption) (*httpbody.HttpBody, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(httpbody.HttpBody)
err := c.cc.Invoke(ctx, ResourceService_GetResourceBinary_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *resourceServiceClient) UpdateResource(ctx context.Context, in *UpdateResourceRequest, opts ...grpc.CallOption) (*Resource, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(Resource)
err := c.cc.Invoke(ctx, ResourceService_UpdateResource_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *resourceServiceClient) DeleteResource(ctx context.Context, in *DeleteResourceRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, ResourceService_DeleteResource_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// ResourceServiceServer is the server API for ResourceService service.
// All implementations must embed UnimplementedResourceServiceServer
// for forward compatibility.
type ResourceServiceServer interface {
// CreateResource creates a new resource.
CreateResource(context.Context, *CreateResourceRequest) (*Resource, error)
// ListResources lists all resources.
ListResources(context.Context, *ListResourcesRequest) (*ListResourcesResponse, error)
// GetResource returns a resource by name.
GetResource(context.Context, *GetResourceRequest) (*Resource, error)
// GetResourceBinary returns a resource binary by name.
GetResourceBinary(context.Context, *GetResourceBinaryRequest) (*httpbody.HttpBody, error)
// UpdateResource updates a resource.
UpdateResource(context.Context, *UpdateResourceRequest) (*Resource, error)
// DeleteResource deletes a resource by name.
DeleteResource(context.Context, *DeleteResourceRequest) (*emptypb.Empty, error)
mustEmbedUnimplementedResourceServiceServer()
}
// UnimplementedResourceServiceServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedResourceServiceServer struct{}
func (UnimplementedResourceServiceServer) CreateResource(context.Context, *CreateResourceRequest) (*Resource, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateResource not implemented")
}
func (UnimplementedResourceServiceServer) ListResources(context.Context, *ListResourcesRequest) (*ListResourcesResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListResources not implemented")
}
func (UnimplementedResourceServiceServer) GetResource(context.Context, *GetResourceRequest) (*Resource, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetResource not implemented")
}
func (UnimplementedResourceServiceServer) GetResourceBinary(context.Context, *GetResourceBinaryRequest) (*httpbody.HttpBody, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetResourceBinary not implemented")
}
func (UnimplementedResourceServiceServer) UpdateResource(context.Context, *UpdateResourceRequest) (*Resource, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateResource not implemented")
}
func (UnimplementedResourceServiceServer) DeleteResource(context.Context, *DeleteResourceRequest) (*emptypb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteResource not implemented")
}
func (UnimplementedResourceServiceServer) mustEmbedUnimplementedResourceServiceServer() {}
func (UnimplementedResourceServiceServer) testEmbeddedByValue() {}
// UnsafeResourceServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to ResourceServiceServer will
// result in compilation errors.
type UnsafeResourceServiceServer interface {
mustEmbedUnimplementedResourceServiceServer()
}
func RegisterResourceServiceServer(s grpc.ServiceRegistrar, srv ResourceServiceServer) {
// If the following call pancis, it indicates UnimplementedResourceServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&ResourceService_ServiceDesc, srv)
}
func _ResourceService_CreateResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateResourceRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ResourceServiceServer).CreateResource(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ResourceService_CreateResource_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ResourceServiceServer).CreateResource(ctx, req.(*CreateResourceRequest))
}
return interceptor(ctx, in, info, handler)
}
func _ResourceService_ListResources_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListResourcesRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ResourceServiceServer).ListResources(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ResourceService_ListResources_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ResourceServiceServer).ListResources(ctx, req.(*ListResourcesRequest))
}
return interceptor(ctx, in, info, handler)
}
func _ResourceService_GetResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetResourceRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ResourceServiceServer).GetResource(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ResourceService_GetResource_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ResourceServiceServer).GetResource(ctx, req.(*GetResourceRequest))
}
return interceptor(ctx, in, info, handler)
}
func _ResourceService_GetResourceBinary_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetResourceBinaryRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ResourceServiceServer).GetResourceBinary(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ResourceService_GetResourceBinary_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ResourceServiceServer).GetResourceBinary(ctx, req.(*GetResourceBinaryRequest))
}
return interceptor(ctx, in, info, handler)
}
func _ResourceService_UpdateResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdateResourceRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ResourceServiceServer).UpdateResource(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ResourceService_UpdateResource_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ResourceServiceServer).UpdateResource(ctx, req.(*UpdateResourceRequest))
}
return interceptor(ctx, in, info, handler)
}
func _ResourceService_DeleteResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteResourceRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ResourceServiceServer).DeleteResource(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ResourceService_DeleteResource_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ResourceServiceServer).DeleteResource(ctx, req.(*DeleteResourceRequest))
}
return interceptor(ctx, in, info, handler)
}
// ResourceService_ServiceDesc is the grpc.ServiceDesc for ResourceService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var ResourceService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "memos.api.v1.ResourceService",
HandlerType: (*ResourceServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "CreateResource",
Handler: _ResourceService_CreateResource_Handler,
},
{
MethodName: "ListResources",
Handler: _ResourceService_ListResources_Handler,
},
{
MethodName: "GetResource",
Handler: _ResourceService_GetResource_Handler,
},
{
MethodName: "GetResourceBinary",
Handler: _ResourceService_GetResourceBinary_Handler,
},
{
MethodName: "UpdateResource",
Handler: _ResourceService_UpdateResource_Handler,
},
{
MethodName: "DeleteResource",
Handler: _ResourceService_DeleteResource_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "api/v1/resource_service.proto",
}

@ -4,12 +4,12 @@ info:
version: version not set
tags:
- name: ActivityService
- name: AttachmentService
- name: UserService
- name: AuthService
- name: IdentityProviderService
- name: InboxService
- name: MarkdownService
- name: ResourceService
- name: MemoService
- name: ShortcutService
- name: WebhookService
@ -52,6 +52,85 @@ paths:
type: string
tags:
- ActivityService
/api/v1/attachments:
get:
summary: ListAttachments lists all attachments.
operationId: AttachmentService_ListAttachments
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/v1ListAttachmentsResponse'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: pageSize
description: |-
Optional. The maximum number of attachments to return.
The service may return fewer than this value.
If unspecified, at most 50 attachments will be returned.
The maximum value is 1000; values above 1000 will be coerced to 1000.
in: query
required: false
type: integer
format: int32
- name: pageToken
description: |-
Optional. A page token, received from a previous `ListAttachments` call.
Provide this to retrieve the subsequent page.
in: query
required: false
type: string
- name: filter
description: |-
Optional. Filter to apply to the list results.
Example: "type=image/png" or "filename:*.jpg"
Supported operators: =, !=, <, <=, >, >=, :
Supported fields: filename, type, size, create_time, memo
in: query
required: false
type: string
- name: orderBy
description: |-
Optional. The order to sort results by.
Example: "create_time desc" or "filename asc"
in: query
required: false
type: string
tags:
- AttachmentService
post:
summary: CreateAttachment creates a new attachment.
operationId: AttachmentService_CreateAttachment
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/v1Attachment'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: attachment
description: Required. The attachment to create.
in: body
required: true
schema:
$ref: '#/definitions/v1Attachment'
required:
- attachment
- name: attachmentId
description: |-
Optional. The attachment ID to use for this attachment.
If empty, a unique ID will be generated.
in: query
required: false
type: string
tags:
- AttachmentService
/api/v1/auth/signin:
post:
summary: SignIn signs in the user.
@ -457,41 +536,6 @@ paths:
format: int32
tags:
- MemoService
/api/v1/resources:
get:
summary: ListResources lists all resources.
operationId: ResourceService_ListResources
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/v1ListResourcesResponse'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
tags:
- ResourceService
post:
summary: CreateResource creates a new resource.
operationId: ResourceService_CreateResource
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/v1Resource'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: resource
in: body
required: true
schema:
$ref: '#/definitions/v1Resource'
tags:
- ResourceService
/api/v1/users:
get:
summary: ListUsers returns a list of users.
@ -760,6 +804,70 @@ paths:
$ref: '#/definitions/googlerpcStatus'
tags:
- WorkspaceService
/api/v1/{attachment.name}:
patch:
summary: UpdateAttachment updates a attachment.
operationId: AttachmentService_UpdateAttachment
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/v1Attachment'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: attachment.name
description: |-
The name of the attachment.
Format: attachments/{attachment}
in: path
required: true
type: string
pattern: attachments/[^/]+
- name: attachment
description: Required. The attachment which replaces the attachment on the server.
in: body
required: true
schema:
type: object
properties:
createTime:
type: string
format: date-time
description: Output only. The creation timestamp.
readOnly: true
filename:
type: string
description: The filename of the attachment.
content:
type: string
format: byte
description: Input only. The content of the attachment.
externalLink:
type: string
description: Optional. The external link of the attachment.
type:
type: string
description: The MIME type of the attachment.
size:
type: string
format: int64
description: Output only. The size of the attachment in bytes.
readOnly: true
memo:
type: string
title: |-
Optional. The related memo. Refer to `Memo.name`.
Format: memos/{memo}
title: Required. The attachment which replaces the attachment on the server.
required:
- filename
- type
- attachment
tags:
- AttachmentService
/api/v1/{identityProvider.name}:
patch:
summary: UpdateIdentityProvider updates an identity provider.
@ -923,11 +1031,11 @@ paths:
readOnly: true
pinned:
type: boolean
resources:
attachments:
type: array
items:
type: object
$ref: '#/definitions/v1Resource'
$ref: '#/definitions/v1Attachment'
relations:
type: array
items:
@ -964,13 +1072,13 @@ paths:
- MemoService
/api/v1/{name_1}:
get:
summary: GetUser gets a user by name.
operationId: UserService_GetUser
summary: GetAttachment returns a attachment by name.
operationId: AttachmentService_GetAttachment
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/v1User'
$ref: '#/definitions/v1Attachment'
default:
description: An unexpected error response.
schema:
@ -978,24 +1086,17 @@ paths:
parameters:
- name: name_1
description: |-
Required. The resource name of the user.
Format: users/{user}
Required. The attachment name of the attachment to retrieve.
Format: attachments/{attachment}
in: path
required: true
type: string
pattern: users/[^/]+
- name: readMask
description: |-
Optional. The fields to return in the response.
If not specified, all fields are returned.
in: query
required: false
type: string
pattern: attachments/[^/]+
tags:
- UserService
- AttachmentService
delete:
summary: DeleteUserAccessToken deletes an access token.
operationId: UserService_DeleteUserAccessToken
summary: DeleteUser deletes a user.
operationId: UserService_DeleteUser
responses:
"200":
description: A successful response.
@ -1009,23 +1110,28 @@ paths:
parameters:
- name: name_1
description: |-
Required. The resource name of the access token to delete.
Format: users/{user}/accessTokens/{access_token}
Required. The resource name of the user to delete.
Format: users/{user}
in: path
required: true
type: string
pattern: users/[^/]+/accessTokens/[^/]+
pattern: users/[^/]+
- name: force
description: Optional. If set to true, the user will be deleted even if they have associated data.
in: query
required: false
type: boolean
tags:
- UserService
/api/v1/{name_2}:
get:
summary: GetIdentityProvider gets an identity provider.
operationId: IdentityProviderService_GetIdentityProvider
summary: GetUser gets a user by name.
operationId: UserService_GetUser
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/apiv1IdentityProvider'
$ref: '#/definitions/v1User'
default:
description: An unexpected error response.
schema:
@ -1033,17 +1139,24 @@ paths:
parameters:
- name: name_2
description: |-
Required. The resource name of the identity provider to get.
Format: identityProviders/{idp}
Required. The resource name of the user.
Format: users/{user}
in: path
required: true
type: string
pattern: identityProviders/[^/]+
pattern: users/[^/]+
- name: readMask
description: |-
Optional. The fields to return in the response.
If not specified, all fields are returned.
in: query
required: false
type: string
tags:
- IdentityProviderService
- UserService
delete:
summary: DeleteIdentityProvider deletes an identity provider.
operationId: IdentityProviderService_DeleteIdentityProvider
summary: DeleteUserAccessToken deletes an access token.
operationId: UserService_DeleteUserAccessToken
responses:
"200":
description: A successful response.
@ -1057,39 +1170,41 @@ paths:
parameters:
- name: name_2
description: |-
Required. The resource name of the identity provider to delete.
Format: identityProviders/{idp}
Required. The resource name of the access token to delete.
Format: users/{user}/accessTokens/{access_token}
in: path
required: true
type: string
pattern: identityProviders/[^/]+
pattern: users/[^/]+/accessTokens/[^/]+
tags:
- IdentityProviderService
- UserService
/api/v1/{name_3}:
get:
summary: GetResource returns a resource by name.
operationId: ResourceService_GetResource
summary: GetIdentityProvider gets an identity provider.
operationId: IdentityProviderService_GetIdentityProvider
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/v1Resource'
$ref: '#/definitions/apiv1IdentityProvider'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name_3
description: The name of the resource.
description: |-
Required. The resource name of the identity provider to get.
Format: identityProviders/{idp}
in: path
required: true
type: string
pattern: resources/[^/]+
pattern: identityProviders/[^/]+
tags:
- ResourceService
- IdentityProviderService
delete:
summary: DeleteInbox deletes an inbox.
operationId: InboxService_DeleteInbox
summary: DeleteIdentityProvider deletes an identity provider.
operationId: IdentityProviderService_DeleteIdentityProvider
responses:
"200":
description: A successful response.
@ -1102,13 +1217,15 @@ paths:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name_3
description: The name of the inbox to delete.
description: |-
Required. The resource name of the identity provider to delete.
Format: identityProviders/{idp}
in: path
required: true
type: string
pattern: inboxes/[^/]+
pattern: identityProviders/[^/]+
tags:
- InboxService
- IdentityProviderService
/api/v1/{name_4}:
get:
summary: GetMemo gets a memo.
@ -1132,8 +1249,8 @@ paths:
tags:
- MemoService
delete:
summary: DeleteResource deletes a resource by name.
operationId: ResourceService_DeleteResource
summary: DeleteInbox deletes an inbox.
operationId: InboxService_DeleteInbox
responses:
"200":
description: A successful response.
@ -1146,13 +1263,13 @@ paths:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name_4
description: The name of the resource.
description: The name of the inbox to delete.
in: path
required: true
type: string
pattern: resources/[^/]+
pattern: inboxes/[^/]+
tags:
- ResourceService
- InboxService
/api/v1/{name_5}:
get:
summary: GetShortcut gets a shortcut by name.
@ -1332,8 +1449,8 @@ paths:
tags:
- ActivityService
delete:
summary: DeleteUser deletes a user.
operationId: UserService_DeleteUser
summary: DeleteAttachment deletes a attachment by name.
operationId: AttachmentService_DeleteAttachment
responses:
"200":
description: A successful response.
@ -1347,19 +1464,63 @@ paths:
parameters:
- name: name
description: |-
Required. The resource name of the user to delete.
Format: users/{user}
Required. The attachment name of the attachment to delete.
Format: attachments/{attachment}
in: path
required: true
type: string
pattern: users/[^/]+
- name: force
description: Optional. If set to true, the user will be deleted even if they have associated data.
in: query
required: false
type: boolean
pattern: attachments/[^/]+
tags:
- UserService
- AttachmentService
/api/v1/{name}/attachments:
get:
summary: ListMemoAttachments lists attachments for a memo.
operationId: MemoService_ListMemoAttachments
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/v1ListMemoAttachmentsResponse'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name
description: The name of the memo.
in: path
required: true
type: string
pattern: memos/[^/]+
tags:
- MemoService
patch:
summary: SetMemoAttachments sets attachments for a memo.
operationId: MemoService_SetMemoAttachments
responses:
"200":
description: A successful response.
schema:
type: object
properties: {}
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name
description: The name of the memo.
in: path
required: true
type: string
pattern: memos/[^/]+
- name: body
in: body
required: true
schema:
$ref: '#/definitions/MemoServiceSetMemoAttachmentsBody'
tags:
- MemoService
/api/v1/{name}/avatar:
get:
summary: GetUserAvatar gets the avatar of a user.
@ -1530,55 +1691,6 @@ paths:
$ref: '#/definitions/MemoServiceSetMemoRelationsBody'
tags:
- MemoService
/api/v1/{name}/resources:
get:
summary: ListMemoResources lists resources for a memo.
operationId: MemoService_ListMemoResources
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/v1ListMemoResourcesResponse'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name
description: The name of the memo.
in: path
required: true
type: string
pattern: memos/[^/]+
tags:
- MemoService
patch:
summary: SetMemoResources sets resources for a memo.
operationId: MemoService_SetMemoResources
responses:
"200":
description: A successful response.
schema:
type: object
properties: {}
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name
description: The name of the memo.
in: path
required: true
type: string
pattern: memos/[^/]+
- name: body
in: body
required: true
schema:
$ref: '#/definitions/MemoServiceSetMemoResourcesBody'
tags:
- MemoService
/api/v1/{name}:getSetting:
get:
summary: GetUserSetting returns the user setting.
@ -1914,55 +2026,6 @@ paths:
$ref: '#/definitions/MemoServiceRenameMemoTagBody'
tags:
- MemoService
/api/v1/{resource.name}:
patch:
summary: UpdateResource updates a resource.
operationId: ResourceService_UpdateResource
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/v1Resource'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: resource.name
description: |-
The name of the resource.
Format: resources/{resource}, resource is the user defined if or uuid.
in: path
required: true
type: string
pattern: resources/[^/]+
- name: resource
in: body
required: true
schema:
type: object
properties:
createTime:
type: string
format: date-time
readOnly: true
filename:
type: string
content:
type: string
format: byte
externalLink:
type: string
type:
type: string
size:
type: string
format: int64
memo:
type: string
description: The related memo. Refer to `Memo.name`.
tags:
- ResourceService
/api/v1/{setting.name}:
patch:
summary: Updates a workspace setting.
@ -2248,8 +2311,8 @@ paths:
- WebhookService
/file/{name}/{filename}:
get:
summary: GetResourceBinary returns a resource binary by name.
operationId: ResourceService_GetResourceBinary
summary: GetAttachmentBinary returns a attachment binary by name.
operationId: AttachmentService_GetAttachmentBinary
responses:
"200":
description: A successful response.
@ -2261,23 +2324,25 @@ paths:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name
description: The name of the resource.
description: |-
Required. The attachment name of the attachment.
Format: attachments/{attachment}
in: path
required: true
type: string
pattern: resources/[^/]+
pattern: attachments/[^/]+
- name: filename
description: The filename of the resource. Mainly used for downloading.
description: The filename of the attachment. Mainly used for downloading.
in: path
required: true
type: string
- name: thumbnail
description: A flag indicating if the thumbnail version of the resource should be returned
description: Optional. A flag indicating if the thumbnail version of the attachment should be returned.
in: query
required: false
type: boolean
tags:
- ResourceService
- AttachmentService
definitions:
ActivityLevel:
type: string
@ -2309,22 +2374,22 @@ definitions:
type: string
newTag:
type: string
MemoServiceSetMemoRelationsBody:
MemoServiceSetMemoAttachmentsBody:
type: object
properties:
relations:
attachments:
type: array
items:
type: object
$ref: '#/definitions/v1MemoRelation'
MemoServiceSetMemoResourcesBody:
$ref: '#/definitions/v1Attachment'
MemoServiceSetMemoRelationsBody:
type: object
properties:
resources:
relations:
type: array
items:
type: object
$ref: '#/definitions/v1Resource'
$ref: '#/definitions/v1MemoRelation'
MemoServiceUpsertMemoReactionBody:
type: object
properties:
@ -2570,11 +2635,11 @@ definitions:
readOnly: true
pinned:
type: boolean
resources:
attachments:
type: array
items:
type: object
$ref: '#/definitions/v1Resource'
$ref: '#/definitions/v1Attachment'
relations:
type: array
items:
@ -2961,6 +3026,45 @@ definitions:
- TYPE_UNSPECIFIED: Unspecified type.
- TYPE_MEMO_COMMENT: Memo comment activity.
- TYPE_VERSION_UPDATE: Version update activity.
v1Attachment:
type: object
properties:
name:
type: string
title: |-
The name of the attachment.
Format: attachments/{attachment}
createTime:
type: string
format: date-time
description: Output only. The creation timestamp.
readOnly: true
filename:
type: string
description: The filename of the attachment.
content:
type: string
format: byte
description: Input only. The content of the attachment.
externalLink:
type: string
description: Optional. The external link of the attachment.
type:
type: string
description: The MIME type of the attachment.
size:
type: string
format: int64
description: Output only. The size of the attachment in bytes.
readOnly: true
memo:
type: string
title: |-
Optional. The related memo. Refer to `Memo.name`.
Format: memos/{memo}
required:
- filename
- type
v1AutoLinkNode:
type: object
properties:
@ -3161,6 +3265,24 @@ definitions:
type: integer
format: int32
description: The total count of user statistics.
v1ListAttachmentsResponse:
type: object
properties:
attachments:
type: array
items:
type: object
$ref: '#/definitions/v1Attachment'
description: The list of attachments.
nextPageToken:
type: string
description: |-
A token that can be sent as `page_token` to retrieve the next page.
If this field is omitted, there are no subsequent pages.
totalSize:
type: integer
format: int32
description: The total count of attachments (may be approximate).
v1ListIdentityProvidersResponse:
type: object
properties:
@ -3186,6 +3308,14 @@ definitions:
description: |-
A token, which can be sent as `page_token` to retrieve the next page.
If this field is omitted, there are no subsequent pages.
v1ListMemoAttachmentsResponse:
type: object
properties:
attachments:
type: array
items:
type: object
$ref: '#/definitions/v1Attachment'
v1ListMemoCommentsResponse:
type: object
properties:
@ -3210,14 +3340,6 @@ definitions:
items:
type: object
$ref: '#/definitions/v1MemoRelation'
v1ListMemoResourcesResponse:
type: object
properties:
resources:
type: array
items:
type: object
$ref: '#/definitions/v1Resource'
v1ListMemosResponse:
type: object
properties:
@ -3244,14 +3366,6 @@ definitions:
items:
type: object
$ref: '#/definitions/v1Node'
v1ListResourcesResponse:
type: object
properties:
resources:
type: array
items:
type: object
$ref: '#/definitions/v1Resource'
v1ListShortcutsResponse:
type: object
properties:
@ -3547,34 +3661,6 @@ definitions:
type: string
params:
type: string
v1Resource:
type: object
properties:
name:
type: string
description: |-
The name of the resource.
Format: resources/{resource}, resource is the user defined if or uuid.
readOnly: true
createTime:
type: string
format: date-time
readOnly: true
filename:
type: string
content:
type: string
format: byte
externalLink:
type: string
type:
type: string
size:
type: string
format: int64
memo:
type: string
description: The related memo. Refer to `Memo.name`.
v1RestoreMarkdownNodesRequest:
type: object
properties:

@ -45,24 +45,41 @@ var SupportedThumbnailMimeTypes = []string{
"image/jpeg",
}
func (s *APIV1Service) CreateResource(ctx context.Context, request *v1pb.CreateResourceRequest) (*v1pb.Resource, error) {
func (s *APIV1Service) CreateAttachment(ctx context.Context, request *v1pb.CreateAttachmentRequest) (*v1pb.Attachment, error) {
user, err := s.GetCurrentUser(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err)
}
// Validate required fields
if request.Attachment == nil {
return nil, status.Errorf(codes.InvalidArgument, "attachment is required")
}
if request.Attachment.Filename == "" {
return nil, status.Errorf(codes.InvalidArgument, "filename is required")
}
if request.Attachment.Type == "" {
return nil, status.Errorf(codes.InvalidArgument, "type is required")
}
// Use provided attachment_id or generate a new one
attachmentUID := request.AttachmentId
if attachmentUID == "" {
attachmentUID = shortuuid.New()
}
create := &store.Resource{
UID: shortuuid.New(),
UID: attachmentUID,
CreatorID: user.ID,
Filename: request.Resource.Filename,
Type: request.Resource.Type,
Filename: request.Attachment.Filename,
Type: request.Attachment.Type,
}
workspaceStorageSetting, err := s.Store.GetWorkspaceStorageSetting(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get workspace storage setting: %v", err)
}
size := binary.Size(request.Resource.Content)
size := binary.Size(request.Attachment.Content)
uploadSizeLimit := int(workspaceStorageSetting.UploadSizeLimitMb) * MebiByte
if uploadSizeLimit == 0 {
uploadSizeLimit = MaxUploadBufferSizeBytes
@ -71,13 +88,14 @@ func (s *APIV1Service) CreateResource(ctx context.Context, request *v1pb.CreateR
return nil, status.Errorf(codes.InvalidArgument, "file size exceeds the limit")
}
create.Size = int64(size)
create.Blob = request.Resource.Content
create.Blob = request.Attachment.Content
if err := SaveResourceBlob(ctx, s.Profile, s.Store, create); err != nil {
return nil, status.Errorf(codes.Internal, "failed to save resource blob: %v", err)
}
if request.Resource.Memo != nil {
memoUID, err := ExtractMemoUIDFromName(*request.Resource.Memo)
if request.Attachment.Memo != nil {
memoUID, err := ExtractMemoUIDFromName(*request.Attachment.Memo)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid memo name: %v", err)
}
@ -85,6 +103,9 @@ func (s *APIV1Service) CreateResource(ctx context.Context, request *v1pb.CreateR
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to find memo: %v", err)
}
if memo == nil {
return nil, status.Errorf(codes.NotFound, "memo not found: %s", *request.Attachment.Memo)
}
create.MemoID = &memo.ID
}
resource, err := s.Store.CreateResource(ctx, create)
@ -92,57 +113,116 @@ func (s *APIV1Service) CreateResource(ctx context.Context, request *v1pb.CreateR
return nil, status.Errorf(codes.Internal, "failed to create resource: %v", err)
}
return s.convertResourceFromStore(ctx, resource), nil
return s.convertAttachmentFromStore(ctx, resource), nil
}
func (s *APIV1Service) ListResources(ctx context.Context, _ *v1pb.ListResourcesRequest) (*v1pb.ListResourcesResponse, error) {
func (s *APIV1Service) ListAttachments(ctx context.Context, request *v1pb.ListAttachmentsRequest) (*v1pb.ListAttachmentsResponse, error) {
user, err := s.GetCurrentUser(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err)
}
resources, err := s.Store.ListResources(ctx, &store.FindResource{
// Set default page size
pageSize := int(request.PageSize)
if pageSize <= 0 {
pageSize = 50
}
if pageSize > 1000 {
pageSize = 1000
}
// Parse page token for offset
offset := 0
if request.PageToken != "" {
// Simple implementation: page token is the offset as string
// In production, you might want to use encrypted tokens
if parsed, err := fmt.Sscanf(request.PageToken, "%d", &offset); err != nil || parsed != 1 {
return nil, status.Errorf(codes.InvalidArgument, "invalid page token")
}
}
findResource := &store.FindResource{
CreatorID: &user.ID,
})
Limit: &pageSize,
Offset: &offset,
}
// Basic filter support for common cases
if request.Filter != "" {
// Simple filter parsing - can be enhanced later
// For now, support basic type filtering: "type=image/png"
if strings.HasPrefix(request.Filter, "type=") {
filterType := strings.TrimPrefix(request.Filter, "type=")
// Create a temporary struct to hold type filter
// Since FindResource doesn't have Type field, we'll apply this post-query
_ = filterType // We'll filter after getting results
}
}
resources, err := s.Store.ListResources(ctx, findResource)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to list resources: %v", err)
}
response := &v1pb.ListResourcesResponse{}
// Apply type filter if specified
if request.Filter != "" && strings.HasPrefix(request.Filter, "type=") {
filterType := strings.TrimPrefix(request.Filter, "type=")
filteredResources := make([]*store.Resource, 0)
for _, resource := range resources {
response.Resources = append(response.Resources, s.convertResourceFromStore(ctx, resource))
if resource.Type == filterType {
filteredResources = append(filteredResources, resource)
}
}
resources = filteredResources
}
response := &v1pb.ListAttachmentsResponse{}
for _, resource := range resources {
response.Attachments = append(response.Attachments, s.convertAttachmentFromStore(ctx, resource))
}
// For simplicity, set total size to the number of returned resources
// In a full implementation, you'd want a separate count query
response.TotalSize = int32(len(response.Attachments))
// Set next page token if we got the full page size (indicating there might be more)
if len(resources) == pageSize {
response.NextPageToken = fmt.Sprintf("%d", offset+pageSize)
}
return response, nil
}
func (s *APIV1Service) GetResource(ctx context.Context, request *v1pb.GetResourceRequest) (*v1pb.Resource, error) {
resourceUID, err := ExtractResourceUIDFromName(request.Name)
func (s *APIV1Service) GetAttachment(ctx context.Context, request *v1pb.GetAttachmentRequest) (*v1pb.Attachment, error) {
attachmentUID, err := ExtractAttachmentUIDFromName(request.Name)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid resource id: %v", err)
return nil, status.Errorf(codes.InvalidArgument, "invalid attachment id: %v", err)
}
resource, err := s.Store.GetResource(ctx, &store.FindResource{UID: &resourceUID})
resource, err := s.Store.GetResource(ctx, &store.FindResource{UID: &attachmentUID})
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get resource: %v", err)
}
if resource == nil {
return nil, status.Errorf(codes.NotFound, "resource not found")
return nil, status.Errorf(codes.NotFound, "attachment not found")
}
return s.convertResourceFromStore(ctx, resource), nil
return s.convertAttachmentFromStore(ctx, resource), nil
}
func (s *APIV1Service) GetResourceBinary(ctx context.Context, request *v1pb.GetResourceBinaryRequest) (*httpbody.HttpBody, error) {
resourceUID, err := ExtractResourceUIDFromName(request.Name)
func (s *APIV1Service) GetAttachmentBinary(ctx context.Context, request *v1pb.GetAttachmentBinaryRequest) (*httpbody.HttpBody, error) {
attachmentUID, err := ExtractAttachmentUIDFromName(request.Name)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid resource id: %v", err)
return nil, status.Errorf(codes.InvalidArgument, "invalid attachment id: %v", err)
}
resource, err := s.Store.GetResource(ctx, &store.FindResource{
GetBlob: true,
UID: &resourceUID,
UID: &attachmentUID,
})
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get resource: %v", err)
}
if resource == nil {
return nil, status.Errorf(codes.NotFound, "resource not found")
return nil, status.Errorf(codes.NotFound, "attachment not found")
}
// Check the related memo visibility.
if resource.MemoID != nil {
@ -202,15 +282,15 @@ func (s *APIV1Service) GetResourceBinary(ctx context.Context, request *v1pb.GetR
}, nil
}
func (s *APIV1Service) UpdateResource(ctx context.Context, request *v1pb.UpdateResourceRequest) (*v1pb.Resource, error) {
resourceUID, err := ExtractResourceUIDFromName(request.Resource.Name)
func (s *APIV1Service) UpdateAttachment(ctx context.Context, request *v1pb.UpdateAttachmentRequest) (*v1pb.Attachment, error) {
attachmentUID, err := ExtractAttachmentUIDFromName(request.Attachment.Name)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid resource id: %v", err)
return nil, status.Errorf(codes.InvalidArgument, "invalid attachment id: %v", err)
}
if request.UpdateMask == nil || len(request.UpdateMask.Paths) == 0 {
return nil, status.Errorf(codes.InvalidArgument, "update mask is required")
}
resource, err := s.Store.GetResource(ctx, &store.FindResource{UID: &resourceUID})
resource, err := s.Store.GetResource(ctx, &store.FindResource{UID: &attachmentUID})
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get resource: %v", err)
}
@ -222,36 +302,36 @@ func (s *APIV1Service) UpdateResource(ctx context.Context, request *v1pb.UpdateR
}
for _, field := range request.UpdateMask.Paths {
if field == "filename" {
update.Filename = &request.Resource.Filename
update.Filename = &request.Attachment.Filename
}
}
if err := s.Store.UpdateResource(ctx, update); err != nil {
return nil, status.Errorf(codes.Internal, "failed to update resource: %v", err)
}
return s.GetResource(ctx, &v1pb.GetResourceRequest{
Name: request.Resource.Name,
return s.GetAttachment(ctx, &v1pb.GetAttachmentRequest{
Name: request.Attachment.Name,
})
}
func (s *APIV1Service) DeleteResource(ctx context.Context, request *v1pb.DeleteResourceRequest) (*emptypb.Empty, error) {
resourceUID, err := ExtractResourceUIDFromName(request.Name)
func (s *APIV1Service) DeleteAttachment(ctx context.Context, request *v1pb.DeleteAttachmentRequest) (*emptypb.Empty, error) {
attachmentUID, err := ExtractAttachmentUIDFromName(request.Name)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid resource id: %v", err)
return nil, status.Errorf(codes.InvalidArgument, "invalid attachment id: %v", err)
}
user, err := s.GetCurrentUser(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err)
}
resource, err := s.Store.GetResource(ctx, &store.FindResource{
UID: &resourceUID,
UID: &attachmentUID,
CreatorID: &user.ID,
})
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to find resource: %v", err)
}
if resource == nil {
return nil, status.Errorf(codes.NotFound, "resource not found")
return nil, status.Errorf(codes.NotFound, "attachment not found")
}
// Delete the resource from the database.
if err := s.Store.DeleteResource(ctx, &store.DeleteResource{
@ -262,16 +342,16 @@ func (s *APIV1Service) DeleteResource(ctx context.Context, request *v1pb.DeleteR
return &emptypb.Empty{}, nil
}
func (s *APIV1Service) convertResourceFromStore(ctx context.Context, resource *store.Resource) *v1pb.Resource {
resourceMessage := &v1pb.Resource{
Name: fmt.Sprintf("%s%s", ResourceNamePrefix, resource.UID),
func (s *APIV1Service) convertAttachmentFromStore(ctx context.Context, resource *store.Resource) *v1pb.Attachment {
attachmentMessage := &v1pb.Attachment{
Name: fmt.Sprintf("%s%s", AttachmentNamePrefix, resource.UID),
CreateTime: timestamppb.New(time.Unix(resource.CreatedTs, 0)),
Filename: resource.Filename,
Type: resource.Type,
Size: resource.Size,
}
if resource.StorageType == storepb.ResourceStorageType_EXTERNAL || resource.StorageType == storepb.ResourceStorageType_S3 {
resourceMessage.ExternalLink = resource.Reference
attachmentMessage.ExternalLink = resource.Reference
}
if resource.MemoID != nil {
memo, _ := s.Store.GetMemo(ctx, &store.FindMemo{
@ -279,11 +359,11 @@ func (s *APIV1Service) convertResourceFromStore(ctx context.Context, resource *s
})
if memo != nil {
memoName := fmt.Sprintf("%s%s", MemoNamePrefix, memo.UID)
resourceMessage.Memo = &memoName
attachmentMessage.Memo = &memoName
}
}
return resourceMessage
return attachmentMessage
}
// SaveResourceBlob save the blob of resource based on the storage config.

@ -13,7 +13,7 @@ import (
"github.com/usememos/memos/store"
)
func (s *APIV1Service) SetMemoResources(ctx context.Context, request *v1pb.SetMemoResourcesRequest) (*emptypb.Empty, error) {
func (s *APIV1Service) SetMemoAttachments(ctx context.Context, request *v1pb.SetMemoAttachmentsRequest) (*emptypb.Empty, error) {
memoUID, err := ExtractMemoUIDFromName(request.Name)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid memo name: %v", err)
@ -32,10 +32,10 @@ func (s *APIV1Service) SetMemoResources(ctx context.Context, request *v1pb.SetMe
// Delete resources that are not in the request.
for _, resource := range resources {
found := false
for _, requestResource := range request.Resources {
requestResourceUID, err := ExtractResourceUIDFromName(requestResource.Name)
for _, requestResource := range request.Attachments {
requestResourceUID, err := ExtractAttachmentUIDFromName(requestResource.Name)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid resource name: %v", err)
return nil, status.Errorf(codes.InvalidArgument, "invalid attachment name: %v", err)
}
if resource.UID == requestResourceUID {
found = true
@ -52,12 +52,12 @@ func (s *APIV1Service) SetMemoResources(ctx context.Context, request *v1pb.SetMe
}
}
slices.Reverse(request.Resources)
slices.Reverse(request.Attachments)
// Update resources' memo_id in the request.
for index, resource := range request.Resources {
resourceUID, err := ExtractResourceUIDFromName(resource.Name)
for index, resource := range request.Attachments {
resourceUID, err := ExtractAttachmentUIDFromName(resource.Name)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid resource name: %v", err)
return nil, status.Errorf(codes.InvalidArgument, "invalid attachment name: %v", err)
}
tempResource, err := s.Store.GetResource(ctx, &store.FindResource{UID: &resourceUID})
if err != nil {
@ -76,7 +76,7 @@ func (s *APIV1Service) SetMemoResources(ctx context.Context, request *v1pb.SetMe
return &emptypb.Empty{}, nil
}
func (s *APIV1Service) ListMemoResources(ctx context.Context, request *v1pb.ListMemoResourcesRequest) (*v1pb.ListMemoResourcesResponse, error) {
func (s *APIV1Service) ListMemoAttachments(ctx context.Context, request *v1pb.ListMemoAttachmentsRequest) (*v1pb.ListMemoAttachmentsResponse, error) {
memoUID, err := ExtractMemoUIDFromName(request.Name)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid memo name: %v", err)
@ -92,11 +92,11 @@ func (s *APIV1Service) ListMemoResources(ctx context.Context, request *v1pb.List
return nil, status.Errorf(codes.Internal, "failed to list resources: %v", err)
}
response := &v1pb.ListMemoResourcesResponse{
Resources: []*v1pb.Resource{},
response := &v1pb.ListMemoAttachmentsResponse{
Attachments: []*v1pb.Attachment{},
}
for _, resource := range resources {
response.Resources = append(response.Resources, s.convertResourceFromStore(ctx, resource))
response.Attachments = append(response.Attachments, s.convertAttachmentFromStore(ctx, resource))
}
return response, nil
}

@ -63,13 +63,13 @@ func (s *APIV1Service) CreateMemo(ctx context.Context, request *v1pb.CreateMemoR
if err != nil {
return nil, err
}
if len(request.Memo.Resources) > 0 {
_, err := s.SetMemoResources(ctx, &v1pb.SetMemoResourcesRequest{
if len(request.Memo.Attachments) > 0 {
_, err := s.SetMemoAttachments(ctx, &v1pb.SetMemoAttachmentsRequest{
Name: fmt.Sprintf("%s%s", MemoNamePrefix, memo.UID),
Resources: request.Memo.Resources,
Attachments: request.Memo.Attachments,
})
if err != nil {
return nil, errors.Wrap(err, "failed to set memo resources")
return nil, errors.Wrap(err, "failed to set memo attachments")
}
}
if len(request.Memo.Relations) > 0 {
@ -318,13 +318,13 @@ func (s *APIV1Service) UpdateMemo(ctx context.Context, request *v1pb.UpdateMemoR
payload := memo.Payload
payload.Location = convertLocationToStore(request.Memo.Location)
update.Payload = payload
} else if path == "resources" {
_, err := s.SetMemoResources(ctx, &v1pb.SetMemoResourcesRequest{
} else if path == "attachments" {
_, err := s.SetMemoAttachments(ctx, &v1pb.SetMemoAttachmentsRequest{
Name: request.Memo.Name,
Resources: request.Memo.Resources,
Attachments: request.Memo.Attachments,
})
if err != nil {
return nil, errors.Wrap(err, "failed to set memo resources")
return nil, errors.Wrap(err, "failed to set memo attachments")
}
} else if path == "relations" {
_, err := s.SetMemoRelations(ctx, &v1pb.SetMemoRelationsRequest{

@ -61,11 +61,11 @@ func (s *APIV1Service) convertMemoFromStore(ctx context.Context, memo *store.Mem
}
memoMessage.Relations = listMemoRelationsResponse.Relations
listMemoResourcesResponse, err := s.ListMemoResources(ctx, &v1pb.ListMemoResourcesRequest{Name: name})
listMemoAttachmentsResponse, err := s.ListMemoAttachments(ctx, &v1pb.ListMemoAttachmentsRequest{Name: name})
if err != nil {
return nil, errors.Wrap(err, "failed to list memo resources")
return nil, errors.Wrap(err, "failed to list memo attachments")
}
memoMessage.Resources = listMemoResourcesResponse.Resources
memoMessage.Attachments = listMemoAttachmentsResponse.Attachments
listMemoReactionsResponse, err := s.ListMemoReactions(ctx, &v1pb.ListMemoReactionsRequest{Name: name})
if err != nil {

@ -13,7 +13,7 @@ const (
WorkspaceSettingNamePrefix = "workspace/settings/"
UserNamePrefix = "users/"
MemoNamePrefix = "memos/"
ResourceNamePrefix = "resources/"
AttachmentNamePrefix = "attachments/"
InboxNamePrefix = "inboxes/"
IdentityProviderNamePrefix = "identityProviders/"
ActivityNamePrefix = "activities/"
@ -83,9 +83,9 @@ func ExtractMemoUIDFromName(name string) (string, error) {
return id, nil
}
// ExtractResourceUIDFromName returns the resource UID from a resource name.
func ExtractResourceUIDFromName(name string) (string, error) {
tokens, err := GetNameParentTokens(name, ResourceNamePrefix)
// ExtractAttachmentUIDFromName returns the attachment UID from a resource name.
func ExtractAttachmentUIDFromName(name string) (string, error) {
tokens, err := GetNameParentTokens(name, AttachmentNamePrefix)
if err != nil {
return "", err
}

@ -26,7 +26,7 @@ type APIV1Service struct {
v1pb.UnimplementedAuthServiceServer
v1pb.UnimplementedUserServiceServer
v1pb.UnimplementedMemoServiceServer
v1pb.UnimplementedResourceServiceServer
v1pb.UnimplementedAttachmentServiceServer
v1pb.UnimplementedShortcutServiceServer
v1pb.UnimplementedInboxServiceServer
v1pb.UnimplementedActivityServiceServer
@ -54,7 +54,7 @@ func NewAPIV1Service(secret string, profile *profile.Profile, store *store.Store
v1pb.RegisterAuthServiceServer(grpcServer, apiv1Service)
v1pb.RegisterUserServiceServer(grpcServer, apiv1Service)
v1pb.RegisterMemoServiceServer(grpcServer, apiv1Service)
v1pb.RegisterResourceServiceServer(grpcServer, apiv1Service)
v1pb.RegisterAttachmentServiceServer(grpcServer, apiv1Service)
v1pb.RegisterShortcutServiceServer(grpcServer, apiv1Service)
v1pb.RegisterInboxServiceServer(grpcServer, apiv1Service)
v1pb.RegisterActivityServiceServer(grpcServer, apiv1Service)
@ -95,7 +95,7 @@ func (s *APIV1Service) RegisterGateway(ctx context.Context, echoServer *echo.Ech
if err := v1pb.RegisterMemoServiceHandler(ctx, gwMux, conn); err != nil {
return err
}
if err := v1pb.RegisterResourceServiceHandler(ctx, gwMux, conn); err != nil {
if err := v1pb.RegisterAttachmentServiceHandler(ctx, gwMux, conn); err != nil {
return err
}
if err := v1pb.RegisterShortcutServiceHandler(ctx, gwMux, conn); err != nil {

@ -136,7 +136,7 @@ func (s *RSSService) generateRSSFromMemoList(ctx context.Context, memoList []*st
if resource.StorageType == storepb.ResourceStorageType_EXTERNAL || resource.StorageType == storepb.ResourceStorageType_S3 {
enclosure.Url = resource.Reference
} else {
enclosure.Url = fmt.Sprintf("%s/file/resources/%s/%s", baseURL, resource.UID, resource.Filename)
enclosure.Url = fmt.Sprintf("%s/file/attachments/%s/%s", baseURL, resource.UID, resource.Filename)
}
enclosure.Length = strconv.Itoa(int(resource.Size))
enclosure.Type = resource.Type

@ -73,7 +73,7 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
return c.String(http.StatusOK, "Service ready.")
})
// Serve frontend resources.
// Serve frontend static files.
frontend.NewFrontendService(profile, store).Serve(ctx, echoServer)
rootGroup := echoServer.Group("")
@ -82,7 +82,7 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
rss.NewRSSService(s.Profile, s.Store).RegisterRoutes(rootGroup)
grpcServer := grpc.NewServer(
// Override the maximum receiving message size to math.MaxInt32 for uploading large resources.
// Override the maximum receiving message size to math.MaxInt32 for uploading large attachments.
grpc.MaxRecvMsgSize(math.MaxInt32),
grpc.ChainUnaryInterceptor(
apiv1.NewLoggerInterceptor().LoggerInterceptor,

@ -0,0 +1,95 @@
import { memo } from "react";
import { Attachment } from "@/types/proto/api/v1/attachment_service";
import { cn } from "@/utils";
import { getAttachmentType, getAttachmentUrl } from "@/utils/attachment";
import MemoResource from "./MemoResource";
import showPreviewImageDialog from "./PreviewImageDialog";
const MemoAttachmentListView = ({ attachments = [] }: { attachments: Attachment[] }) => {
const mediaAttachments: Attachment[] = [];
const otherAttachments: Attachment[] = [];
attachments.forEach((attachment) => {
const type = getAttachmentType(attachment);
if (type === "image/*" || type === "video/*") {
mediaAttachments.push(attachment);
return;
}
otherAttachments.push(attachment);
});
const handleImageClick = (imgUrl: string) => {
const imgUrls = mediaAttachments
.filter((attachment) => getAttachmentType(attachment) === "image/*")
.map((attachment) => getAttachmentUrl(attachment));
const index = imgUrls.findIndex((url) => url === imgUrl);
showPreviewImageDialog(imgUrls, index);
};
const MediaCard = ({ attachment, className }: { attachment: Attachment; className?: string }) => {
const type = getAttachmentType(attachment);
const attachmentUrl = getAttachmentUrl(attachment);
if (type === "image/*") {
return (
<img
className={cn(
"cursor-pointer h-full w-auto rounded-lg border border-zinc-200 dark:border-zinc-800 object-contain hover:opacity-80",
className,
)}
src={attachment.externalLink ? attachmentUrl : attachmentUrl + "?thumbnail=true"}
onClick={() => handleImageClick(attachmentUrl)}
decoding="async"
loading="lazy"
/>
);
} else if (type === "video/*") {
return (
<video
className={cn(
"cursor-pointer h-full w-auto rounded-lg border border-zinc-200 dark:border-zinc-800 object-contain bg-zinc-100 dark:bg-zinc-800",
className,
)}
preload="metadata"
crossOrigin="anonymous"
src={attachmentUrl}
controls
/>
);
} else {
return <></>;
}
};
const MediaList = ({ attachments = [] }: { attachments: Attachment[] }) => {
const cards = attachments.map((attachment) => (
<div key={attachment.name} className="max-w-[70%] grow flex flex-col justify-start items-start shrink-0">
<MediaCard className="max-h-64 grow" attachment={attachment} />
</div>
));
return <div className="w-full flex flex-row justify-start overflow-auto gap-2">{cards}</div>;
};
const OtherList = ({ attachments = [] }: { attachments: Attachment[] }) => {
if (attachments.length === 0) return <></>;
return (
<div className="w-full flex flex-row justify-start overflow-auto gap-2">
{otherAttachments.map((attachment) => (
<MemoResource key={attachment.name} resource={attachment} />
))}
</div>
);
};
return (
<>
{mediaAttachments.length > 0 && <MediaList attachments={mediaAttachments} />}
<OtherList attachments={otherAttachments} />
</>
);
};
export default memo(MemoAttachmentListView);

@ -4,7 +4,7 @@ import { observer } from "mobx-react-lite";
import { useContext, useEffect } from "react";
import toast from "react-hot-toast";
import { Link } from "react-router-dom";
import MemoResourceListView from "@/components/MemoResourceListView";
import MemoAttachmentListView from "@/components/MemoAttachmentListView";
import useLoading from "@/hooks/useLoading";
import { extractMemoIdFromName } from "@/store/common";
import { memoStore } from "@/store/v2";
@ -54,7 +54,7 @@ const EmbeddedMemo = observer(({ resourceId: uid, params: paramsStr }: Props) =>
nodes={memo.nodes}
embeddedMemos={context.embeddedMemos}
/>
<MemoResourceListView resources={memo.resources} />
<MemoAttachmentListView attachments={memo.attachments} />
</>
);
if (inlineMode) {

@ -1,8 +1,8 @@
import { observer } from "mobx-react-lite";
import { useEffect } from "react";
import MemoResourceListView from "@/components/MemoResourceListView";
import MemoAttachmentListView from "@/components/MemoAttachmentListView";
import useLoading from "@/hooks/useLoading";
import { resourceStore } from "@/store/v2";
import { attachmentStore } from "@/store/v2";
import { cn } from "@/utils";
import Error from "./Error";
@ -38,23 +38,23 @@ const getAdditionalClassNameWithParams = (params: URLSearchParams) => {
const EmbeddedResource = observer(({ resourceId: uid, params: paramsStr }: Props) => {
const loadingState = useLoading();
const resource = resourceStore.getResourceByName(uid);
const attachment = attachmentStore.getAttachmentByName(uid);
const params = new URLSearchParams(paramsStr);
useEffect(() => {
resourceStore.fetchResourceByName(`resources/${uid}`).finally(() => loadingState.setFinish());
attachmentStore.fetchAttachmentByName(`attachments/${uid}`).finally(() => loadingState.setFinish());
}, [uid]);
if (loadingState.isLoading) {
return null;
}
if (!resource) {
return <Error message={`Resource not found: ${uid}`} />;
if (!attachment) {
return <Error message={`Attachment not found: ${uid}`} />;
}
return (
<div className={cn("max-w-full", getAdditionalClassNameWithParams(params))}>
<MemoResourceListView resources={[resource]} />
<MemoAttachmentListView attachments={[attachment]} />
</div>
);
});

@ -16,7 +16,7 @@ const EmbeddedContent = ({ resourceName, params }: Props) => {
const { resourceType, resourceId } = extractResourceTypeAndId(resourceName);
if (resourceType === "memos") {
return <EmbeddedMemo resourceId={resourceId} params={params} />;
} else if (resourceType === "resources") {
} else if (resourceType === "attachments") {
return <EmbeddedResource resourceId={resourceId} params={params} />;
}
return <Error message={`Unknown resource: ${resourceName}`} />;

@ -3,8 +3,8 @@ import { LoaderIcon, PaperclipIcon } from "lucide-react";
import { observer } from "mobx-react-lite";
import { useContext, useRef, useState } from "react";
import toast from "react-hot-toast";
import { resourceStore } from "@/store/v2";
import { Resource } from "@/types/proto/api/v1/resource_service";
import { attachmentStore } from "@/store/v2";
import { Attachment } from "@/types/proto/api/v1/attachment_service";
import { MemoEditorContext } from "../types";
interface Props {
@ -37,7 +37,7 @@ const UploadResourceButton = observer((props: Props) => {
};
});
const createdResourceList: Resource[] = [];
const createdAttachmentList: Attachment[] = [];
try {
if (!fileInputRef.current || !fileInputRef.current.files) {
return;
@ -45,22 +45,23 @@ const UploadResourceButton = observer((props: Props) => {
for (const file of fileInputRef.current.files) {
const { name: filename, size, type } = file;
const buffer = new Uint8Array(await file.arrayBuffer());
const resource = await resourceStore.createResource({
resource: Resource.fromPartial({
const attachment = await attachmentStore.createAttachment({
attachment: Attachment.fromPartial({
filename,
size,
type,
content: buffer,
}),
attachmentId: "",
});
createdResourceList.push(resource);
createdAttachmentList.push(attachment);
}
} catch (error: any) {
console.error(error);
toast.error(error.details);
}
context.setResourceList([...context.resourceList, ...createdResourceList]);
context.setAttachmentList([...context.attachmentList, ...createdAttachmentList]);
setState((state) => {
return {
...state,

@ -1,50 +1,50 @@
import { DndContext, closestCenter, MouseSensor, TouchSensor, useSensor, useSensors, DragEndEvent } from "@dnd-kit/core";
import { arrayMove, SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
import { XIcon } from "lucide-react";
import { Resource } from "@/types/proto/api/v1/resource_service";
import { Attachment } from "@/types/proto/api/v1/attachment_service";
import ResourceIcon from "../ResourceIcon";
import SortableItem from "./SortableItem";
interface Props {
resourceList: Resource[];
setResourceList: (resourceList: Resource[]) => void;
attachmentList: Attachment[];
setAttachmentList: (attachmentList: Attachment[]) => void;
}
const ResourceListView = (props: Props) => {
const { resourceList, setResourceList } = props;
const AttachmentListView = (props: Props) => {
const { attachmentList, setAttachmentList } = props;
const sensors = useSensors(useSensor(MouseSensor), useSensor(TouchSensor));
const handleDeleteResource = async (name: string) => {
setResourceList(resourceList.filter((resource) => resource.name !== name));
const handleDeleteAttachment = async (name: string) => {
setAttachmentList(attachmentList.filter((attachment) => attachment.name !== name));
};
const handleDragEnd = (event: DragEndEvent) => {
const { active, over } = event;
if (over && active.id !== over.id) {
const oldIndex = resourceList.findIndex((resource) => resource.name === active.id);
const newIndex = resourceList.findIndex((resource) => resource.name === over.id);
const oldIndex = attachmentList.findIndex((attachment) => attachment.name === active.id);
const newIndex = attachmentList.findIndex((attachment) => attachment.name === over.id);
setResourceList(arrayMove(resourceList, oldIndex, newIndex));
setAttachmentList(arrayMove(attachmentList, oldIndex, newIndex));
}
};
return (
<DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
<SortableContext items={resourceList.map((resource) => resource.name)} strategy={verticalListSortingStrategy}>
{resourceList.length > 0 && (
<SortableContext items={attachmentList.map((attachment) => attachment.name)} strategy={verticalListSortingStrategy}>
{attachmentList.length > 0 && (
<div className="w-full flex flex-row justify-start flex-wrap gap-2 mt-2 max-h-[50vh] overflow-y-auto">
{resourceList.map((resource) => {
{attachmentList.map((attachment) => {
return (
<div
key={resource.name}
key={attachment.name}
className="max-w-full w-auto flex flex-row justify-start items-center flex-nowrap gap-x-1 bg-zinc-100 dark:bg-zinc-900 px-2 py-1 rounded hover:shadow-sm text-gray-500 dark:text-gray-400"
>
<SortableItem id={resource.name} className="flex flex-row justify-start items-center gap-x-1">
<ResourceIcon resource={resource} className="w-4! h-4! opacity-100!" />
<span className="text-sm max-w-32 truncate">{resource.filename}</span>
<SortableItem id={attachment.name} className="flex flex-row justify-start items-center gap-x-1">
<ResourceIcon resource={attachment} className="w-4! h-4! opacity-100!" />
<span className="text-sm max-w-32 truncate">{attachment.filename}</span>
</SortableItem>
<button className="shrink-0" onClick={() => handleDeleteResource(resource.name)}>
<button className="shrink-0" onClick={() => handleDeleteAttachment(attachment.name)}>
<XIcon className="w-4 h-auto cursor-pointer opacity-60 hover:opacity-100" />
</button>
</div>
@ -57,4 +57,4 @@ const ResourceListView = (props: Props) => {
);
};
export default ResourceListView;
export default AttachmentListView;

@ -13,9 +13,9 @@ import { isValidUrl } from "@/helpers/utils";
import useAsyncEffect from "@/hooks/useAsyncEffect";
import useCurrentUser from "@/hooks/useCurrentUser";
import { extractMemoIdFromName } from "@/store/common";
import { memoStore, resourceStore, userStore, workspaceStore } from "@/store/v2";
import { memoStore, attachmentStore, userStore, workspaceStore } from "@/store/v2";
import { Attachment } from "@/types/proto/api/v1/attachment_service";
import { Location, Memo, MemoRelation, MemoRelation_Type, Visibility } from "@/types/proto/api/v1/memo_service";
import { Resource } from "@/types/proto/api/v1/resource_service";
import { UserSetting } from "@/types/proto/api/v1/user_service";
import { cn } from "@/utils";
import { useTranslate } from "@/utils/i18n";
@ -27,9 +27,9 @@ import MarkdownMenu from "./ActionButton/MarkdownMenu";
import TagSelector from "./ActionButton/TagSelector";
import UploadResourceButton from "./ActionButton/UploadResourceButton";
import VisibilitySelector from "./ActionButton/VisibilitySelector";
import AttachmentListView from "./AttachmentListView";
import Editor, { EditorRefActions } from "./Editor";
import RelationListView from "./RelationListView";
import ResourceListView from "./ResourceListView";
import { handleEditorKeydownWithMarkdownShortcuts, hyperlinkHighlightedText } from "./handlers";
import { MemoEditorContext } from "./types";
@ -48,7 +48,7 @@ export interface Props {
interface State {
memoVisibility: Visibility;
resourceList: Resource[];
attachmentList: Attachment[];
relationList: MemoRelation[];
location: Location | undefined;
isUploadingResource: boolean;
@ -64,7 +64,7 @@ const MemoEditor = observer((props: Props) => {
const currentUser = useCurrentUser();
const [state, setState] = useState<State>({
memoVisibility: Visibility.PRIVATE,
resourceList: [],
attachmentList: [],
relationList: [],
location: undefined,
isUploadingResource: false,
@ -126,7 +126,7 @@ const MemoEditor = observer((props: Props) => {
setState((prevState) => ({
...prevState,
memoVisibility: memo.visibility,
resourceList: memo.resources,
attachmentList: memo.attachments,
relationList: memo.relations,
location: memo.location,
}));
@ -185,10 +185,10 @@ const MemoEditor = observer((props: Props) => {
}));
};
const handleSetResourceList = (resourceList: Resource[]) => {
const handleSetAttachmentList = (attachmentList: Attachment[]) => {
setState((prevState) => ({
...prevState,
resourceList,
attachmentList,
}));
};
@ -211,13 +211,14 @@ const MemoEditor = observer((props: Props) => {
const buffer = new Uint8Array(await file.arrayBuffer());
try {
const resource = await resourceStore.createResource({
resource: Resource.fromPartial({
const attachment = await attachmentStore.createAttachment({
attachment: Attachment.fromPartial({
filename,
size,
type,
content: buffer,
}),
attachmentId: "",
});
setState((state) => {
return {
@ -225,7 +226,7 @@ const MemoEditor = observer((props: Props) => {
isUploadingResource: false,
};
});
return resource;
return attachment;
} catch (error: any) {
console.error(error);
toast.error(error.details);
@ -239,15 +240,15 @@ const MemoEditor = observer((props: Props) => {
};
const uploadMultiFiles = async (files: FileList) => {
const uploadedResourceList: Resource[] = [];
const uploadedAttachmentList: Attachment[] = [];
for (const file of files) {
const resource = await handleUploadResource(file);
if (resource) {
uploadedResourceList.push(resource);
const attachment = await handleUploadResource(file);
if (attachment) {
uploadedAttachmentList.push(attachment);
if (memoName) {
await resourceStore.updateResource({
resource: Resource.fromPartial({
name: resource.name,
await attachmentStore.updateAttachment({
attachment: Attachment.fromPartial({
name: attachment.name,
memo: memoName,
}),
updateMask: ["memo"],
@ -255,10 +256,10 @@ const MemoEditor = observer((props: Props) => {
}
}
}
if (uploadedResourceList.length > 0) {
if (uploadedAttachmentList.length > 0) {
setState((prevState) => ({
...prevState,
resourceList: [...prevState.resourceList, ...uploadedResourceList],
attachmentList: [...prevState.attachmentList, ...uploadedAttachmentList],
}));
}
};
@ -349,9 +350,9 @@ const MemoEditor = observer((props: Props) => {
updateMask.add("visibility");
memoPatch.visibility = state.memoVisibility;
}
if (!isEqual(state.resourceList, prevMemo.resources)) {
updateMask.add("resources");
memoPatch.resources = state.resourceList;
if (!isEqual(state.attachmentList, prevMemo.attachments)) {
updateMask.add("attachments");
memoPatch.attachments = state.attachmentList;
}
if (!isEqual(state.relationList, prevMemo.relations)) {
updateMask.add("relations");
@ -361,7 +362,7 @@ const MemoEditor = observer((props: Props) => {
updateMask.add("location");
memoPatch.location = state.location;
}
if (["content", "resources", "relations", "location"].some((key) => updateMask.has(key))) {
if (["content", "attachments", "relations", "location"].some((key) => updateMask.has(key))) {
updateMask.add("update_time");
}
if (createTime && !isEqual(createTime, prevMemo.createTime)) {
@ -391,7 +392,7 @@ const MemoEditor = observer((props: Props) => {
memo: Memo.fromPartial({
content,
visibility: state.memoVisibility,
resources: state.resourceList,
attachments: state.attachmentList,
relations: state.relationList,
location: state.location,
}),
@ -402,7 +403,7 @@ const MemoEditor = observer((props: Props) => {
comment: {
content,
visibility: state.memoVisibility,
resources: state.resourceList,
attachments: state.attachmentList,
relations: state.relationList,
location: state.location,
},
@ -424,7 +425,7 @@ const MemoEditor = observer((props: Props) => {
return {
...state,
isRequesting: false,
resourceList: [],
attachmentList: [],
relationList: [],
location: undefined,
isDraggingFile: false,
@ -455,17 +456,17 @@ const MemoEditor = observer((props: Props) => {
[i18n.language],
);
const allowSave = (hasContent || state.resourceList.length > 0) && !state.isUploadingResource && !state.isRequesting;
const allowSave = (hasContent || state.attachmentList.length > 0) && !state.isUploadingResource && !state.isRequesting;
return (
<MemoEditorContext.Provider
value={{
resourceList: state.resourceList,
attachmentList: state.attachmentList,
relationList: state.relationList,
setResourceList: (resourceList: Resource[]) => {
setAttachmentList: (attachmentList: Attachment[]) => {
setState((prevState) => ({
...prevState,
resourceList,
attachmentList,
}));
},
setRelationList: (relationList: MemoRelation[]) => {
@ -495,7 +496,7 @@ const MemoEditor = observer((props: Props) => {
onCompositionEnd={handleCompositionEnd}
>
<Editor ref={editorRef} {...editorConfig} />
<ResourceListView resourceList={state.resourceList} setResourceList={handleSetResourceList} />
<AttachmentListView attachmentList={state.attachmentList} setAttachmentList={handleSetAttachmentList} />
<RelationListView relationList={referenceRelations} setRelationList={handleSetRelationList} />
<div className="relative w-full flex flex-row justify-between items-center py-1" onFocus={(e) => e.stopPropagation()}>
<div className="flex flex-row justify-start items-center opacity-80 dark:opacity-60 space-x-2">

@ -1,18 +1,18 @@
import { createContext } from "react";
import { Attachment } from "@/types/proto/api/v1/attachment_service";
import { MemoRelation } from "@/types/proto/api/v1/memo_service";
import { Resource } from "@/types/proto/api/v1/resource_service";
interface Context {
resourceList: Resource[];
attachmentList: Attachment[];
relationList: MemoRelation[];
setResourceList: (resourceList: Resource[]) => void;
setAttachmentList: (attachmentList: Attachment[]) => void;
setRelationList: (relationList: MemoRelation[]) => void;
memoName?: string;
}
export const MemoEditorContext = createContext<Context>({
resourceList: [],
attachmentList: [],
relationList: [],
setResourceList: () => {},
setAttachmentList: () => {},
setRelationList: () => {},
});

@ -1,15 +1,15 @@
import { Resource } from "@/types/proto/api/v1/resource_service";
import { getResourceUrl } from "@/utils/resource";
import { Attachment } from "@/types/proto/api/v1/attachment_service";
import { getAttachmentUrl } from "@/utils/attachment";
import ResourceIcon from "./ResourceIcon";
interface Props {
resource: Resource;
resource: Attachment;
className?: string;
}
const MemoResource: React.FC<Props> = (props: Props) => {
const { className, resource } = props;
const resourceUrl = getResourceUrl(resource);
const resourceUrl = getAttachmentUrl(resource);
const handlePreviewBtnClick = () => {
window.open(resourceUrl);

@ -1,95 +0,0 @@
import { memo } from "react";
import { Resource } from "@/types/proto/api/v1/resource_service";
import { cn } from "@/utils";
import { getResourceType, getResourceUrl } from "@/utils/resource";
import MemoResource from "./MemoResource";
import showPreviewImageDialog from "./PreviewImageDialog";
const MemoResourceListView = ({ resources = [] }: { resources: Resource[] }) => {
const mediaResources: Resource[] = [];
const otherResources: Resource[] = [];
resources.forEach((resource) => {
const type = getResourceType(resource);
if (type === "image/*" || type === "video/*") {
mediaResources.push(resource);
return;
}
otherResources.push(resource);
});
const handleImageClick = (imgUrl: string) => {
const imgUrls = mediaResources
.filter((resource) => getResourceType(resource) === "image/*")
.map((resource) => getResourceUrl(resource));
const index = imgUrls.findIndex((url) => url === imgUrl);
showPreviewImageDialog(imgUrls, index);
};
const MediaCard = ({ resource, className }: { resource: Resource; className?: string }) => {
const type = getResourceType(resource);
const resourceUrl = getResourceUrl(resource);
if (type === "image/*") {
return (
<img
className={cn(
"cursor-pointer h-full w-auto rounded-lg border border-zinc-200 dark:border-zinc-800 object-contain hover:opacity-80",
className,
)}
src={resource.externalLink ? resourceUrl : resourceUrl + "?thumbnail=true"}
onClick={() => handleImageClick(resourceUrl)}
decoding="async"
loading="lazy"
/>
);
} else if (type === "video/*") {
return (
<video
className={cn(
"cursor-pointer h-full w-auto rounded-lg border border-zinc-200 dark:border-zinc-800 object-contain bg-zinc-100 dark:bg-zinc-800",
className,
)}
preload="metadata"
crossOrigin="anonymous"
src={resourceUrl}
controls
/>
);
} else {
return <></>;
}
};
const MediaList = ({ resources = [] }: { resources: Resource[] }) => {
const cards = resources.map((resource) => (
<div key={resource.name} className="max-w-[70%] grow flex flex-col justify-start items-start shrink-0">
<MediaCard className="max-h-64 grow" resource={resource} />
</div>
));
return <div className="w-full flex flex-row justify-start overflow-auto gap-2">{cards}</div>;
};
const OtherList = ({ resources = [] }: { resources: Resource[] }) => {
if (resources.length === 0) return <></>;
return (
<div className="w-full flex flex-row justify-start overflow-auto gap-2">
{otherResources.map((resource) => (
<MemoResource key={resource.name} resource={resource} />
))}
</div>
);
};
return (
<>
{mediaResources.length > 0 && <MediaList resources={mediaResources} />}
<OtherList resources={otherResources} />
</>
);
};
export default memo(MemoResourceListView);

@ -14,12 +14,12 @@ import { useTranslate } from "@/utils/i18n";
import { convertVisibilityToString } from "@/utils/memo";
import { isSuperUser } from "@/utils/user";
import MemoActionMenu from "./MemoActionMenu";
import MemoAttachmentListView from "./MemoAttachmentListView";
import MemoContent from "./MemoContent";
import MemoEditor from "./MemoEditor";
import MemoLocationView from "./MemoLocationView";
import MemoReactionistView from "./MemoReactionListView";
import MemoRelationListView from "./MemoRelationListView";
import MemoResourceListView from "./MemoResourceListView";
import showPreviewImageDialog from "./PreviewImageDialog";
import ReactionSelector from "./ReactionSelector";
import UserAvatar from "./UserAvatar";
@ -226,7 +226,7 @@ const MemoView: React.FC<Props> = observer((props: Props) => {
parentPage={parentPage}
/>
{memo.location && <MemoLocationView location={memo.location} />}
<MemoResourceListView resources={memo.resources} />
<MemoAttachmentListView attachments={memo.attachments} />
<MemoRelationListView memo={memo} relations={referencedMemos} parentPage={parentPage} />
<MemoReactionistView memo={memo} reactions={memo.reactions} />
</div>

@ -48,10 +48,10 @@ const Navigation = observer((props: Props) => {
title: t("common.explore"),
icon: <EarthIcon className="w-6 h-auto opacity-70 shrink-0" />,
};
const resourcesNavLink: NavLinkItem = {
id: "header-resources",
path: Routes.RESOURCES,
title: t("common.resources"),
const attachmentsNavLink: NavLinkItem = {
id: "header-attachments",
path: Routes.ATTACHMENTS,
title: t("common.attachments"),
icon: <PaperclipIcon className="w-6 h-auto opacity-70 shrink-0" />,
};
const signInNavLink: NavLinkItem = {
@ -61,7 +61,7 @@ const Navigation = observer((props: Props) => {
icon: <UserCircleIcon className="w-6 h-auto opacity-70 shrink-0" />,
};
const navLinks: NavLinkItem[] = currentUser ? [homeNavLink, exploreNavLink, resourcesNavLink] : [exploreNavLink, signInNavLink];
const navLinks: NavLinkItem[] = currentUser ? [homeNavLink, exploreNavLink, attachmentsNavLink] : [exploreNavLink, signInNavLink];
return (
<header

@ -10,22 +10,22 @@ import {
SheetIcon,
} from "lucide-react";
import React from "react";
import { Resource } from "@/types/proto/api/v1/resource_service";
import { Attachment } from "@/types/proto/api/v1/attachment_service";
import { cn } from "@/utils";
import { getResourceType, getResourceUrl } from "@/utils/resource";
import { getAttachmentType, getAttachmentUrl } from "@/utils/attachment";
import showPreviewImageDialog from "./PreviewImageDialog";
import SquareDiv from "./kit/SquareDiv";
interface Props {
resource: Resource;
resource: Attachment;
className?: string;
strokeWidth?: number;
}
const ResourceIcon = (props: Props) => {
const { resource } = props;
const resourceType = getResourceType(resource);
const resourceUrl = getResourceUrl(resource);
const resourceType = getAttachmentType(resource);
const resourceUrl = getAttachmentUrl(resource);
const className = cn("w-full h-auto", props.className);
const strokeWidth = props.strokeWidth;

@ -1,11 +1,11 @@
import { createChannel, createClientFactory, FetchTransport } from "nice-grpc-web";
import { ActivityServiceDefinition } from "./types/proto/api/v1/activity_service";
import { AttachmentServiceDefinition } from "./types/proto/api/v1/attachment_service";
import { AuthServiceDefinition } from "./types/proto/api/v1/auth_service";
import { IdentityProviderServiceDefinition } from "./types/proto/api/v1/idp_service";
import { InboxServiceDefinition } from "./types/proto/api/v1/inbox_service";
import { MarkdownServiceDefinition } from "./types/proto/api/v1/markdown_service";
import { MemoServiceDefinition } from "./types/proto/api/v1/memo_service";
import { ResourceServiceDefinition } from "./types/proto/api/v1/resource_service";
import { ShortcutServiceDefinition } from "./types/proto/api/v1/shortcut_service";
import { UserServiceDefinition } from "./types/proto/api/v1/user_service";
import { WebhookServiceDefinition } from "./types/proto/api/v1/webhook_service";
@ -28,7 +28,7 @@ export const userServiceClient = clientFactory.create(UserServiceDefinition, cha
export const memoServiceClient = clientFactory.create(MemoServiceDefinition, channel);
export const resourceServiceClient = clientFactory.create(ResourceServiceDefinition, channel);
export const attachmentServiceClient = clientFactory.create(AttachmentServiceDefinition, channel);
export const shortcutServiceClient = clientFactory.create(ShortcutServiceDefinition, channel);

@ -26,7 +26,9 @@ const RootLayout = observer(() => {
if (workspaceStore.state.memoRelatedSetting.disallowPublicVisibility) {
window.location.href = Routes.AUTH;
return;
} else if (([Routes.ROOT, Routes.RESOURCES, Routes.INBOX, Routes.ARCHIVED, Routes.SETTING] as string[]).includes(location.pathname)) {
} else if (
([Routes.ROOT, Routes.ATTACHMENTS, Routes.INBOX, Routes.ARCHIVED, Routes.SETTING] as string[]).includes(location.pathname)
) {
window.location.href = Routes.EXPLORE;
return;
}

@ -20,6 +20,7 @@
"admin": "Admin",
"archive": "Archive",
"archived": "Archived",
"attachments": "Attachments",
"avatar": "Avatar",
"basic": "Basic",
"beta": "Beta",

@ -8,17 +8,17 @@ import { useEffect, useState } from "react";
import Empty from "@/components/Empty";
import MobileHeader from "@/components/MobileHeader";
import ResourceIcon from "@/components/ResourceIcon";
import { resourceServiceClient } from "@/grpcweb";
import { attachmentServiceClient } from "@/grpcweb";
import useLoading from "@/hooks/useLoading";
import useResponsiveWidth from "@/hooks/useResponsiveWidth";
import i18n from "@/i18n";
import { memoStore } from "@/store/v2";
import { Resource } from "@/types/proto/api/v1/resource_service";
import { Attachment } from "@/types/proto/api/v1/attachment_service";
import { useTranslate } from "@/utils/i18n";
function groupResourcesByDate(resources: Resource[]) {
const grouped = new Map<string, Resource[]>();
resources
function groupAttachmentsByDate(attachments: Attachment[]) {
const grouped = new Map<string, Attachment[]>();
attachments
.sort((a, b) => dayjs(b.createTime).unix() - dayjs(a.createTime).unix())
.forEach((item) => {
const monthStr = dayjs(item.createTime).format("YYYY-MM");
@ -34,33 +34,33 @@ interface State {
searchQuery: string;
}
const Resources = observer(() => {
const Attachments = observer(() => {
const t = useTranslate();
const { md } = useResponsiveWidth();
const loadingState = useLoading();
const [state, setState] = useState<State>({
searchQuery: "",
});
const [resources, setResources] = useState<Resource[]>([]);
const filteredResources = resources.filter((resource) => includes(resource.filename, state.searchQuery));
const groupedResources = groupResourcesByDate(filteredResources.filter((resource) => resource.memo));
const unusedResources = filteredResources.filter((resource) => !resource.memo);
const [attachments, setAttachments] = useState<Attachment[]>([]);
const filteredAttachments = attachments.filter((attachment) => includes(attachment.filename, state.searchQuery));
const groupedAttachments = groupAttachmentsByDate(filteredAttachments.filter((attachment) => attachment.memo));
const unusedAttachments = filteredAttachments.filter((attachment) => !attachment.memo);
useEffect(() => {
resourceServiceClient.listResources({}).then(({ resources }) => {
setResources(resources);
attachmentServiceClient.listAttachments({}).then(({ attachments }) => {
setAttachments(attachments);
loadingState.setFinish();
Promise.all(resources.map((resource) => (resource.memo ? memoStore.getOrFetchMemoByName(resource.memo) : null)));
Promise.all(attachments.map((attachment) => (attachment.memo ? memoStore.getOrFetchMemoByName(attachment.memo) : null)));
});
}, []);
const handleDeleteUnusedResources = async () => {
const confirmed = window.confirm("Are you sure to delete all unused resources? This action cannot be undone.");
const handleDeleteUnusedAttachments = async () => {
const confirmed = window.confirm("Are you sure to delete all unused attachments? This action cannot be undone.");
if (confirmed) {
for (const resource of unusedResources) {
await resourceServiceClient.deleteResource({ name: resource.name });
for (const attachment of unusedAttachments) {
await attachmentServiceClient.deleteAttachment({ name: attachment.name });
}
setResources(resources.filter((resource) => resource.memo));
setAttachments(attachments.filter((attachment) => attachment.memo));
}
};
@ -72,7 +72,7 @@ const Resources = observer(() => {
<div className="relative w-full flex flex-row justify-between items-center">
<p className="py-1 flex flex-row justify-start items-center select-none opacity-80">
<PaperclipIcon className="w-6 h-auto mr-1 opacity-80" />
<span className="text-lg">{t("common.resources")}</span>
<span className="text-lg">{t("common.attachments")}</span>
</p>
<div>
<Input
@ -91,14 +91,14 @@ const Resources = observer(() => {
</div>
) : (
<>
{filteredResources.length === 0 ? (
{filteredAttachments.length === 0 ? (
<div className="w-full mt-8 mb-8 flex flex-col justify-center items-center italic">
<Empty />
<p className="mt-4 text-gray-600 dark:text-gray-400">{t("message.no-data")}</p>
</div>
) : (
<div className={"w-full h-auto px-2 flex flex-col justify-start items-start gap-y-8"}>
{Array.from(groupedResources.entries()).map(([monthStr, resources]) => {
{Array.from(groupedAttachments.entries()).map(([monthStr, attachments]) => {
return (
<div key={monthStr} className="w-full flex flex-row justify-start items-start">
<div className="w-16 sm:w-24 pt-4 sm:pl-4 flex flex-col justify-start items-start">
@ -108,14 +108,14 @@ const Resources = observer(() => {
</span>
</div>
<div className="w-full max-w-[calc(100%-4rem)] sm:max-w-[calc(100%-6rem)] flex flex-row justify-start items-start gap-4 flex-wrap">
{resources.map((resource) => {
{attachments.map((attachment) => {
return (
<div key={resource.name} className="w-24 sm:w-32 h-auto flex flex-col justify-start items-start">
<div key={attachment.name} className="w-24 sm:w-32 h-auto flex flex-col justify-start items-start">
<div className="w-24 h-24 flex justify-center items-center sm:w-32 sm:h-32 border border-zinc-200 dark:border-zinc-900 overflow-clip rounded-xl cursor-pointer hover:shadow hover:opacity-80">
<ResourceIcon resource={resource} strokeWidth={0.5} />
<ResourceIcon resource={attachment} strokeWidth={0.5} />
</div>
<div className="w-full max-w-full flex flex-row justify-between items-center mt-1 px-1">
<p className="text-xs shrink text-gray-400 truncate">{resource.filename}</p>
<p className="text-xs shrink text-gray-400 truncate">{attachment.filename}</p>
</div>
</div>
);
@ -125,7 +125,7 @@ const Resources = observer(() => {
);
})}
{unusedResources.length > 0 && (
{unusedAttachments.length > 0 && (
<>
<Divider />
<div className="w-full flex flex-row justify-start items-start">
@ -133,21 +133,21 @@ const Resources = observer(() => {
<div className="w-full max-w-[calc(100%-4rem)] sm:max-w-[calc(100%-6rem)] flex flex-row justify-start items-start gap-4 flex-wrap">
<div className="w-full flex flex-row justify-start items-center gap-2">
<span className="text-gray-600 dark:text-gray-400">{t("resource.unused-resources")}</span>
<span className="text-gray-500 dark:text-gray-500 opacity-80">({unusedResources.length})</span>
<span className="text-gray-500 dark:text-gray-500 opacity-80">({unusedAttachments.length})</span>
<Tooltip title="Delete all" placement="top">
<Button variant="plain" onClick={handleDeleteUnusedResources}>
<Button variant="plain" onClick={handleDeleteUnusedAttachments}>
<TrashIcon className="w-4 h-auto opacity-60" />
</Button>
</Tooltip>
</div>
{unusedResources.map((resource) => {
{unusedAttachments.map((attachment) => {
return (
<div key={resource.name} className="w-24 sm:w-32 h-auto flex flex-col justify-start items-start">
<div key={attachment.name} className="w-24 sm:w-32 h-auto flex flex-col justify-start items-start">
<div className="w-24 h-24 flex justify-center items-center sm:w-32 sm:h-32 border border-zinc-200 dark:border-zinc-900 overflow-clip rounded-xl cursor-pointer hover:shadow hover:opacity-80">
<ResourceIcon resource={resource} strokeWidth={0.5} />
<ResourceIcon resource={attachment} strokeWidth={0.5} />
</div>
<div className="w-full max-w-full flex flex-row justify-between items-center mt-1 px-1">
<p className="text-xs shrink text-gray-400 truncate">{resource.filename}</p>
<p className="text-xs shrink text-gray-400 truncate">{attachment.filename}</p>
</div>
</div>
);
@ -167,4 +167,4 @@ const Resources = observer(() => {
);
});
export default Resources;
export default Attachments;

@ -14,7 +14,7 @@ const Inboxes = lazy(() => import("@/pages/Inboxes"));
const MemoDetail = lazy(() => import("@/pages/MemoDetail"));
const NotFound = lazy(() => import("@/pages/NotFound"));
const PermissionDenied = lazy(() => import("@/pages/PermissionDenied"));
const Resources = lazy(() => import("@/pages/Resources"));
const Attachments = lazy(() => import("@/pages/Attachments"));
const Setting = lazy(() => import("@/pages/Setting"));
const SignIn = lazy(() => import("@/pages/SignIn"));
const SignUp = lazy(() => import("@/pages/SignUp"));
@ -23,7 +23,7 @@ const MemoDetailRedirect = lazy(() => import("./MemoDetailRedirect"));
export enum Routes {
ROOT = "/",
RESOURCES = "/resources",
ATTACHMENTS = "/attachments",
INBOX = "/inbox",
ARCHIVED = "/archived",
SETTING = "/setting",
@ -111,10 +111,10 @@ const router = createBrowserRouter([
),
},
{
path: Routes.RESOURCES,
path: Routes.ATTACHMENTS,
element: (
<Suspense fallback={<Loading />}>
<Resources />
<Attachments />
</Suspense>
),
},

@ -0,0 +1,59 @@
import { makeAutoObservable } from "mobx";
import { attachmentServiceClient } from "@/grpcweb";
import { CreateAttachmentRequest, Attachment, UpdateAttachmentRequest } from "@/types/proto/api/v1/attachment_service";
class LocalState {
attachmentMapByName: Record<string, Attachment> = {};
constructor() {
makeAutoObservable(this);
}
setPartial(partial: Partial<LocalState>) {
Object.assign(this, partial);
}
}
const attachmentStore = (() => {
const state = new LocalState();
const fetchAttachmentByName = async (name: string) => {
const attachment = await attachmentServiceClient.getAttachment({
name,
});
const attachmentMap = { ...state.attachmentMapByName };
attachmentMap[attachment.name] = attachment;
state.setPartial({ attachmentMapByName: attachmentMap });
return attachment;
};
const getAttachmentByName = (name: string) => {
return Object.values(state.attachmentMapByName).find((a) => a.name === name);
};
const createAttachment = async (create: CreateAttachmentRequest): Promise<Attachment> => {
const attachment = await attachmentServiceClient.createAttachment(create);
const attachmentMap = { ...state.attachmentMapByName };
attachmentMap[attachment.name] = attachment;
state.setPartial({ attachmentMapByName: attachmentMap });
return attachment;
};
const updateAttachment = async (update: UpdateAttachmentRequest): Promise<Attachment> => {
const attachment = await attachmentServiceClient.updateAttachment(update);
const attachmentMap = { ...state.attachmentMapByName };
attachmentMap[attachment.name] = attachment;
state.setPartial({ attachmentMapByName: attachmentMap });
return attachment;
};
return {
state,
fetchAttachmentByName,
getAttachmentByName,
createAttachment,
updateAttachment,
};
})();
export default attachmentStore;

@ -1,8 +1,8 @@
import attachmentStore from "./attachment";
import memoStore from "./memo";
import memoFilterStore from "./memoFilter";
import resourceStore from "./resource";
import userStore from "./user";
import viewStore from "./view";
import workspaceStore from "./workspace";
export { memoFilterStore, memoStore, resourceStore, workspaceStore, userStore, viewStore };
export { memoFilterStore, memoStore, attachmentStore, workspaceStore, userStore, viewStore };

@ -1,59 +0,0 @@
import { makeAutoObservable } from "mobx";
import { resourceServiceClient } from "@/grpcweb";
import { CreateResourceRequest, Resource, UpdateResourceRequest } from "@/types/proto/api/v1/resource_service";
class LocalState {
resourceMapByName: Record<string, Resource> = {};
constructor() {
makeAutoObservable(this);
}
setPartial(partial: Partial<LocalState>) {
Object.assign(this, partial);
}
}
const resourceStore = (() => {
const state = new LocalState();
const fetchResourceByName = async (name: string) => {
const resource = await resourceServiceClient.getResource({
name,
});
const resourceMap = { ...state.resourceMapByName };
resourceMap[resource.name] = resource;
state.setPartial({ resourceMapByName: resourceMap });
return resource;
};
const getResourceByName = (name: string) => {
return Object.values(state.resourceMapByName).find((r) => r.name === name);
};
const createResource = async (create: CreateResourceRequest): Promise<Resource> => {
const resource = await resourceServiceClient.createResource(create);
const resourceMap = { ...state.resourceMapByName };
resourceMap[resource.name] = resource;
state.setPartial({ resourceMapByName: resourceMap });
return resource;
};
const updateResource = async (update: UpdateResourceRequest): Promise<Resource> => {
const resource = await resourceServiceClient.updateResource(update);
const resourceMap = { ...state.resourceMapByName };
resourceMap[resource.name] = resource;
state.setPartial({ resourceMapByName: resourceMap });
return resource;
};
return {
state,
fetchResourceByName,
getResourceByName,
createResource,
updateResource,
};
})();
export default resourceStore;

@ -2,7 +2,7 @@
// versions:
// protoc-gen-ts_proto v2.6.1
// protoc unknown
// source: api/v1/resource_service.proto
// source: api/v1/attachment_service.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
@ -13,58 +13,122 @@ import { Timestamp } from "../../google/protobuf/timestamp";
export const protobufPackage = "memos.api.v1";
export interface Resource {
export interface Attachment {
/**
* The name of the resource.
* Format: resources/{resource}, resource is the user defined if or uuid.
* The name of the attachment.
* Format: attachments/{attachment}
*/
name: string;
createTime?: Date | undefined;
/** Output only. The creation timestamp. */
createTime?:
| Date
| undefined;
/** The filename of the attachment. */
filename: string;
/** Input only. The content of the attachment. */
content: Uint8Array;
/** Optional. The external link of the attachment. */
externalLink: string;
/** The MIME type of the attachment. */
type: string;
/** Output only. The size of the attachment in bytes. */
size: number;
/** The related memo. Refer to `Memo.name`. */
/**
* Optional. The related memo. Refer to `Memo.name`.
* Format: memos/{memo}
*/
memo?: string | undefined;
}
export interface CreateResourceRequest {
resource?: Resource | undefined;
export interface CreateAttachmentRequest {
/** Required. The attachment to create. */
attachment?:
| Attachment
| undefined;
/**
* Optional. The attachment ID to use for this attachment.
* If empty, a unique ID will be generated.
*/
attachmentId: string;
}
export interface ListResourcesRequest {
export interface ListAttachmentsRequest {
/**
* Optional. The maximum number of attachments to return.
* The service may return fewer than this value.
* If unspecified, at most 50 attachments will be returned.
* The maximum value is 1000; values above 1000 will be coerced to 1000.
*/
pageSize: number;
/**
* Optional. A page token, received from a previous `ListAttachments` call.
* Provide this to retrieve the subsequent page.
*/
pageToken: string;
/**
* Optional. Filter to apply to the list results.
* Example: "type=image/png" or "filename:*.jpg"
* Supported operators: =, !=, <, <=, >, >=, :
* Supported fields: filename, type, size, create_time, memo
*/
filter: string;
/**
* Optional. The order to sort results by.
* Example: "create_time desc" or "filename asc"
*/
orderBy: string;
}
export interface ListResourcesResponse {
resources: Resource[];
export interface ListAttachmentsResponse {
/** The list of attachments. */
attachments: Attachment[];
/**
* A token that can be sent as `page_token` to retrieve the next page.
* If this field is omitted, there are no subsequent pages.
*/
nextPageToken: string;
/** The total count of attachments (may be approximate). */
totalSize: number;
}
export interface GetResourceRequest {
/** The name of the resource. */
export interface GetAttachmentRequest {
/**
* Required. The attachment name of the attachment to retrieve.
* Format: attachments/{attachment}
*/
name: string;
}
export interface GetResourceBinaryRequest {
/** The name of the resource. */
export interface GetAttachmentBinaryRequest {
/**
* Required. The attachment name of the attachment.
* Format: attachments/{attachment}
*/
name: string;
/** The filename of the resource. Mainly used for downloading. */
/** The filename of the attachment. Mainly used for downloading. */
filename: string;
/** A flag indicating if the thumbnail version of the resource should be returned */
/** Optional. A flag indicating if the thumbnail version of the attachment should be returned. */
thumbnail: boolean;
}
export interface UpdateResourceRequest {
resource?: Resource | undefined;
export interface UpdateAttachmentRequest {
/** Required. The attachment which replaces the attachment on the server. */
attachment?:
| Attachment
| undefined;
/** Required. The list of fields to update. */
updateMask?: string[] | undefined;
}
export interface DeleteResourceRequest {
/** The name of the resource. */
export interface DeleteAttachmentRequest {
/**
* Required. The attachment name of the attachment to delete.
* Format: attachments/{attachment}
*/
name: string;
}
function createBaseResource(): Resource {
function createBaseAttachment(): Attachment {
return {
name: "",
createTime: undefined,
@ -77,8 +141,8 @@ function createBaseResource(): Resource {
};
}
export const Resource: MessageFns<Resource> = {
encode(message: Resource, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
export const Attachment: MessageFns<Attachment> = {
encode(message: Attachment, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.name !== "") {
writer.uint32(10).string(message.name);
}
@ -106,10 +170,10 @@ export const Resource: MessageFns<Resource> = {
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): Resource {
decode(input: BinaryReader | Uint8Array, length?: number): Attachment {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseResource();
const message = createBaseAttachment();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
@ -186,11 +250,11 @@ export const Resource: MessageFns<Resource> = {
return message;
},
create(base?: DeepPartial<Resource>): Resource {
return Resource.fromPartial(base ?? {});
create(base?: DeepPartial<Attachment>): Attachment {
return Attachment.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<Resource>): Resource {
const message = createBaseResource();
fromPartial(object: DeepPartial<Attachment>): Attachment {
const message = createBaseAttachment();
message.name = object.name ?? "";
message.createTime = object.createTime ?? undefined;
message.filename = object.filename ?? "";
@ -203,22 +267,25 @@ export const Resource: MessageFns<Resource> = {
},
};
function createBaseCreateResourceRequest(): CreateResourceRequest {
return { resource: undefined };
function createBaseCreateAttachmentRequest(): CreateAttachmentRequest {
return { attachment: undefined, attachmentId: "" };
}
export const CreateResourceRequest: MessageFns<CreateResourceRequest> = {
encode(message: CreateResourceRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.resource !== undefined) {
Resource.encode(message.resource, writer.uint32(10).fork()).join();
export const CreateAttachmentRequest: MessageFns<CreateAttachmentRequest> = {
encode(message: CreateAttachmentRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.attachment !== undefined) {
Attachment.encode(message.attachment, writer.uint32(10).fork()).join();
}
if (message.attachmentId !== "") {
writer.uint32(18).string(message.attachmentId);
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): CreateResourceRequest {
decode(input: BinaryReader | Uint8Array, length?: number): CreateAttachmentRequest {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseCreateResourceRequest();
const message = createBaseCreateAttachmentRequest();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
@ -227,7 +294,15 @@ export const CreateResourceRequest: MessageFns<CreateResourceRequest> = {
break;
}
message.resource = Resource.decode(reader, reader.uint32());
message.attachment = Attachment.decode(reader, reader.uint32());
continue;
}
case 2: {
if (tag !== 18) {
break;
}
message.attachmentId = reader.string();
continue;
}
}
@ -239,34 +314,79 @@ export const CreateResourceRequest: MessageFns<CreateResourceRequest> = {
return message;
},
create(base?: DeepPartial<CreateResourceRequest>): CreateResourceRequest {
return CreateResourceRequest.fromPartial(base ?? {});
create(base?: DeepPartial<CreateAttachmentRequest>): CreateAttachmentRequest {
return CreateAttachmentRequest.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<CreateResourceRequest>): CreateResourceRequest {
const message = createBaseCreateResourceRequest();
message.resource = (object.resource !== undefined && object.resource !== null)
? Resource.fromPartial(object.resource)
fromPartial(object: DeepPartial<CreateAttachmentRequest>): CreateAttachmentRequest {
const message = createBaseCreateAttachmentRequest();
message.attachment = (object.attachment !== undefined && object.attachment !== null)
? Attachment.fromPartial(object.attachment)
: undefined;
message.attachmentId = object.attachmentId ?? "";
return message;
},
};
function createBaseListResourcesRequest(): ListResourcesRequest {
return {};
function createBaseListAttachmentsRequest(): ListAttachmentsRequest {
return { pageSize: 0, pageToken: "", filter: "", orderBy: "" };
}
export const ListResourcesRequest: MessageFns<ListResourcesRequest> = {
encode(_: ListResourcesRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
export const ListAttachmentsRequest: MessageFns<ListAttachmentsRequest> = {
encode(message: ListAttachmentsRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.pageSize !== 0) {
writer.uint32(8).int32(message.pageSize);
}
if (message.pageToken !== "") {
writer.uint32(18).string(message.pageToken);
}
if (message.filter !== "") {
writer.uint32(26).string(message.filter);
}
if (message.orderBy !== "") {
writer.uint32(34).string(message.orderBy);
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): ListResourcesRequest {
decode(input: BinaryReader | Uint8Array, length?: number): ListAttachmentsRequest {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseListResourcesRequest();
const message = createBaseListAttachmentsRequest();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1: {
if (tag !== 8) {
break;
}
message.pageSize = reader.int32();
continue;
}
case 2: {
if (tag !== 18) {
break;
}
message.pageToken = reader.string();
continue;
}
case 3: {
if (tag !== 26) {
break;
}
message.filter = reader.string();
continue;
}
case 4: {
if (tag !== 34) {
break;
}
message.orderBy = reader.string();
continue;
}
}
if ((tag & 7) === 4 || tag === 0) {
break;
@ -276,31 +396,41 @@ export const ListResourcesRequest: MessageFns<ListResourcesRequest> = {
return message;
},
create(base?: DeepPartial<ListResourcesRequest>): ListResourcesRequest {
return ListResourcesRequest.fromPartial(base ?? {});
create(base?: DeepPartial<ListAttachmentsRequest>): ListAttachmentsRequest {
return ListAttachmentsRequest.fromPartial(base ?? {});
},
fromPartial(_: DeepPartial<ListResourcesRequest>): ListResourcesRequest {
const message = createBaseListResourcesRequest();
fromPartial(object: DeepPartial<ListAttachmentsRequest>): ListAttachmentsRequest {
const message = createBaseListAttachmentsRequest();
message.pageSize = object.pageSize ?? 0;
message.pageToken = object.pageToken ?? "";
message.filter = object.filter ?? "";
message.orderBy = object.orderBy ?? "";
return message;
},
};
function createBaseListResourcesResponse(): ListResourcesResponse {
return { resources: [] };
function createBaseListAttachmentsResponse(): ListAttachmentsResponse {
return { attachments: [], nextPageToken: "", totalSize: 0 };
}
export const ListResourcesResponse: MessageFns<ListResourcesResponse> = {
encode(message: ListResourcesResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
for (const v of message.resources) {
Resource.encode(v!, writer.uint32(10).fork()).join();
export const ListAttachmentsResponse: MessageFns<ListAttachmentsResponse> = {
encode(message: ListAttachmentsResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
for (const v of message.attachments) {
Attachment.encode(v!, writer.uint32(10).fork()).join();
}
if (message.nextPageToken !== "") {
writer.uint32(18).string(message.nextPageToken);
}
if (message.totalSize !== 0) {
writer.uint32(24).int32(message.totalSize);
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): ListResourcesResponse {
decode(input: BinaryReader | Uint8Array, length?: number): ListAttachmentsResponse {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseListResourcesResponse();
const message = createBaseListAttachmentsResponse();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
@ -309,7 +439,23 @@ export const ListResourcesResponse: MessageFns<ListResourcesResponse> = {
break;
}
message.resources.push(Resource.decode(reader, reader.uint32()));
message.attachments.push(Attachment.decode(reader, reader.uint32()));
continue;
}
case 2: {
if (tag !== 18) {
break;
}
message.nextPageToken = reader.string();
continue;
}
case 3: {
if (tag !== 24) {
break;
}
message.totalSize = reader.int32();
continue;
}
}
@ -321,32 +467,34 @@ export const ListResourcesResponse: MessageFns<ListResourcesResponse> = {
return message;
},
create(base?: DeepPartial<ListResourcesResponse>): ListResourcesResponse {
return ListResourcesResponse.fromPartial(base ?? {});
create(base?: DeepPartial<ListAttachmentsResponse>): ListAttachmentsResponse {
return ListAttachmentsResponse.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<ListResourcesResponse>): ListResourcesResponse {
const message = createBaseListResourcesResponse();
message.resources = object.resources?.map((e) => Resource.fromPartial(e)) || [];
fromPartial(object: DeepPartial<ListAttachmentsResponse>): ListAttachmentsResponse {
const message = createBaseListAttachmentsResponse();
message.attachments = object.attachments?.map((e) => Attachment.fromPartial(e)) || [];
message.nextPageToken = object.nextPageToken ?? "";
message.totalSize = object.totalSize ?? 0;
return message;
},
};
function createBaseGetResourceRequest(): GetResourceRequest {
function createBaseGetAttachmentRequest(): GetAttachmentRequest {
return { name: "" };
}
export const GetResourceRequest: MessageFns<GetResourceRequest> = {
encode(message: GetResourceRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
export const GetAttachmentRequest: MessageFns<GetAttachmentRequest> = {
encode(message: GetAttachmentRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.name !== "") {
writer.uint32(10).string(message.name);
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): GetResourceRequest {
decode(input: BinaryReader | Uint8Array, length?: number): GetAttachmentRequest {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseGetResourceRequest();
const message = createBaseGetAttachmentRequest();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
@ -367,22 +515,22 @@ export const GetResourceRequest: MessageFns<GetResourceRequest> = {
return message;
},
create(base?: DeepPartial<GetResourceRequest>): GetResourceRequest {
return GetResourceRequest.fromPartial(base ?? {});
create(base?: DeepPartial<GetAttachmentRequest>): GetAttachmentRequest {
return GetAttachmentRequest.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<GetResourceRequest>): GetResourceRequest {
const message = createBaseGetResourceRequest();
fromPartial(object: DeepPartial<GetAttachmentRequest>): GetAttachmentRequest {
const message = createBaseGetAttachmentRequest();
message.name = object.name ?? "";
return message;
},
};
function createBaseGetResourceBinaryRequest(): GetResourceBinaryRequest {
function createBaseGetAttachmentBinaryRequest(): GetAttachmentBinaryRequest {
return { name: "", filename: "", thumbnail: false };
}
export const GetResourceBinaryRequest: MessageFns<GetResourceBinaryRequest> = {
encode(message: GetResourceBinaryRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
export const GetAttachmentBinaryRequest: MessageFns<GetAttachmentBinaryRequest> = {
encode(message: GetAttachmentBinaryRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.name !== "") {
writer.uint32(10).string(message.name);
}
@ -395,10 +543,10 @@ export const GetResourceBinaryRequest: MessageFns<GetResourceBinaryRequest> = {
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): GetResourceBinaryRequest {
decode(input: BinaryReader | Uint8Array, length?: number): GetAttachmentBinaryRequest {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseGetResourceBinaryRequest();
const message = createBaseGetAttachmentBinaryRequest();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
@ -435,11 +583,11 @@ export const GetResourceBinaryRequest: MessageFns<GetResourceBinaryRequest> = {
return message;
},
create(base?: DeepPartial<GetResourceBinaryRequest>): GetResourceBinaryRequest {
return GetResourceBinaryRequest.fromPartial(base ?? {});
create(base?: DeepPartial<GetAttachmentBinaryRequest>): GetAttachmentBinaryRequest {
return GetAttachmentBinaryRequest.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<GetResourceBinaryRequest>): GetResourceBinaryRequest {
const message = createBaseGetResourceBinaryRequest();
fromPartial(object: DeepPartial<GetAttachmentBinaryRequest>): GetAttachmentBinaryRequest {
const message = createBaseGetAttachmentBinaryRequest();
message.name = object.name ?? "";
message.filename = object.filename ?? "";
message.thumbnail = object.thumbnail ?? false;
@ -447,14 +595,14 @@ export const GetResourceBinaryRequest: MessageFns<GetResourceBinaryRequest> = {
},
};
function createBaseUpdateResourceRequest(): UpdateResourceRequest {
return { resource: undefined, updateMask: undefined };
function createBaseUpdateAttachmentRequest(): UpdateAttachmentRequest {
return { attachment: undefined, updateMask: undefined };
}
export const UpdateResourceRequest: MessageFns<UpdateResourceRequest> = {
encode(message: UpdateResourceRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.resource !== undefined) {
Resource.encode(message.resource, writer.uint32(10).fork()).join();
export const UpdateAttachmentRequest: MessageFns<UpdateAttachmentRequest> = {
encode(message: UpdateAttachmentRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.attachment !== undefined) {
Attachment.encode(message.attachment, writer.uint32(10).fork()).join();
}
if (message.updateMask !== undefined) {
FieldMask.encode(FieldMask.wrap(message.updateMask), writer.uint32(18).fork()).join();
@ -462,10 +610,10 @@ export const UpdateResourceRequest: MessageFns<UpdateResourceRequest> = {
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): UpdateResourceRequest {
decode(input: BinaryReader | Uint8Array, length?: number): UpdateAttachmentRequest {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseUpdateResourceRequest();
const message = createBaseUpdateAttachmentRequest();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
@ -474,7 +622,7 @@ export const UpdateResourceRequest: MessageFns<UpdateResourceRequest> = {
break;
}
message.resource = Resource.decode(reader, reader.uint32());
message.attachment = Attachment.decode(reader, reader.uint32());
continue;
}
case 2: {
@ -494,35 +642,35 @@ export const UpdateResourceRequest: MessageFns<UpdateResourceRequest> = {
return message;
},
create(base?: DeepPartial<UpdateResourceRequest>): UpdateResourceRequest {
return UpdateResourceRequest.fromPartial(base ?? {});
create(base?: DeepPartial<UpdateAttachmentRequest>): UpdateAttachmentRequest {
return UpdateAttachmentRequest.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<UpdateResourceRequest>): UpdateResourceRequest {
const message = createBaseUpdateResourceRequest();
message.resource = (object.resource !== undefined && object.resource !== null)
? Resource.fromPartial(object.resource)
fromPartial(object: DeepPartial<UpdateAttachmentRequest>): UpdateAttachmentRequest {
const message = createBaseUpdateAttachmentRequest();
message.attachment = (object.attachment !== undefined && object.attachment !== null)
? Attachment.fromPartial(object.attachment)
: undefined;
message.updateMask = object.updateMask ?? undefined;
return message;
},
};
function createBaseDeleteResourceRequest(): DeleteResourceRequest {
function createBaseDeleteAttachmentRequest(): DeleteAttachmentRequest {
return { name: "" };
}
export const DeleteResourceRequest: MessageFns<DeleteResourceRequest> = {
encode(message: DeleteResourceRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
export const DeleteAttachmentRequest: MessageFns<DeleteAttachmentRequest> = {
encode(message: DeleteAttachmentRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.name !== "") {
writer.uint32(10).string(message.name);
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): DeleteResourceRequest {
decode(input: BinaryReader | Uint8Array, length?: number): DeleteAttachmentRequest {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseDeleteResourceRequest();
const message = createBaseDeleteAttachmentRequest();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
@ -543,45 +691,48 @@ export const DeleteResourceRequest: MessageFns<DeleteResourceRequest> = {
return message;
},
create(base?: DeepPartial<DeleteResourceRequest>): DeleteResourceRequest {
return DeleteResourceRequest.fromPartial(base ?? {});
create(base?: DeepPartial<DeleteAttachmentRequest>): DeleteAttachmentRequest {
return DeleteAttachmentRequest.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<DeleteResourceRequest>): DeleteResourceRequest {
const message = createBaseDeleteResourceRequest();
fromPartial(object: DeepPartial<DeleteAttachmentRequest>): DeleteAttachmentRequest {
const message = createBaseDeleteAttachmentRequest();
message.name = object.name ?? "";
return message;
},
};
export type ResourceServiceDefinition = typeof ResourceServiceDefinition;
export const ResourceServiceDefinition = {
name: "ResourceService",
fullName: "memos.api.v1.ResourceService",
export type AttachmentServiceDefinition = typeof AttachmentServiceDefinition;
export const AttachmentServiceDefinition = {
name: "AttachmentService",
fullName: "memos.api.v1.AttachmentService",
methods: {
/** CreateResource creates a new resource. */
createResource: {
name: "CreateResource",
requestType: CreateResourceRequest,
/** CreateAttachment creates a new attachment. */
createAttachment: {
name: "CreateAttachment",
requestType: CreateAttachmentRequest,
requestStream: false,
responseType: Resource,
responseType: Attachment,
responseStream: false,
options: {
_unknownFields: {
8410: [new Uint8Array([10, 97, 116, 116, 97, 99, 104, 109, 101, 110, 116])],
578365826: [
new Uint8Array([
29,
33,
58,
8,
114,
101,
115,
111,
117,
114,
10,
97,
116,
116,
97,
99,
104,
109,
101,
110,
116,
34,
17,
19,
47,
97,
112,
@ -590,50 +741,75 @@ export const ResourceServiceDefinition = {
118,
49,
47,
114,
101,
115,
111,
117,
114,
97,
116,
116,
97,
99,
104,
109,
101,
110,
116,
115,
]),
],
},
},
},
/** ListResources lists all resources. */
listResources: {
name: "ListResources",
requestType: ListResourcesRequest,
/** ListAttachments lists all attachments. */
listAttachments: {
name: "ListAttachments",
requestType: ListAttachmentsRequest,
requestStream: false,
responseType: ListResourcesResponse,
responseType: ListAttachmentsResponse,
responseStream: false,
options: {
_unknownFields: {
578365826: [
new Uint8Array([19, 18, 17, 47, 97, 112, 105, 47, 118, 49, 47, 114, 101, 115, 111, 117, 114, 99, 101, 115]),
new Uint8Array([
21,
18,
19,
47,
97,
112,
105,
47,
118,
49,
47,
97,
116,
116,
97,
99,
104,
109,
101,
110,
116,
115,
]),
],
},
},
},
/** GetResource returns a resource by name. */
getResource: {
name: "GetResource",
requestType: GetResourceRequest,
/** GetAttachment returns a attachment by name. */
getAttachment: {
name: "GetAttachment",
requestType: GetAttachmentRequest,
requestStream: false,
responseType: Resource,
responseType: Attachment,
responseStream: false,
options: {
_unknownFields: {
8410: [new Uint8Array([4, 110, 97, 109, 101])],
578365826: [
new Uint8Array([
28,
30,
18,
26,
28,
47,
97,
112,
@ -648,14 +824,16 @@ export const ResourceServiceDefinition = {
109,
101,
61,
114,
101,
115,
111,
117,
114,
97,
116,
116,
97,
99,
104,
109,
101,
110,
116,
115,
47,
42,
@ -665,10 +843,10 @@ export const ResourceServiceDefinition = {
},
},
},
/** GetResourceBinary returns a resource binary by name. */
getResourceBinary: {
name: "GetResourceBinary",
requestType: GetResourceBinaryRequest,
/** GetAttachmentBinary returns a attachment binary by name. */
getAttachmentBinary: {
name: "GetAttachmentBinary",
requestType: GetAttachmentBinaryRequest,
requestStream: false,
responseType: HttpBody,
responseStream: false,
@ -677,9 +855,9 @@ export const ResourceServiceDefinition = {
8410: [new Uint8Array([13, 110, 97, 109, 101, 44, 102, 105, 108, 101, 110, 97, 109, 101])],
578365826: [
new Uint8Array([
37,
39,
18,
35,
37,
47,
102,
105,
@ -692,14 +870,16 @@ export const ResourceServiceDefinition = {
109,
101,
61,
114,
101,
115,
111,
117,
114,
97,
116,
116,
97,
99,
104,
109,
101,
110,
116,
115,
47,
42,
@ -720,26 +900,28 @@ export const ResourceServiceDefinition = {
},
},
},
/** UpdateResource updates a resource. */
updateResource: {
name: "UpdateResource",
requestType: UpdateResourceRequest,
/** UpdateAttachment updates a attachment. */
updateAttachment: {
name: "UpdateAttachment",
requestType: UpdateAttachmentRequest,
requestStream: false,
responseType: Resource,
responseType: Attachment,
responseStream: false,
options: {
_unknownFields: {
8410: [
new Uint8Array([
20,
114,
101,
115,
111,
117,
114,
22,
97,
116,
116,
97,
99,
104,
109,
101,
110,
116,
44,
117,
112,
@ -756,19 +938,21 @@ export const ResourceServiceDefinition = {
],
578365826: [
new Uint8Array([
47,
53,
58,
8,
114,
101,
115,
111,
117,
114,
10,
97,
116,
116,
97,
99,
104,
109,
101,
110,
116,
50,
35,
39,
47,
97,
112,
@ -778,28 +962,32 @@ export const ResourceServiceDefinition = {
49,
47,
123,
114,
101,
115,
111,
117,
114,
97,
116,
116,
97,
99,
104,
109,
101,
110,
116,
46,
110,
97,
109,
101,
61,
114,
101,
115,
111,
117,
114,
97,
116,
116,
97,
99,
104,
109,
101,
110,
116,
115,
47,
42,
@ -809,10 +997,10 @@ export const ResourceServiceDefinition = {
},
},
},
/** DeleteResource deletes a resource by name. */
deleteResource: {
name: "DeleteResource",
requestType: DeleteResourceRequest,
/** DeleteAttachment deletes a attachment by name. */
deleteAttachment: {
name: "DeleteAttachment",
requestType: DeleteAttachmentRequest,
requestStream: false,
responseType: Empty,
responseStream: false,
@ -821,9 +1009,9 @@ export const ResourceServiceDefinition = {
8410: [new Uint8Array([4, 110, 97, 109, 101])],
578365826: [
new Uint8Array([
28,
30,
42,
26,
28,
47,
97,
112,
@ -838,14 +1026,16 @@ export const ResourceServiceDefinition = {
109,
101,
61,
114,
101,
115,
111,
117,
114,
97,
116,
116,
97,
99,
104,
109,
101,
110,
116,
115,
47,
42,

@ -9,10 +9,10 @@ import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
import { Empty } from "../../google/protobuf/empty";
import { FieldMask } from "../../google/protobuf/field_mask";
import { Timestamp } from "../../google/protobuf/timestamp";
import { Attachment } from "./attachment_service";
import { Direction, directionFromJSON, directionToNumber, State, stateFromJSON, stateToNumber } from "./common";
import { Node } from "./markdown_service";
import { Reaction } from "./reaction_service";
import { Resource } from "./resource_service";
export const protobufPackage = "memos.api.v1";
@ -81,7 +81,7 @@ export interface Memo {
visibility: Visibility;
tags: string[];
pinned: boolean;
resources: Resource[];
attachments: Attachment[];
relations: MemoRelation[];
reactions: Reaction[];
property?:
@ -206,19 +206,19 @@ export interface DeleteMemoTagRequest {
deleteRelatedMemos: boolean;
}
export interface SetMemoResourcesRequest {
export interface SetMemoAttachmentsRequest {
/** The name of the memo. */
name: string;
resources: Resource[];
attachments: Attachment[];
}
export interface ListMemoResourcesRequest {
export interface ListMemoAttachmentsRequest {
/** The name of the memo. */
name: string;
}
export interface ListMemoResourcesResponse {
resources: Resource[];
export interface ListMemoAttachmentsResponse {
attachments: Attachment[];
}
export interface MemoRelation {
@ -344,7 +344,7 @@ function createBaseMemo(): Memo {
visibility: Visibility.VISIBILITY_UNSPECIFIED,
tags: [],
pinned: false,
resources: [],
attachments: [],
relations: [],
reactions: [],
property: undefined,
@ -389,8 +389,8 @@ export const Memo: MessageFns<Memo> = {
if (message.pinned !== false) {
writer.uint32(96).bool(message.pinned);
}
for (const v of message.resources) {
Resource.encode(v!, writer.uint32(114).fork()).join();
for (const v of message.attachments) {
Attachment.encode(v!, writer.uint32(114).fork()).join();
}
for (const v of message.relations) {
MemoRelation.encode(v!, writer.uint32(122).fork()).join();
@ -513,7 +513,7 @@ export const Memo: MessageFns<Memo> = {
break;
}
message.resources.push(Resource.decode(reader, reader.uint32()));
message.attachments.push(Attachment.decode(reader, reader.uint32()));
continue;
}
case 15: {
@ -589,7 +589,7 @@ export const Memo: MessageFns<Memo> = {
message.visibility = object.visibility ?? Visibility.VISIBILITY_UNSPECIFIED;
message.tags = object.tags?.map((e) => e) || [];
message.pinned = object.pinned ?? false;
message.resources = object.resources?.map((e) => Resource.fromPartial(e)) || [];
message.attachments = object.attachments?.map((e) => Attachment.fromPartial(e)) || [];
message.relations = object.relations?.map((e) => MemoRelation.fromPartial(e)) || [];
message.reactions = object.reactions?.map((e) => Reaction.fromPartial(e)) || [];
message.property = (object.property !== undefined && object.property !== null)
@ -1289,25 +1289,25 @@ export const DeleteMemoTagRequest: MessageFns<DeleteMemoTagRequest> = {
},
};
function createBaseSetMemoResourcesRequest(): SetMemoResourcesRequest {
return { name: "", resources: [] };
function createBaseSetMemoAttachmentsRequest(): SetMemoAttachmentsRequest {
return { name: "", attachments: [] };
}
export const SetMemoResourcesRequest: MessageFns<SetMemoResourcesRequest> = {
encode(message: SetMemoResourcesRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
export const SetMemoAttachmentsRequest: MessageFns<SetMemoAttachmentsRequest> = {
encode(message: SetMemoAttachmentsRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.name !== "") {
writer.uint32(10).string(message.name);
}
for (const v of message.resources) {
Resource.encode(v!, writer.uint32(18).fork()).join();
for (const v of message.attachments) {
Attachment.encode(v!, writer.uint32(18).fork()).join();
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): SetMemoResourcesRequest {
decode(input: BinaryReader | Uint8Array, length?: number): SetMemoAttachmentsRequest {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseSetMemoResourcesRequest();
const message = createBaseSetMemoAttachmentsRequest();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
@ -1324,7 +1324,7 @@ export const SetMemoResourcesRequest: MessageFns<SetMemoResourcesRequest> = {
break;
}
message.resources.push(Resource.decode(reader, reader.uint32()));
message.attachments.push(Attachment.decode(reader, reader.uint32()));
continue;
}
}
@ -1336,33 +1336,33 @@ export const SetMemoResourcesRequest: MessageFns<SetMemoResourcesRequest> = {
return message;
},
create(base?: DeepPartial<SetMemoResourcesRequest>): SetMemoResourcesRequest {
return SetMemoResourcesRequest.fromPartial(base ?? {});
create(base?: DeepPartial<SetMemoAttachmentsRequest>): SetMemoAttachmentsRequest {
return SetMemoAttachmentsRequest.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<SetMemoResourcesRequest>): SetMemoResourcesRequest {
const message = createBaseSetMemoResourcesRequest();
fromPartial(object: DeepPartial<SetMemoAttachmentsRequest>): SetMemoAttachmentsRequest {
const message = createBaseSetMemoAttachmentsRequest();
message.name = object.name ?? "";
message.resources = object.resources?.map((e) => Resource.fromPartial(e)) || [];
message.attachments = object.attachments?.map((e) => Attachment.fromPartial(e)) || [];
return message;
},
};
function createBaseListMemoResourcesRequest(): ListMemoResourcesRequest {
function createBaseListMemoAttachmentsRequest(): ListMemoAttachmentsRequest {
return { name: "" };
}
export const ListMemoResourcesRequest: MessageFns<ListMemoResourcesRequest> = {
encode(message: ListMemoResourcesRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
export const ListMemoAttachmentsRequest: MessageFns<ListMemoAttachmentsRequest> = {
encode(message: ListMemoAttachmentsRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.name !== "") {
writer.uint32(10).string(message.name);
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): ListMemoResourcesRequest {
decode(input: BinaryReader | Uint8Array, length?: number): ListMemoAttachmentsRequest {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseListMemoResourcesRequest();
const message = createBaseListMemoAttachmentsRequest();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
@ -1383,32 +1383,32 @@ export const ListMemoResourcesRequest: MessageFns<ListMemoResourcesRequest> = {
return message;
},
create(base?: DeepPartial<ListMemoResourcesRequest>): ListMemoResourcesRequest {
return ListMemoResourcesRequest.fromPartial(base ?? {});
create(base?: DeepPartial<ListMemoAttachmentsRequest>): ListMemoAttachmentsRequest {
return ListMemoAttachmentsRequest.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<ListMemoResourcesRequest>): ListMemoResourcesRequest {
const message = createBaseListMemoResourcesRequest();
fromPartial(object: DeepPartial<ListMemoAttachmentsRequest>): ListMemoAttachmentsRequest {
const message = createBaseListMemoAttachmentsRequest();
message.name = object.name ?? "";
return message;
},
};
function createBaseListMemoResourcesResponse(): ListMemoResourcesResponse {
return { resources: [] };
function createBaseListMemoAttachmentsResponse(): ListMemoAttachmentsResponse {
return { attachments: [] };
}
export const ListMemoResourcesResponse: MessageFns<ListMemoResourcesResponse> = {
encode(message: ListMemoResourcesResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
for (const v of message.resources) {
Resource.encode(v!, writer.uint32(10).fork()).join();
export const ListMemoAttachmentsResponse: MessageFns<ListMemoAttachmentsResponse> = {
encode(message: ListMemoAttachmentsResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
for (const v of message.attachments) {
Attachment.encode(v!, writer.uint32(10).fork()).join();
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): ListMemoResourcesResponse {
decode(input: BinaryReader | Uint8Array, length?: number): ListMemoAttachmentsResponse {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseListMemoResourcesResponse();
const message = createBaseListMemoAttachmentsResponse();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
@ -1417,7 +1417,7 @@ export const ListMemoResourcesResponse: MessageFns<ListMemoResourcesResponse> =
break;
}
message.resources.push(Resource.decode(reader, reader.uint32()));
message.attachments.push(Attachment.decode(reader, reader.uint32()));
continue;
}
}
@ -1429,12 +1429,12 @@ export const ListMemoResourcesResponse: MessageFns<ListMemoResourcesResponse> =
return message;
},
create(base?: DeepPartial<ListMemoResourcesResponse>): ListMemoResourcesResponse {
return ListMemoResourcesResponse.fromPartial(base ?? {});
create(base?: DeepPartial<ListMemoAttachmentsResponse>): ListMemoAttachmentsResponse {
return ListMemoAttachmentsResponse.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<ListMemoResourcesResponse>): ListMemoResourcesResponse {
const message = createBaseListMemoResourcesResponse();
message.resources = object.resources?.map((e) => Resource.fromPartial(e)) || [];
fromPartial(object: DeepPartial<ListMemoAttachmentsResponse>): ListMemoAttachmentsResponse {
const message = createBaseListMemoAttachmentsResponse();
message.attachments = object.attachments?.map((e) => Attachment.fromPartial(e)) || [];
return message;
},
};
@ -2441,10 +2441,10 @@ export const MemoServiceDefinition = {
},
},
},
/** SetMemoResources sets resources for a memo. */
setMemoResources: {
name: "SetMemoResources",
requestType: SetMemoResourcesRequest,
/** SetMemoAttachments sets attachments for a memo. */
setMemoAttachments: {
name: "SetMemoAttachments",
requestType: SetMemoAttachmentsRequest,
requestStream: false,
responseType: Empty,
responseStream: false,
@ -2453,12 +2453,12 @@ export const MemoServiceDefinition = {
8410: [new Uint8Array([4, 110, 97, 109, 101])],
578365826: [
new Uint8Array([
37,
39,
58,
1,
42,
50,
32,
34,
47,
97,
112,
@ -2482,35 +2482,37 @@ export const MemoServiceDefinition = {
42,
125,
47,
114,
101,
115,
111,
117,
114,
97,
116,
116,
97,
99,
104,
109,
101,
110,
116,
115,
]),
],
},
},
},
/** ListMemoResources lists resources for a memo. */
listMemoResources: {
name: "ListMemoResources",
requestType: ListMemoResourcesRequest,
/** ListMemoAttachments lists attachments for a memo. */
listMemoAttachments: {
name: "ListMemoAttachments",
requestType: ListMemoAttachmentsRequest,
requestStream: false,
responseType: ListMemoResourcesResponse,
responseType: ListMemoAttachmentsResponse,
responseStream: false,
options: {
_unknownFields: {
8410: [new Uint8Array([4, 110, 97, 109, 101])],
578365826: [
new Uint8Array([
34,
36,
18,
32,
34,
47,
97,
112,
@ -2534,14 +2536,16 @@ export const MemoServiceDefinition = {
42,
125,
47,
114,
101,
115,
111,
117,
114,
97,
116,
116,
97,
99,
104,
109,
101,
110,
116,
115,
]),
],

@ -0,0 +1,45 @@
import { Attachment } from "@/types/proto/api/v1/attachment_service";
export const getAttachmentUrl = (attachment: Attachment) => {
if (attachment.externalLink) {
return attachment.externalLink;
}
return `${window.location.origin}/file/${attachment.name}/${attachment.filename}`;
};
export const getAttachmentType = (attachment: Attachment) => {
if (isImage(attachment.type)) {
return "image/*";
} else if (attachment.type.startsWith("video")) {
return "video/*";
} else if (attachment.type.startsWith("audio")) {
return "audio/*";
} else if (attachment.type.startsWith("text")) {
return "text/*";
} else if (attachment.type.startsWith("application/epub+zip")) {
return "application/epub+zip";
} else if (attachment.type.startsWith("application/pdf")) {
return "application/pdf";
} else if (attachment.type.includes("word")) {
return "application/msword";
} else if (attachment.type.includes("excel")) {
return "application/msexcel";
} else if (attachment.type.startsWith("application/zip")) {
return "application/zip";
} else if (attachment.type.startsWith("application/x-java-archive")) {
return "application/x-java-archive";
} else {
return "application/octet-stream";
}
};
// isImage returns true if the given mime type is an image.
export const isImage = (t: string) => {
// Don't show PSDs as images.
return t.startsWith("image/") && !isPSD(t);
};
const isPSD = (t: string) => {
return t === "image/vnd.adobe.photoshop" || t === "image/x-photoshop" || t === "image/photoshop";
};

@ -1,45 +0,0 @@
import { Resource } from "@/types/proto/api/v1/resource_service";
export const getResourceUrl = (resource: Resource) => {
if (resource.externalLink) {
return resource.externalLink;
}
return `${window.location.origin}/file/${resource.name}/${resource.filename}`;
};
export const getResourceType = (resource: Resource) => {
if (isImage(resource.type)) {
return "image/*";
} else if (resource.type.startsWith("video")) {
return "video/*";
} else if (resource.type.startsWith("audio")) {
return "audio/*";
} else if (resource.type.startsWith("text")) {
return "text/*";
} else if (resource.type.startsWith("application/epub+zip")) {
return "application/epub+zip";
} else if (resource.type.startsWith("application/pdf")) {
return "application/pdf";
} else if (resource.type.includes("word")) {
return "application/msword";
} else if (resource.type.includes("excel")) {
return "application/msexcel";
} else if (resource.type.startsWith("application/zip")) {
return "application/zip";
} else if (resource.type.startsWith("application/x-java-archive")) {
return "application/x-java-archive";
} else {
return "application/octet-stream";
}
};
// isImage returns true if the given mime type is an image.
export const isImage = (t: string) => {
// Don't show PSDs as images.
return t.startsWith("image/") && !isPSD(t);
};
const isPSD = (t: string) => {
return t === "image/vnd.adobe.photoshop" || t === "image/x-photoshop" || t === "image/photoshop";
};
Loading…
Cancel
Save