chore: add batch get settings API

pull/5947/head
boojack 2 weeks ago
parent 21303e879d
commit f3f059b2f7

@ -26,6 +26,14 @@ service InstanceService {
option (google.api.method_signature) = "name";
}
// Batch gets instance settings.
rpc BatchGetInstanceSettings(BatchGetInstanceSettingsRequest) returns (BatchGetInstanceSettingsResponse) {
option (google.api.http) = {
post: "/api/v1/instance/settings:batchGet"
body: "*"
};
}
// Updates an instance setting.
rpc UpdateInstanceSetting(UpdateInstanceSettingRequest) returns (InstanceSetting) {
option (google.api.http) = {
@ -284,6 +292,22 @@ message GetInstanceSettingRequest {
];
}
// Request message for BatchGetInstanceSettings method.
message BatchGetInstanceSettingsRequest {
// The resource names of the instance settings.
// Format: instance/settings/{setting}
repeated string names = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {type: "memos.api.v1/InstanceSetting"}
];
}
// Response message for BatchGetInstanceSettings method.
message BatchGetInstanceSettingsResponse {
// The instance settings in the same order as the input names.
repeated InstanceSetting settings = 1;
}
// Request message for UpdateInstanceSetting method.
message UpdateInstanceSettingRequest {
// The instance setting resource which replaces the resource on the server.

@ -40,6 +40,9 @@ const (
// InstanceServiceGetInstanceSettingProcedure is the fully-qualified name of the InstanceService's
// GetInstanceSetting RPC.
InstanceServiceGetInstanceSettingProcedure = "/memos.api.v1.InstanceService/GetInstanceSetting"
// InstanceServiceBatchGetInstanceSettingsProcedure is the fully-qualified name of the
// InstanceService's BatchGetInstanceSettings RPC.
InstanceServiceBatchGetInstanceSettingsProcedure = "/memos.api.v1.InstanceService/BatchGetInstanceSettings"
// InstanceServiceUpdateInstanceSettingProcedure is the fully-qualified name of the
// InstanceService's UpdateInstanceSetting RPC.
InstanceServiceUpdateInstanceSettingProcedure = "/memos.api.v1.InstanceService/UpdateInstanceSetting"
@ -57,6 +60,8 @@ type InstanceServiceClient interface {
GetInstanceProfile(context.Context, *connect.Request[v1.GetInstanceProfileRequest]) (*connect.Response[v1.InstanceProfile], error)
// Gets an instance setting.
GetInstanceSetting(context.Context, *connect.Request[v1.GetInstanceSettingRequest]) (*connect.Response[v1.InstanceSetting], error)
// Batch gets instance settings.
BatchGetInstanceSettings(context.Context, *connect.Request[v1.BatchGetInstanceSettingsRequest]) (*connect.Response[v1.BatchGetInstanceSettingsResponse], error)
// Updates an instance setting.
UpdateInstanceSetting(context.Context, *connect.Request[v1.UpdateInstanceSettingRequest]) (*connect.Response[v1.InstanceSetting], error)
// Tests notification email delivery with the provided or stored SMTP settings.
@ -88,6 +93,12 @@ func NewInstanceServiceClient(httpClient connect.HTTPClient, baseURL string, opt
connect.WithSchema(instanceServiceMethods.ByName("GetInstanceSetting")),
connect.WithClientOptions(opts...),
),
batchGetInstanceSettings: connect.NewClient[v1.BatchGetInstanceSettingsRequest, v1.BatchGetInstanceSettingsResponse](
httpClient,
baseURL+InstanceServiceBatchGetInstanceSettingsProcedure,
connect.WithSchema(instanceServiceMethods.ByName("BatchGetInstanceSettings")),
connect.WithClientOptions(opts...),
),
updateInstanceSetting: connect.NewClient[v1.UpdateInstanceSettingRequest, v1.InstanceSetting](
httpClient,
baseURL+InstanceServiceUpdateInstanceSettingProcedure,
@ -113,6 +124,7 @@ func NewInstanceServiceClient(httpClient connect.HTTPClient, baseURL string, opt
type instanceServiceClient struct {
getInstanceProfile *connect.Client[v1.GetInstanceProfileRequest, v1.InstanceProfile]
getInstanceSetting *connect.Client[v1.GetInstanceSettingRequest, v1.InstanceSetting]
batchGetInstanceSettings *connect.Client[v1.BatchGetInstanceSettingsRequest, v1.BatchGetInstanceSettingsResponse]
updateInstanceSetting *connect.Client[v1.UpdateInstanceSettingRequest, v1.InstanceSetting]
testInstanceEmailSetting *connect.Client[v1.TestInstanceEmailSettingRequest, emptypb.Empty]
getInstanceStats *connect.Client[v1.GetInstanceStatsRequest, v1.InstanceStats]
@ -128,6 +140,11 @@ func (c *instanceServiceClient) GetInstanceSetting(ctx context.Context, req *con
return c.getInstanceSetting.CallUnary(ctx, req)
}
// BatchGetInstanceSettings calls memos.api.v1.InstanceService.BatchGetInstanceSettings.
func (c *instanceServiceClient) BatchGetInstanceSettings(ctx context.Context, req *connect.Request[v1.BatchGetInstanceSettingsRequest]) (*connect.Response[v1.BatchGetInstanceSettingsResponse], error) {
return c.batchGetInstanceSettings.CallUnary(ctx, req)
}
// UpdateInstanceSetting calls memos.api.v1.InstanceService.UpdateInstanceSetting.
func (c *instanceServiceClient) UpdateInstanceSetting(ctx context.Context, req *connect.Request[v1.UpdateInstanceSettingRequest]) (*connect.Response[v1.InstanceSetting], error) {
return c.updateInstanceSetting.CallUnary(ctx, req)
@ -149,6 +166,8 @@ type InstanceServiceHandler interface {
GetInstanceProfile(context.Context, *connect.Request[v1.GetInstanceProfileRequest]) (*connect.Response[v1.InstanceProfile], error)
// Gets an instance setting.
GetInstanceSetting(context.Context, *connect.Request[v1.GetInstanceSettingRequest]) (*connect.Response[v1.InstanceSetting], error)
// Batch gets instance settings.
BatchGetInstanceSettings(context.Context, *connect.Request[v1.BatchGetInstanceSettingsRequest]) (*connect.Response[v1.BatchGetInstanceSettingsResponse], error)
// Updates an instance setting.
UpdateInstanceSetting(context.Context, *connect.Request[v1.UpdateInstanceSettingRequest]) (*connect.Response[v1.InstanceSetting], error)
// Tests notification email delivery with the provided or stored SMTP settings.
@ -176,6 +195,12 @@ func NewInstanceServiceHandler(svc InstanceServiceHandler, opts ...connect.Handl
connect.WithSchema(instanceServiceMethods.ByName("GetInstanceSetting")),
connect.WithHandlerOptions(opts...),
)
instanceServiceBatchGetInstanceSettingsHandler := connect.NewUnaryHandler(
InstanceServiceBatchGetInstanceSettingsProcedure,
svc.BatchGetInstanceSettings,
connect.WithSchema(instanceServiceMethods.ByName("BatchGetInstanceSettings")),
connect.WithHandlerOptions(opts...),
)
instanceServiceUpdateInstanceSettingHandler := connect.NewUnaryHandler(
InstanceServiceUpdateInstanceSettingProcedure,
svc.UpdateInstanceSetting,
@ -200,6 +225,8 @@ func NewInstanceServiceHandler(svc InstanceServiceHandler, opts ...connect.Handl
instanceServiceGetInstanceProfileHandler.ServeHTTP(w, r)
case InstanceServiceGetInstanceSettingProcedure:
instanceServiceGetInstanceSettingHandler.ServeHTTP(w, r)
case InstanceServiceBatchGetInstanceSettingsProcedure:
instanceServiceBatchGetInstanceSettingsHandler.ServeHTTP(w, r)
case InstanceServiceUpdateInstanceSettingProcedure:
instanceServiceUpdateInstanceSettingHandler.ServeHTTP(w, r)
case InstanceServiceTestInstanceEmailSettingProcedure:
@ -223,6 +250,10 @@ func (UnimplementedInstanceServiceHandler) GetInstanceSetting(context.Context, *
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.InstanceService.GetInstanceSetting is not implemented"))
}
func (UnimplementedInstanceServiceHandler) BatchGetInstanceSettings(context.Context, *connect.Request[v1.BatchGetInstanceSettingsRequest]) (*connect.Response[v1.BatchGetInstanceSettingsResponse], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.InstanceService.BatchGetInstanceSettings is not implemented"))
}
func (UnimplementedInstanceServiceHandler) UpdateInstanceSetting(context.Context, *connect.Request[v1.UpdateInstanceSettingRequest]) (*connect.Response[v1.InstanceSetting], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.InstanceService.UpdateInstanceSetting is not implemented"))
}

@ -524,6 +524,99 @@ func (x *GetInstanceSettingRequest) GetName() string {
return ""
}
// Request message for BatchGetInstanceSettings method.
type BatchGetInstanceSettingsRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The resource names of the instance settings.
// Format: instance/settings/{setting}
Names []string `protobuf:"bytes,1,rep,name=names,proto3" json:"names,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *BatchGetInstanceSettingsRequest) Reset() {
*x = BatchGetInstanceSettingsRequest{}
mi := &file_api_v1_instance_service_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *BatchGetInstanceSettingsRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BatchGetInstanceSettingsRequest) ProtoMessage() {}
func (x *BatchGetInstanceSettingsRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_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 BatchGetInstanceSettingsRequest.ProtoReflect.Descriptor instead.
func (*BatchGetInstanceSettingsRequest) Descriptor() ([]byte, []int) {
return file_api_v1_instance_service_proto_rawDescGZIP(), []int{4}
}
func (x *BatchGetInstanceSettingsRequest) GetNames() []string {
if x != nil {
return x.Names
}
return nil
}
// Response message for BatchGetInstanceSettings method.
type BatchGetInstanceSettingsResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The instance settings in the same order as the input names.
Settings []*InstanceSetting `protobuf:"bytes,1,rep,name=settings,proto3" json:"settings,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *BatchGetInstanceSettingsResponse) Reset() {
*x = BatchGetInstanceSettingsResponse{}
mi := &file_api_v1_instance_service_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *BatchGetInstanceSettingsResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BatchGetInstanceSettingsResponse) ProtoMessage() {}
func (x *BatchGetInstanceSettingsResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_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 BatchGetInstanceSettingsResponse.ProtoReflect.Descriptor instead.
func (*BatchGetInstanceSettingsResponse) Descriptor() ([]byte, []int) {
return file_api_v1_instance_service_proto_rawDescGZIP(), []int{5}
}
func (x *BatchGetInstanceSettingsResponse) GetSettings() []*InstanceSetting {
if x != nil {
return x.Settings
}
return nil
}
// Request message for UpdateInstanceSetting method.
type UpdateInstanceSettingRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
@ -537,7 +630,7 @@ type UpdateInstanceSettingRequest struct {
func (x *UpdateInstanceSettingRequest) Reset() {
*x = UpdateInstanceSettingRequest{}
mi := &file_api_v1_instance_service_proto_msgTypes[4]
mi := &file_api_v1_instance_service_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -549,7 +642,7 @@ func (x *UpdateInstanceSettingRequest) String() string {
func (*UpdateInstanceSettingRequest) ProtoMessage() {}
func (x *UpdateInstanceSettingRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_service_proto_msgTypes[4]
mi := &file_api_v1_instance_service_proto_msgTypes[6]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -562,7 +655,7 @@ func (x *UpdateInstanceSettingRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use UpdateInstanceSettingRequest.ProtoReflect.Descriptor instead.
func (*UpdateInstanceSettingRequest) Descriptor() ([]byte, []int) {
return file_api_v1_instance_service_proto_rawDescGZIP(), []int{4}
return file_api_v1_instance_service_proto_rawDescGZIP(), []int{6}
}
func (x *UpdateInstanceSettingRequest) GetSetting() *InstanceSetting {
@ -592,7 +685,7 @@ type TestInstanceEmailSettingRequest struct {
func (x *TestInstanceEmailSettingRequest) Reset() {
*x = TestInstanceEmailSettingRequest{}
mi := &file_api_v1_instance_service_proto_msgTypes[5]
mi := &file_api_v1_instance_service_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -604,7 +697,7 @@ func (x *TestInstanceEmailSettingRequest) String() string {
func (*TestInstanceEmailSettingRequest) ProtoMessage() {}
func (x *TestInstanceEmailSettingRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_service_proto_msgTypes[5]
mi := &file_api_v1_instance_service_proto_msgTypes[7]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -617,7 +710,7 @@ func (x *TestInstanceEmailSettingRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use TestInstanceEmailSettingRequest.ProtoReflect.Descriptor instead.
func (*TestInstanceEmailSettingRequest) Descriptor() ([]byte, []int) {
return file_api_v1_instance_service_proto_rawDescGZIP(), []int{5}
return file_api_v1_instance_service_proto_rawDescGZIP(), []int{7}
}
func (x *TestInstanceEmailSettingRequest) GetEmail() *InstanceSetting_NotificationSetting_EmailSetting {
@ -643,7 +736,7 @@ type GetInstanceStatsRequest struct {
func (x *GetInstanceStatsRequest) Reset() {
*x = GetInstanceStatsRequest{}
mi := &file_api_v1_instance_service_proto_msgTypes[6]
mi := &file_api_v1_instance_service_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -655,7 +748,7 @@ func (x *GetInstanceStatsRequest) String() string {
func (*GetInstanceStatsRequest) ProtoMessage() {}
func (x *GetInstanceStatsRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_service_proto_msgTypes[6]
mi := &file_api_v1_instance_service_proto_msgTypes[8]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -668,7 +761,7 @@ func (x *GetInstanceStatsRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetInstanceStatsRequest.ProtoReflect.Descriptor instead.
func (*GetInstanceStatsRequest) Descriptor() ([]byte, []int) {
return file_api_v1_instance_service_proto_rawDescGZIP(), []int{6}
return file_api_v1_instance_service_proto_rawDescGZIP(), []int{8}
}
// Resource usage statistics for the instance.
@ -685,7 +778,7 @@ type InstanceStats struct {
func (x *InstanceStats) Reset() {
*x = InstanceStats{}
mi := &file_api_v1_instance_service_proto_msgTypes[7]
mi := &file_api_v1_instance_service_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -697,7 +790,7 @@ func (x *InstanceStats) String() string {
func (*InstanceStats) ProtoMessage() {}
func (x *InstanceStats) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_service_proto_msgTypes[7]
mi := &file_api_v1_instance_service_proto_msgTypes[9]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -710,7 +803,7 @@ func (x *InstanceStats) ProtoReflect() protoreflect.Message {
// Deprecated: Use InstanceStats.ProtoReflect.Descriptor instead.
func (*InstanceStats) Descriptor() ([]byte, []int) {
return file_api_v1_instance_service_proto_rawDescGZIP(), []int{7}
return file_api_v1_instance_service_proto_rawDescGZIP(), []int{9}
}
func (x *InstanceStats) GetDatabase() *InstanceStats_DatabaseStats {
@ -761,7 +854,7 @@ type InstanceSetting_GeneralSetting struct {
func (x *InstanceSetting_GeneralSetting) Reset() {
*x = InstanceSetting_GeneralSetting{}
mi := &file_api_v1_instance_service_proto_msgTypes[8]
mi := &file_api_v1_instance_service_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -773,7 +866,7 @@ func (x *InstanceSetting_GeneralSetting) String() string {
func (*InstanceSetting_GeneralSetting) ProtoMessage() {}
func (x *InstanceSetting_GeneralSetting) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_service_proto_msgTypes[8]
mi := &file_api_v1_instance_service_proto_msgTypes[10]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -863,7 +956,7 @@ type InstanceSetting_StorageSetting struct {
func (x *InstanceSetting_StorageSetting) Reset() {
*x = InstanceSetting_StorageSetting{}
mi := &file_api_v1_instance_service_proto_msgTypes[9]
mi := &file_api_v1_instance_service_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -875,7 +968,7 @@ func (x *InstanceSetting_StorageSetting) String() string {
func (*InstanceSetting_StorageSetting) ProtoMessage() {}
func (x *InstanceSetting_StorageSetting) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_service_proto_msgTypes[9]
mi := &file_api_v1_instance_service_proto_msgTypes[11]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -934,7 +1027,7 @@ type InstanceSetting_MemoRelatedSetting struct {
func (x *InstanceSetting_MemoRelatedSetting) Reset() {
*x = InstanceSetting_MemoRelatedSetting{}
mi := &file_api_v1_instance_service_proto_msgTypes[10]
mi := &file_api_v1_instance_service_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -946,7 +1039,7 @@ func (x *InstanceSetting_MemoRelatedSetting) String() string {
func (*InstanceSetting_MemoRelatedSetting) ProtoMessage() {}
func (x *InstanceSetting_MemoRelatedSetting) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_service_proto_msgTypes[10]
mi := &file_api_v1_instance_service_proto_msgTypes[12]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -997,7 +1090,7 @@ type InstanceSetting_TagMetadata struct {
func (x *InstanceSetting_TagMetadata) Reset() {
*x = InstanceSetting_TagMetadata{}
mi := &file_api_v1_instance_service_proto_msgTypes[11]
mi := &file_api_v1_instance_service_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1009,7 +1102,7 @@ func (x *InstanceSetting_TagMetadata) String() string {
func (*InstanceSetting_TagMetadata) ProtoMessage() {}
func (x *InstanceSetting_TagMetadata) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_service_proto_msgTypes[11]
mi := &file_api_v1_instance_service_proto_msgTypes[13]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1053,7 +1146,7 @@ type InstanceSetting_TagsSetting struct {
func (x *InstanceSetting_TagsSetting) Reset() {
*x = InstanceSetting_TagsSetting{}
mi := &file_api_v1_instance_service_proto_msgTypes[12]
mi := &file_api_v1_instance_service_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1065,7 +1158,7 @@ func (x *InstanceSetting_TagsSetting) String() string {
func (*InstanceSetting_TagsSetting) ProtoMessage() {}
func (x *InstanceSetting_TagsSetting) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_service_proto_msgTypes[12]
mi := &file_api_v1_instance_service_proto_msgTypes[14]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1098,7 +1191,7 @@ type InstanceSetting_NotificationSetting struct {
func (x *InstanceSetting_NotificationSetting) Reset() {
*x = InstanceSetting_NotificationSetting{}
mi := &file_api_v1_instance_service_proto_msgTypes[13]
mi := &file_api_v1_instance_service_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1110,7 +1203,7 @@ func (x *InstanceSetting_NotificationSetting) String() string {
func (*InstanceSetting_NotificationSetting) ProtoMessage() {}
func (x *InstanceSetting_NotificationSetting) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_service_proto_msgTypes[13]
mi := &file_api_v1_instance_service_proto_msgTypes[15]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1147,7 +1240,7 @@ type InstanceSetting_AISetting struct {
func (x *InstanceSetting_AISetting) Reset() {
*x = InstanceSetting_AISetting{}
mi := &file_api_v1_instance_service_proto_msgTypes[14]
mi := &file_api_v1_instance_service_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1159,7 +1252,7 @@ func (x *InstanceSetting_AISetting) String() string {
func (*InstanceSetting_AISetting) ProtoMessage() {}
func (x *InstanceSetting_AISetting) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_service_proto_msgTypes[14]
mi := &file_api_v1_instance_service_proto_msgTypes[16]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1208,7 +1301,7 @@ type InstanceSetting_AIProviderConfig struct {
func (x *InstanceSetting_AIProviderConfig) Reset() {
*x = InstanceSetting_AIProviderConfig{}
mi := &file_api_v1_instance_service_proto_msgTypes[15]
mi := &file_api_v1_instance_service_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1220,7 +1313,7 @@ func (x *InstanceSetting_AIProviderConfig) String() string {
func (*InstanceSetting_AIProviderConfig) ProtoMessage() {}
func (x *InstanceSetting_AIProviderConfig) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_service_proto_msgTypes[15]
mi := &file_api_v1_instance_service_proto_msgTypes[17]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1306,7 +1399,7 @@ type InstanceSetting_TranscriptionConfig struct {
func (x *InstanceSetting_TranscriptionConfig) Reset() {
*x = InstanceSetting_TranscriptionConfig{}
mi := &file_api_v1_instance_service_proto_msgTypes[16]
mi := &file_api_v1_instance_service_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1318,7 +1411,7 @@ func (x *InstanceSetting_TranscriptionConfig) String() string {
func (*InstanceSetting_TranscriptionConfig) ProtoMessage() {}
func (x *InstanceSetting_TranscriptionConfig) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_service_proto_msgTypes[16]
mi := &file_api_v1_instance_service_proto_msgTypes[18]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1374,7 +1467,7 @@ type InstanceSetting_GeneralSetting_CustomProfile struct {
func (x *InstanceSetting_GeneralSetting_CustomProfile) Reset() {
*x = InstanceSetting_GeneralSetting_CustomProfile{}
mi := &file_api_v1_instance_service_proto_msgTypes[17]
mi := &file_api_v1_instance_service_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1386,7 +1479,7 @@ func (x *InstanceSetting_GeneralSetting_CustomProfile) String() string {
func (*InstanceSetting_GeneralSetting_CustomProfile) ProtoMessage() {}
func (x *InstanceSetting_GeneralSetting_CustomProfile) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_service_proto_msgTypes[17]
mi := &file_api_v1_instance_service_proto_msgTypes[19]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1439,7 +1532,7 @@ type InstanceSetting_StorageSetting_S3Config struct {
func (x *InstanceSetting_StorageSetting_S3Config) Reset() {
*x = InstanceSetting_StorageSetting_S3Config{}
mi := &file_api_v1_instance_service_proto_msgTypes[18]
mi := &file_api_v1_instance_service_proto_msgTypes[20]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1451,7 +1544,7 @@ func (x *InstanceSetting_StorageSetting_S3Config) String() string {
func (*InstanceSetting_StorageSetting_S3Config) ProtoMessage() {}
func (x *InstanceSetting_StorageSetting_S3Config) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_service_proto_msgTypes[18]
mi := &file_api_v1_instance_service_proto_msgTypes[20]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1528,7 +1621,7 @@ type InstanceSetting_NotificationSetting_EmailSetting struct {
func (x *InstanceSetting_NotificationSetting_EmailSetting) Reset() {
*x = InstanceSetting_NotificationSetting_EmailSetting{}
mi := &file_api_v1_instance_service_proto_msgTypes[20]
mi := &file_api_v1_instance_service_proto_msgTypes[22]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1540,7 +1633,7 @@ func (x *InstanceSetting_NotificationSetting_EmailSetting) String() string {
func (*InstanceSetting_NotificationSetting_EmailSetting) ProtoMessage() {}
func (x *InstanceSetting_NotificationSetting_EmailSetting) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_service_proto_msgTypes[20]
mi := &file_api_v1_instance_service_proto_msgTypes[22]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1639,7 +1732,7 @@ type InstanceStats_DatabaseStats struct {
func (x *InstanceStats_DatabaseStats) Reset() {
*x = InstanceStats_DatabaseStats{}
mi := &file_api_v1_instance_service_proto_msgTypes[21]
mi := &file_api_v1_instance_service_proto_msgTypes[23]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1651,7 +1744,7 @@ func (x *InstanceStats_DatabaseStats) String() string {
func (*InstanceStats_DatabaseStats) ProtoMessage() {}
func (x *InstanceStats_DatabaseStats) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_instance_service_proto_msgTypes[21]
mi := &file_api_v1_instance_service_proto_msgTypes[23]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1664,7 +1757,7 @@ func (x *InstanceStats_DatabaseStats) ProtoReflect() protoreflect.Message {
// Deprecated: Use InstanceStats_DatabaseStats.ProtoReflect.Descriptor instead.
func (*InstanceStats_DatabaseStats) Descriptor() ([]byte, []int) {
return file_api_v1_instance_service_proto_rawDescGZIP(), []int{7, 0}
return file_api_v1_instance_service_proto_rawDescGZIP(), []int{9, 0}
}
func (x *InstanceStats_DatabaseStats) GetDriver() string {
@ -1795,7 +1888,12 @@ const file_api_v1_instance_service_proto_rawDesc = "" +
"\x05value\"U\n" +
"\x19GetInstanceSettingRequest\x128\n" +
"\x04name\x18\x01 \x01(\tB$\xe0A\x02\xfaA\x1e\n" +
"\x1cmemos.api.v1/InstanceSettingR\x04name\"\x9e\x01\n" +
"\x1cmemos.api.v1/InstanceSettingR\x04name\"]\n" +
"\x1fBatchGetInstanceSettingsRequest\x12:\n" +
"\x05names\x18\x01 \x03(\tB$\xe0A\x02\xfaA\x1e\n" +
"\x1cmemos.api.v1/InstanceSettingR\x05names\"]\n" +
" BatchGetInstanceSettingsResponse\x129\n" +
"\bsettings\x18\x01 \x03(\v2\x1d.memos.api.v1.InstanceSettingR\bsettings\"\x9e\x01\n" +
"\x1cUpdateInstanceSettingRequest\x12<\n" +
"\asetting\x18\x01 \x01(\v2\x1d.memos.api.v1.InstanceSettingB\x03\xe0A\x02R\asetting\x12@\n" +
"\vupdate_mask\x18\x02 \x01(\v2\x1a.google.protobuf.FieldMaskB\x03\xe0A\x01R\n" +
@ -1811,10 +1909,11 @@ const file_api_v1_instance_service_proto_rawDesc = "" +
"\rDatabaseStats\x12\x16\n" +
"\x06driver\x18\x01 \x01(\tR\x06driver\x12\x1d\n" +
"\n" +
"size_bytes\x18\x02 \x01(\x03R\tsizeBytes2\xf4\x05\n" +
"size_bytes\x18\x02 \x01(\x03R\tsizeBytes2\x9f\a\n" +
"\x0fInstanceService\x12~\n" +
"\x12GetInstanceProfile\x12'.memos.api.v1.GetInstanceProfileRequest\x1a\x1d.memos.api.v1.InstanceProfile\" \x82\xd3\xe4\x93\x02\x1a\x12\x18/api/v1/instance/profile\x12\x8f\x01\n" +
"\x12GetInstanceSetting\x12'.memos.api.v1.GetInstanceSettingRequest\x1a\x1d.memos.api.v1.InstanceSetting\"1\xdaA\x04name\x82\xd3\xe4\x93\x02$\x12\"/api/v1/{name=instance/settings/*}\x12\xb5\x01\n" +
"\x12GetInstanceSetting\x12'.memos.api.v1.GetInstanceSettingRequest\x1a\x1d.memos.api.v1.InstanceSetting\"1\xdaA\x04name\x82\xd3\xe4\x93\x02$\x12\"/api/v1/{name=instance/settings/*}\x12\xa8\x01\n" +
"\x18BatchGetInstanceSettings\x12-.memos.api.v1.BatchGetInstanceSettingsRequest\x1a..memos.api.v1.BatchGetInstanceSettingsResponse\"-\x82\xd3\xe4\x93\x02':\x01*\"\"/api/v1/instance/settings:batchGet\x12\xb5\x01\n" +
"\x15UpdateInstanceSetting\x12*.memos.api.v1.UpdateInstanceSettingRequest\x1a\x1d.memos.api.v1.InstanceSetting\"Q\xdaA\x13setting,update_mask\x82\xd3\xe4\x93\x025:\asetting2*/api/v1/{setting.name=instance/settings/*}\x12\x9e\x01\n" +
"\x18TestInstanceEmailSetting\x12-.memos.api.v1.TestInstanceEmailSettingRequest\x1a\x16.google.protobuf.Empty\";\x82\xd3\xe4\x93\x025:\x01*\"0/api/v1/instance/settings/notification:testEmail\x12v\n" +
"\x10GetInstanceStats\x12%.memos.api.v1.GetInstanceStatsRequest\x1a\x1b.memos.api.v1.InstanceStats\"\x1e\x82\xd3\xe4\x93\x02\x18\x12\x16/api/v1/instance/statsB\xac\x01\n" +
@ -1833,7 +1932,7 @@ func file_api_v1_instance_service_proto_rawDescGZIP() []byte {
}
var file_api_v1_instance_service_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
var file_api_v1_instance_service_proto_msgTypes = make([]protoimpl.MessageInfo, 22)
var file_api_v1_instance_service_proto_msgTypes = make([]protoimpl.MessageInfo, 24)
var file_api_v1_instance_service_proto_goTypes = []any{
(InstanceSetting_Key)(0), // 0: memos.api.v1.InstanceSetting.Key
(InstanceSetting_AIProviderType)(0), // 1: memos.api.v1.InstanceSetting.AIProviderType
@ -1842,68 +1941,73 @@ var file_api_v1_instance_service_proto_goTypes = []any{
(*GetInstanceProfileRequest)(nil), // 4: memos.api.v1.GetInstanceProfileRequest
(*InstanceSetting)(nil), // 5: memos.api.v1.InstanceSetting
(*GetInstanceSettingRequest)(nil), // 6: memos.api.v1.GetInstanceSettingRequest
(*UpdateInstanceSettingRequest)(nil), // 7: memos.api.v1.UpdateInstanceSettingRequest
(*TestInstanceEmailSettingRequest)(nil), // 8: memos.api.v1.TestInstanceEmailSettingRequest
(*GetInstanceStatsRequest)(nil), // 9: memos.api.v1.GetInstanceStatsRequest
(*InstanceStats)(nil), // 10: memos.api.v1.InstanceStats
(*InstanceSetting_GeneralSetting)(nil), // 11: memos.api.v1.InstanceSetting.GeneralSetting
(*InstanceSetting_StorageSetting)(nil), // 12: memos.api.v1.InstanceSetting.StorageSetting
(*InstanceSetting_MemoRelatedSetting)(nil), // 13: memos.api.v1.InstanceSetting.MemoRelatedSetting
(*InstanceSetting_TagMetadata)(nil), // 14: memos.api.v1.InstanceSetting.TagMetadata
(*InstanceSetting_TagsSetting)(nil), // 15: memos.api.v1.InstanceSetting.TagsSetting
(*InstanceSetting_NotificationSetting)(nil), // 16: memos.api.v1.InstanceSetting.NotificationSetting
(*InstanceSetting_AISetting)(nil), // 17: memos.api.v1.InstanceSetting.AISetting
(*InstanceSetting_AIProviderConfig)(nil), // 18: memos.api.v1.InstanceSetting.AIProviderConfig
(*InstanceSetting_TranscriptionConfig)(nil), // 19: memos.api.v1.InstanceSetting.TranscriptionConfig
(*InstanceSetting_GeneralSetting_CustomProfile)(nil), // 20: memos.api.v1.InstanceSetting.GeneralSetting.CustomProfile
(*InstanceSetting_StorageSetting_S3Config)(nil), // 21: memos.api.v1.InstanceSetting.StorageSetting.S3Config
nil, // 22: memos.api.v1.InstanceSetting.TagsSetting.TagsEntry
(*InstanceSetting_NotificationSetting_EmailSetting)(nil), // 23: memos.api.v1.InstanceSetting.NotificationSetting.EmailSetting
(*InstanceStats_DatabaseStats)(nil), // 24: memos.api.v1.InstanceStats.DatabaseStats
(*User)(nil), // 25: memos.api.v1.User
(*fieldmaskpb.FieldMask)(nil), // 26: google.protobuf.FieldMask
(*timestamppb.Timestamp)(nil), // 27: google.protobuf.Timestamp
(*color.Color)(nil), // 28: google.type.Color
(*emptypb.Empty)(nil), // 29: google.protobuf.Empty
(*BatchGetInstanceSettingsRequest)(nil), // 7: memos.api.v1.BatchGetInstanceSettingsRequest
(*BatchGetInstanceSettingsResponse)(nil), // 8: memos.api.v1.BatchGetInstanceSettingsResponse
(*UpdateInstanceSettingRequest)(nil), // 9: memos.api.v1.UpdateInstanceSettingRequest
(*TestInstanceEmailSettingRequest)(nil), // 10: memos.api.v1.TestInstanceEmailSettingRequest
(*GetInstanceStatsRequest)(nil), // 11: memos.api.v1.GetInstanceStatsRequest
(*InstanceStats)(nil), // 12: memos.api.v1.InstanceStats
(*InstanceSetting_GeneralSetting)(nil), // 13: memos.api.v1.InstanceSetting.GeneralSetting
(*InstanceSetting_StorageSetting)(nil), // 14: memos.api.v1.InstanceSetting.StorageSetting
(*InstanceSetting_MemoRelatedSetting)(nil), // 15: memos.api.v1.InstanceSetting.MemoRelatedSetting
(*InstanceSetting_TagMetadata)(nil), // 16: memos.api.v1.InstanceSetting.TagMetadata
(*InstanceSetting_TagsSetting)(nil), // 17: memos.api.v1.InstanceSetting.TagsSetting
(*InstanceSetting_NotificationSetting)(nil), // 18: memos.api.v1.InstanceSetting.NotificationSetting
(*InstanceSetting_AISetting)(nil), // 19: memos.api.v1.InstanceSetting.AISetting
(*InstanceSetting_AIProviderConfig)(nil), // 20: memos.api.v1.InstanceSetting.AIProviderConfig
(*InstanceSetting_TranscriptionConfig)(nil), // 21: memos.api.v1.InstanceSetting.TranscriptionConfig
(*InstanceSetting_GeneralSetting_CustomProfile)(nil), // 22: memos.api.v1.InstanceSetting.GeneralSetting.CustomProfile
(*InstanceSetting_StorageSetting_S3Config)(nil), // 23: memos.api.v1.InstanceSetting.StorageSetting.S3Config
nil, // 24: memos.api.v1.InstanceSetting.TagsSetting.TagsEntry
(*InstanceSetting_NotificationSetting_EmailSetting)(nil), // 25: memos.api.v1.InstanceSetting.NotificationSetting.EmailSetting
(*InstanceStats_DatabaseStats)(nil), // 26: memos.api.v1.InstanceStats.DatabaseStats
(*User)(nil), // 27: memos.api.v1.User
(*fieldmaskpb.FieldMask)(nil), // 28: google.protobuf.FieldMask
(*timestamppb.Timestamp)(nil), // 29: google.protobuf.Timestamp
(*color.Color)(nil), // 30: google.type.Color
(*emptypb.Empty)(nil), // 31: google.protobuf.Empty
}
var file_api_v1_instance_service_proto_depIdxs = []int32{
25, // 0: memos.api.v1.InstanceProfile.admin:type_name -> memos.api.v1.User
11, // 1: memos.api.v1.InstanceSetting.general_setting:type_name -> memos.api.v1.InstanceSetting.GeneralSetting
12, // 2: memos.api.v1.InstanceSetting.storage_setting:type_name -> memos.api.v1.InstanceSetting.StorageSetting
13, // 3: memos.api.v1.InstanceSetting.memo_related_setting:type_name -> memos.api.v1.InstanceSetting.MemoRelatedSetting
15, // 4: memos.api.v1.InstanceSetting.tags_setting:type_name -> memos.api.v1.InstanceSetting.TagsSetting
16, // 5: memos.api.v1.InstanceSetting.notification_setting:type_name -> memos.api.v1.InstanceSetting.NotificationSetting
17, // 6: memos.api.v1.InstanceSetting.ai_setting:type_name -> memos.api.v1.InstanceSetting.AISetting
5, // 7: memos.api.v1.UpdateInstanceSettingRequest.setting:type_name -> memos.api.v1.InstanceSetting
26, // 8: memos.api.v1.UpdateInstanceSettingRequest.update_mask:type_name -> google.protobuf.FieldMask
23, // 9: memos.api.v1.TestInstanceEmailSettingRequest.email:type_name -> memos.api.v1.InstanceSetting.NotificationSetting.EmailSetting
24, // 10: memos.api.v1.InstanceStats.database:type_name -> memos.api.v1.InstanceStats.DatabaseStats
27, // 11: memos.api.v1.InstanceStats.generated_time:type_name -> google.protobuf.Timestamp
20, // 12: memos.api.v1.InstanceSetting.GeneralSetting.custom_profile:type_name -> memos.api.v1.InstanceSetting.GeneralSetting.CustomProfile
2, // 13: memos.api.v1.InstanceSetting.StorageSetting.storage_type:type_name -> memos.api.v1.InstanceSetting.StorageSetting.StorageType
21, // 14: memos.api.v1.InstanceSetting.StorageSetting.s3_config:type_name -> memos.api.v1.InstanceSetting.StorageSetting.S3Config
28, // 15: memos.api.v1.InstanceSetting.TagMetadata.background_color:type_name -> google.type.Color
22, // 16: memos.api.v1.InstanceSetting.TagsSetting.tags:type_name -> memos.api.v1.InstanceSetting.TagsSetting.TagsEntry
23, // 17: memos.api.v1.InstanceSetting.NotificationSetting.email:type_name -> memos.api.v1.InstanceSetting.NotificationSetting.EmailSetting
18, // 18: memos.api.v1.InstanceSetting.AISetting.providers:type_name -> memos.api.v1.InstanceSetting.AIProviderConfig
19, // 19: memos.api.v1.InstanceSetting.AISetting.transcription:type_name -> memos.api.v1.InstanceSetting.TranscriptionConfig
1, // 20: memos.api.v1.InstanceSetting.AIProviderConfig.type:type_name -> memos.api.v1.InstanceSetting.AIProviderType
14, // 21: memos.api.v1.InstanceSetting.TagsSetting.TagsEntry.value:type_name -> memos.api.v1.InstanceSetting.TagMetadata
4, // 22: memos.api.v1.InstanceService.GetInstanceProfile:input_type -> memos.api.v1.GetInstanceProfileRequest
6, // 23: memos.api.v1.InstanceService.GetInstanceSetting:input_type -> memos.api.v1.GetInstanceSettingRequest
7, // 24: memos.api.v1.InstanceService.UpdateInstanceSetting:input_type -> memos.api.v1.UpdateInstanceSettingRequest
8, // 25: memos.api.v1.InstanceService.TestInstanceEmailSetting:input_type -> memos.api.v1.TestInstanceEmailSettingRequest
9, // 26: memos.api.v1.InstanceService.GetInstanceStats:input_type -> memos.api.v1.GetInstanceStatsRequest
3, // 27: memos.api.v1.InstanceService.GetInstanceProfile:output_type -> memos.api.v1.InstanceProfile
5, // 28: memos.api.v1.InstanceService.GetInstanceSetting:output_type -> memos.api.v1.InstanceSetting
5, // 29: memos.api.v1.InstanceService.UpdateInstanceSetting:output_type -> memos.api.v1.InstanceSetting
29, // 30: memos.api.v1.InstanceService.TestInstanceEmailSetting:output_type -> google.protobuf.Empty
10, // 31: memos.api.v1.InstanceService.GetInstanceStats:output_type -> memos.api.v1.InstanceStats
27, // [27:32] is the sub-list for method output_type
22, // [22:27] is the sub-list for method input_type
22, // [22:22] is the sub-list for extension type_name
22, // [22:22] is the sub-list for extension extendee
0, // [0:22] is the sub-list for field type_name
27, // 0: memos.api.v1.InstanceProfile.admin:type_name -> memos.api.v1.User
13, // 1: memos.api.v1.InstanceSetting.general_setting:type_name -> memos.api.v1.InstanceSetting.GeneralSetting
14, // 2: memos.api.v1.InstanceSetting.storage_setting:type_name -> memos.api.v1.InstanceSetting.StorageSetting
15, // 3: memos.api.v1.InstanceSetting.memo_related_setting:type_name -> memos.api.v1.InstanceSetting.MemoRelatedSetting
17, // 4: memos.api.v1.InstanceSetting.tags_setting:type_name -> memos.api.v1.InstanceSetting.TagsSetting
18, // 5: memos.api.v1.InstanceSetting.notification_setting:type_name -> memos.api.v1.InstanceSetting.NotificationSetting
19, // 6: memos.api.v1.InstanceSetting.ai_setting:type_name -> memos.api.v1.InstanceSetting.AISetting
5, // 7: memos.api.v1.BatchGetInstanceSettingsResponse.settings:type_name -> memos.api.v1.InstanceSetting
5, // 8: memos.api.v1.UpdateInstanceSettingRequest.setting:type_name -> memos.api.v1.InstanceSetting
28, // 9: memos.api.v1.UpdateInstanceSettingRequest.update_mask:type_name -> google.protobuf.FieldMask
25, // 10: memos.api.v1.TestInstanceEmailSettingRequest.email:type_name -> memos.api.v1.InstanceSetting.NotificationSetting.EmailSetting
26, // 11: memos.api.v1.InstanceStats.database:type_name -> memos.api.v1.InstanceStats.DatabaseStats
29, // 12: memos.api.v1.InstanceStats.generated_time:type_name -> google.protobuf.Timestamp
22, // 13: memos.api.v1.InstanceSetting.GeneralSetting.custom_profile:type_name -> memos.api.v1.InstanceSetting.GeneralSetting.CustomProfile
2, // 14: memos.api.v1.InstanceSetting.StorageSetting.storage_type:type_name -> memos.api.v1.InstanceSetting.StorageSetting.StorageType
23, // 15: memos.api.v1.InstanceSetting.StorageSetting.s3_config:type_name -> memos.api.v1.InstanceSetting.StorageSetting.S3Config
30, // 16: memos.api.v1.InstanceSetting.TagMetadata.background_color:type_name -> google.type.Color
24, // 17: memos.api.v1.InstanceSetting.TagsSetting.tags:type_name -> memos.api.v1.InstanceSetting.TagsSetting.TagsEntry
25, // 18: memos.api.v1.InstanceSetting.NotificationSetting.email:type_name -> memos.api.v1.InstanceSetting.NotificationSetting.EmailSetting
20, // 19: memos.api.v1.InstanceSetting.AISetting.providers:type_name -> memos.api.v1.InstanceSetting.AIProviderConfig
21, // 20: memos.api.v1.InstanceSetting.AISetting.transcription:type_name -> memos.api.v1.InstanceSetting.TranscriptionConfig
1, // 21: memos.api.v1.InstanceSetting.AIProviderConfig.type:type_name -> memos.api.v1.InstanceSetting.AIProviderType
16, // 22: memos.api.v1.InstanceSetting.TagsSetting.TagsEntry.value:type_name -> memos.api.v1.InstanceSetting.TagMetadata
4, // 23: memos.api.v1.InstanceService.GetInstanceProfile:input_type -> memos.api.v1.GetInstanceProfileRequest
6, // 24: memos.api.v1.InstanceService.GetInstanceSetting:input_type -> memos.api.v1.GetInstanceSettingRequest
7, // 25: memos.api.v1.InstanceService.BatchGetInstanceSettings:input_type -> memos.api.v1.BatchGetInstanceSettingsRequest
9, // 26: memos.api.v1.InstanceService.UpdateInstanceSetting:input_type -> memos.api.v1.UpdateInstanceSettingRequest
10, // 27: memos.api.v1.InstanceService.TestInstanceEmailSetting:input_type -> memos.api.v1.TestInstanceEmailSettingRequest
11, // 28: memos.api.v1.InstanceService.GetInstanceStats:input_type -> memos.api.v1.GetInstanceStatsRequest
3, // 29: memos.api.v1.InstanceService.GetInstanceProfile:output_type -> memos.api.v1.InstanceProfile
5, // 30: memos.api.v1.InstanceService.GetInstanceSetting:output_type -> memos.api.v1.InstanceSetting
8, // 31: memos.api.v1.InstanceService.BatchGetInstanceSettings:output_type -> memos.api.v1.BatchGetInstanceSettingsResponse
5, // 32: memos.api.v1.InstanceService.UpdateInstanceSetting:output_type -> memos.api.v1.InstanceSetting
31, // 33: memos.api.v1.InstanceService.TestInstanceEmailSetting:output_type -> google.protobuf.Empty
12, // 34: memos.api.v1.InstanceService.GetInstanceStats:output_type -> memos.api.v1.InstanceStats
29, // [29:35] is the sub-list for method output_type
23, // [23:29] is the sub-list for method input_type
23, // [23:23] is the sub-list for extension type_name
23, // [23:23] is the sub-list for extension extendee
0, // [0:23] is the sub-list for field type_name
}
func init() { file_api_v1_instance_service_proto_init() }
@ -1926,7 +2030,7 @@ func file_api_v1_instance_service_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_v1_instance_service_proto_rawDesc), len(file_api_v1_instance_service_proto_rawDesc)),
NumEnums: 3,
NumMessages: 22,
NumMessages: 24,
NumExtensions: 0,
NumServices: 1,
},

@ -95,6 +95,33 @@ func local_request_InstanceService_GetInstanceSetting_0(ctx context.Context, mar
return msg, metadata, err
}
func request_InstanceService_BatchGetInstanceSettings_0(ctx context.Context, marshaler runtime.Marshaler, client InstanceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq BatchGetInstanceSettingsRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.BatchGetInstanceSettings(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_InstanceService_BatchGetInstanceSettings_0(ctx context.Context, marshaler runtime.Marshaler, server InstanceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq BatchGetInstanceSettingsRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.BatchGetInstanceSettings(ctx, &protoReq)
return msg, metadata, err
}
var filter_InstanceService_UpdateInstanceSetting_0 = &utilities.DoubleArray{Encoding: map[string]int{"setting": 0, "name": 1}, Base: []int{1, 2, 1, 0, 0}, Check: []int{0, 1, 2, 3, 2}}
func request_InstanceService_UpdateInstanceSetting_0(ctx context.Context, marshaler runtime.Marshaler, client InstanceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
@ -270,6 +297,26 @@ func RegisterInstanceServiceHandlerServer(ctx context.Context, mux *runtime.Serv
}
forward_InstanceService_GetInstanceSetting_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPost, pattern_InstanceService_BatchGetInstanceSettings_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.InstanceService/BatchGetInstanceSettings", runtime.WithHTTPPathPattern("/api/v1/instance/settings:batchGet"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_InstanceService_BatchGetInstanceSettings_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_InstanceService_BatchGetInstanceSettings_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPatch, pattern_InstanceService_UpdateInstanceSetting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@ -404,6 +451,23 @@ func RegisterInstanceServiceHandlerClient(ctx context.Context, mux *runtime.Serv
}
forward_InstanceService_GetInstanceSetting_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPost, pattern_InstanceService_BatchGetInstanceSettings_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.InstanceService/BatchGetInstanceSettings", runtime.WithHTTPPathPattern("/api/v1/instance/settings:batchGet"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_InstanceService_BatchGetInstanceSettings_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_InstanceService_BatchGetInstanceSettings_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPatch, pattern_InstanceService_UpdateInstanceSetting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@ -461,6 +525,7 @@ func RegisterInstanceServiceHandlerClient(ctx context.Context, mux *runtime.Serv
var (
pattern_InstanceService_GetInstanceProfile_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "instance", "profile"}, ""))
pattern_InstanceService_GetInstanceSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 3, 5, 4}, []string{"api", "v1", "instance", "settings", "name"}, ""))
pattern_InstanceService_BatchGetInstanceSettings_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "instance", "settings"}, "batchGet"))
pattern_InstanceService_UpdateInstanceSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 3, 5, 4}, []string{"api", "v1", "instance", "settings", "setting.name"}, ""))
pattern_InstanceService_TestInstanceEmailSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"api", "v1", "instance", "settings", "notification"}, "testEmail"))
pattern_InstanceService_GetInstanceStats_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "instance", "stats"}, ""))
@ -469,6 +534,7 @@ var (
var (
forward_InstanceService_GetInstanceProfile_0 = runtime.ForwardResponseMessage
forward_InstanceService_GetInstanceSetting_0 = runtime.ForwardResponseMessage
forward_InstanceService_BatchGetInstanceSettings_0 = runtime.ForwardResponseMessage
forward_InstanceService_UpdateInstanceSetting_0 = runtime.ForwardResponseMessage
forward_InstanceService_TestInstanceEmailSetting_0 = runtime.ForwardResponseMessage
forward_InstanceService_GetInstanceStats_0 = runtime.ForwardResponseMessage

@ -22,6 +22,7 @@ const _ = grpc.SupportPackageIsVersion9
const (
InstanceService_GetInstanceProfile_FullMethodName = "/memos.api.v1.InstanceService/GetInstanceProfile"
InstanceService_GetInstanceSetting_FullMethodName = "/memos.api.v1.InstanceService/GetInstanceSetting"
InstanceService_BatchGetInstanceSettings_FullMethodName = "/memos.api.v1.InstanceService/BatchGetInstanceSettings"
InstanceService_UpdateInstanceSetting_FullMethodName = "/memos.api.v1.InstanceService/UpdateInstanceSetting"
InstanceService_TestInstanceEmailSetting_FullMethodName = "/memos.api.v1.InstanceService/TestInstanceEmailSetting"
InstanceService_GetInstanceStats_FullMethodName = "/memos.api.v1.InstanceService/GetInstanceStats"
@ -35,6 +36,8 @@ type InstanceServiceClient interface {
GetInstanceProfile(ctx context.Context, in *GetInstanceProfileRequest, opts ...grpc.CallOption) (*InstanceProfile, error)
// Gets an instance setting.
GetInstanceSetting(ctx context.Context, in *GetInstanceSettingRequest, opts ...grpc.CallOption) (*InstanceSetting, error)
// Batch gets instance settings.
BatchGetInstanceSettings(ctx context.Context, in *BatchGetInstanceSettingsRequest, opts ...grpc.CallOption) (*BatchGetInstanceSettingsResponse, error)
// Updates an instance setting.
UpdateInstanceSetting(ctx context.Context, in *UpdateInstanceSettingRequest, opts ...grpc.CallOption) (*InstanceSetting, error)
// Tests notification email delivery with the provided or stored SMTP settings.
@ -71,6 +74,16 @@ func (c *instanceServiceClient) GetInstanceSetting(ctx context.Context, in *GetI
return out, nil
}
func (c *instanceServiceClient) BatchGetInstanceSettings(ctx context.Context, in *BatchGetInstanceSettingsRequest, opts ...grpc.CallOption) (*BatchGetInstanceSettingsResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(BatchGetInstanceSettingsResponse)
err := c.cc.Invoke(ctx, InstanceService_BatchGetInstanceSettings_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *instanceServiceClient) UpdateInstanceSetting(ctx context.Context, in *UpdateInstanceSettingRequest, opts ...grpc.CallOption) (*InstanceSetting, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(InstanceSetting)
@ -109,6 +122,8 @@ type InstanceServiceServer interface {
GetInstanceProfile(context.Context, *GetInstanceProfileRequest) (*InstanceProfile, error)
// Gets an instance setting.
GetInstanceSetting(context.Context, *GetInstanceSettingRequest) (*InstanceSetting, error)
// Batch gets instance settings.
BatchGetInstanceSettings(context.Context, *BatchGetInstanceSettingsRequest) (*BatchGetInstanceSettingsResponse, error)
// Updates an instance setting.
UpdateInstanceSetting(context.Context, *UpdateInstanceSettingRequest) (*InstanceSetting, error)
// Tests notification email delivery with the provided or stored SMTP settings.
@ -131,6 +146,9 @@ func (UnimplementedInstanceServiceServer) GetInstanceProfile(context.Context, *G
func (UnimplementedInstanceServiceServer) GetInstanceSetting(context.Context, *GetInstanceSettingRequest) (*InstanceSetting, error) {
return nil, status.Error(codes.Unimplemented, "method GetInstanceSetting not implemented")
}
func (UnimplementedInstanceServiceServer) BatchGetInstanceSettings(context.Context, *BatchGetInstanceSettingsRequest) (*BatchGetInstanceSettingsResponse, error) {
return nil, status.Error(codes.Unimplemented, "method BatchGetInstanceSettings not implemented")
}
func (UnimplementedInstanceServiceServer) UpdateInstanceSetting(context.Context, *UpdateInstanceSettingRequest) (*InstanceSetting, error) {
return nil, status.Error(codes.Unimplemented, "method UpdateInstanceSetting not implemented")
}
@ -197,6 +215,24 @@ func _InstanceService_GetInstanceSetting_Handler(srv interface{}, ctx context.Co
return interceptor(ctx, in, info, handler)
}
func _InstanceService_BatchGetInstanceSettings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(BatchGetInstanceSettingsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(InstanceServiceServer).BatchGetInstanceSettings(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: InstanceService_BatchGetInstanceSettings_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(InstanceServiceServer).BatchGetInstanceSettings(ctx, req.(*BatchGetInstanceSettingsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _InstanceService_UpdateInstanceSetting_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdateInstanceSettingRequest)
if err := dec(in); err != nil {
@ -266,6 +302,10 @@ var InstanceService_ServiceDesc = grpc.ServiceDesc{
MethodName: "GetInstanceSetting",
Handler: _InstanceService_GetInstanceSetting_Handler,
},
{
MethodName: "BatchGetInstanceSettings",
Handler: _InstanceService_BatchGetInstanceSettings_Handler,
},
{
MethodName: "UpdateInstanceSetting",
Handler: _InstanceService_UpdateInstanceSetting_Handler,

@ -498,6 +498,31 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/Status'
/api/v1/instance/settings:batchGet:
post:
tags:
- InstanceService
description: Batch gets instance settings.
operationId: InstanceService_BatchGetInstanceSettings
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/BatchGetInstanceSettingsRequest'
required: true
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/BatchGetInstanceSettingsResponse'
default:
description: Default error response
content:
application/json:
schema:
$ref: '#/components/schemas/Status'
/api/v1/instance/stats:
get:
tags:
@ -2326,6 +2351,28 @@ components:
type: array
items:
type: string
BatchGetInstanceSettingsRequest:
required:
- names
type: object
properties:
names:
type: array
items:
type: string
description: |-
The resource names of the instance settings.
Format: instance/settings/{setting}
description: Request message for BatchGetInstanceSettings method.
BatchGetInstanceSettingsResponse:
type: object
properties:
settings:
type: array
items:
$ref: '#/components/schemas/InstanceSetting'
description: The instance settings in the same order as the input names.
description: Response message for BatchGetInstanceSettings method.
BatchGetLinkMetadataRequest:
required:
- urls

@ -14,8 +14,9 @@ var PublicMethods = map[string]struct{}{
"/memos.api.v1.AuthService/RefreshToken": {}, // Token refresh uses cookie, must be accessible when access token expired
// Instance Service - needed before login to show instance info
"/memos.api.v1.InstanceService/GetInstanceProfile": {},
"/memos.api.v1.InstanceService/GetInstanceSetting": {},
"/memos.api.v1.InstanceService/GetInstanceProfile": {},
"/memos.api.v1.InstanceService/GetInstanceSetting": {},
"/memos.api.v1.InstanceService/BatchGetInstanceSettings": {},
// User Service - public user profiles and stats
"/memos.api.v1.UserService/CreateUser": {}, // Allow first user registration

@ -15,6 +15,7 @@ func TestPublicMethodsArePublic(t *testing.T) {
// Instance Service
"/memos.api.v1.InstanceService/GetInstanceProfile",
"/memos.api.v1.InstanceService/GetInstanceSetting",
"/memos.api.v1.InstanceService/BatchGetInstanceSettings",
// User Service
"/memos.api.v1.UserService/CreateUser",
"/memos.api.v1.UserService/GetUser",

@ -31,6 +31,14 @@ func (s *ConnectServiceHandler) GetInstanceSetting(ctx context.Context, req *con
return connect.NewResponse(resp), nil
}
func (s *ConnectServiceHandler) BatchGetInstanceSettings(ctx context.Context, req *connect.Request[v1pb.BatchGetInstanceSettingsRequest]) (*connect.Response[v1pb.BatchGetInstanceSettingsResponse], error) {
resp, err := s.APIV1Service.BatchGetInstanceSettings(ctx, req.Msg)
if err != nil {
return nil, convertGRPCError(err)
}
return connect.NewResponse(resp), nil
}
func (s *ConnectServiceHandler) UpdateInstanceSetting(ctx context.Context, req *connect.Request[v1pb.UpdateInstanceSettingRequest]) (*connect.Response[v1pb.InstanceSetting], error) {
resp, err := s.APIV1Service.UpdateInstanceSetting(ctx, req.Msg)
if err != nil {

@ -24,8 +24,27 @@ const (
maxTranscriptionConfigModelLength = 256
maxTranscriptionConfigLanguageLength = 32
maxTranscriptionConfigPromptLength = 4096
maxBatchGetInstanceSettings = 100
)
type instanceSettingCaller struct {
user *store.User
loaded bool
}
func (c *instanceSettingCaller) currentUser(ctx context.Context, service *APIV1Service) (*store.User, error) {
if c.loaded {
return c.user, nil
}
user, err := service.fetchCurrentUser(ctx)
if err != nil {
return nil, err
}
c.user = user
c.loaded = true
return c.user, nil
}
// GetInstanceProfile returns the instance profile.
func (s *APIV1Service) GetInstanceProfile(ctx context.Context, _ *v1pb.GetInstanceProfileRequest) (*v1pb.InstanceProfile, error) {
admin, err := s.GetInstanceAdmin(ctx)
@ -44,7 +63,30 @@ func (s *APIV1Service) GetInstanceProfile(ctx context.Context, _ *v1pb.GetInstan
}
func (s *APIV1Service) GetInstanceSetting(ctx context.Context, request *v1pb.GetInstanceSettingRequest) (*v1pb.InstanceSetting, error) {
instanceSettingKeyString, err := ExtractInstanceSettingKeyFromName(request.Name)
return s.getInstanceSetting(ctx, request.Name, &instanceSettingCaller{})
}
// BatchGetInstanceSettings returns multiple instance settings in request order.
func (s *APIV1Service) BatchGetInstanceSettings(ctx context.Context, request *v1pb.BatchGetInstanceSettingsRequest) (*v1pb.BatchGetInstanceSettingsResponse, error) {
if len(request.Names) > maxBatchGetInstanceSettings {
return nil, status.Errorf(codes.InvalidArgument, "too many instance setting names (max %d)", maxBatchGetInstanceSettings)
}
caller := &instanceSettingCaller{}
settings := make([]*v1pb.InstanceSetting, 0, len(request.Names))
for _, name := range request.Names {
setting, err := s.getInstanceSetting(ctx, name, caller)
if err != nil {
return nil, err
}
settings = append(settings, setting)
}
return &v1pb.BatchGetInstanceSettingsResponse{Settings: settings}, nil
}
func (s *APIV1Service) getInstanceSetting(ctx context.Context, name string, caller *instanceSettingCaller) (*v1pb.InstanceSetting, error) {
instanceSettingKeyString, err := ExtractInstanceSettingKeyFromName(name)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid instance setting name: %v", err)
}
@ -86,7 +128,7 @@ func (s *APIV1Service) GetInstanceSetting(ctx context.Context, request *v1pb.Get
// Storage and notification settings contain credentials; restrict to admins only.
if instanceSetting.Key == storepb.InstanceSettingKey_STORAGE ||
instanceSetting.Key == storepb.InstanceSettingKey_NOTIFICATION {
user, err := s.fetchCurrentUser(ctx)
user, err := caller.currentUser(ctx, s)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err)
}
@ -99,7 +141,7 @@ func (s *APIV1Service) GetInstanceSetting(ctx context.Context, request *v1pb.Get
}
isAdminCaller := false
if instanceSetting.Key == storepb.InstanceSettingKey_AI {
user, err := s.fetchCurrentUser(ctx)
user, err := caller.currentUser(ctx, s)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err)
}

@ -289,6 +289,71 @@ func TestGetInstanceSetting(t *testing.T) {
})
}
func TestBatchGetInstanceSettings(t *testing.T) {
ctx := context.Background()
t.Run("BatchGetInstanceSettings - returns settings in request order", func(t *testing.T) {
ts := NewTestService(t)
defer ts.Cleanup()
resp, err := ts.Service.BatchGetInstanceSettings(ctx, &v1pb.BatchGetInstanceSettingsRequest{
Names: []string{
"instance/settings/TAGS",
"instance/settings/GENERAL",
"instance/settings/MEMO_RELATED",
},
})
require.NoError(t, err)
require.NotNil(t, resp)
require.Len(t, resp.Settings, 3)
require.Equal(t, "instance/settings/TAGS", resp.Settings[0].Name)
require.NotNil(t, resp.Settings[0].GetTagsSetting())
require.Equal(t, "instance/settings/GENERAL", resp.Settings[1].Name)
require.NotNil(t, resp.Settings[1].GetGeneralSetting())
require.Equal(t, "instance/settings/MEMO_RELATED", resp.Settings[2].Name)
require.NotNil(t, resp.Settings[2].GetMemoRelatedSetting())
})
t.Run("BatchGetInstanceSettings - admin-only setting requires admin", func(t *testing.T) {
ts := NewTestService(t)
defer ts.Cleanup()
regularUser, err := ts.CreateRegularUser(ctx, "batch-user")
require.NoError(t, err)
userCtx := ts.CreateUserContext(ctx, regularUser.ID)
_, err = ts.Service.BatchGetInstanceSettings(userCtx, &v1pb.BatchGetInstanceSettingsRequest{
Names: []string{"instance/settings/GENERAL", "instance/settings/NOTIFICATION"},
})
require.Error(t, err)
require.Contains(t, err.Error(), "permission denied")
admin, err := ts.CreateHostUser(ctx, "batch-admin")
require.NoError(t, err)
adminCtx := ts.CreateUserContext(ctx, admin.ID)
resp, err := ts.Service.BatchGetInstanceSettings(adminCtx, &v1pb.BatchGetInstanceSettingsRequest{
Names: []string{"instance/settings/GENERAL", "instance/settings/NOTIFICATION"},
})
require.NoError(t, err)
require.Len(t, resp.Settings, 2)
require.NotNil(t, resp.Settings[1].GetNotificationSetting())
})
t.Run("BatchGetInstanceSettings - invalid setting name", func(t *testing.T) {
ts := NewTestService(t)
defer ts.Cleanup()
_, err := ts.Service.BatchGetInstanceSettings(ctx, &v1pb.BatchGetInstanceSettingsRequest{
Names: []string{"instance/settings/GENERAL", "invalid/setting/name"},
})
require.Error(t, err)
require.Contains(t, err.Error(), "invalid instance setting name")
})
}
func TestTestInstanceEmailSettingAuthorization(t *testing.T) {
ctx := context.Background()
ts := NewTestService(t)

@ -47,6 +47,7 @@ interface InstanceContextValue extends InstanceState {
aiSetting: InstanceSetting_AISetting;
initialize: () => Promise<void>;
fetchSetting: (key: InstanceSetting_Key) => Promise<void>;
fetchSettings: (keys: InstanceSetting_Key[]) => Promise<void>;
updateSetting: (setting: InstanceSetting) => Promise<void>;
}
@ -117,15 +118,20 @@ export function InstanceProvider({ children }: { children: ReactNode }) {
try {
const profile = await instanceServiceClient.getInstanceProfile({});
const [generalSetting, memoRelatedSettingResponse, tagsSettingResponse] = await Promise.all([
instanceServiceClient.getInstanceSetting({ name: buildInstanceSettingName(InstanceSetting_Key.GENERAL) }),
instanceServiceClient.getInstanceSetting({ name: buildInstanceSettingName(InstanceSetting_Key.MEMO_RELATED) }),
instanceServiceClient.getInstanceSetting({ name: buildInstanceSettingName(InstanceSetting_Key.TAGS) }),
]);
const settingsResponse = await instanceServiceClient.batchGetInstanceSettings({
names: [
buildInstanceSettingName(InstanceSetting_Key.GENERAL),
buildInstanceSettingName(InstanceSetting_Key.MEMO_RELATED),
buildInstanceSettingName(InstanceSetting_Key.TAGS),
],
});
for (const setting of settingsResponse.settings) {
fetchedSettingsRef.current.add(setting.name);
}
setState({
profile,
settings: [generalSetting, memoRelatedSettingResponse, tagsSettingResponse],
settings: settingsResponse.settings,
isInitialized: true,
isLoading: false,
profileLoaded: true,
@ -140,6 +146,31 @@ export function InstanceProvider({ children }: { children: ReactNode }) {
}
}, []);
const fetchSettings = useCallback(async (keys: InstanceSetting_Key[]) => {
const names = keys.map(buildInstanceSettingName).filter((name) => !fetchedSettingsRef.current.has(name));
if (names.length === 0) {
return;
}
for (const name of names) {
fetchedSettingsRef.current.add(name);
}
try {
const response = await instanceServiceClient.batchGetInstanceSettings({ names });
const fetchedNames = new Set(response.settings.map((setting) => setting.name));
setState((prev) => ({
...prev,
settings: [...prev.settings.filter((setting) => !fetchedNames.has(setting.name)), ...response.settings],
}));
} catch (error) {
for (const name of names) {
fetchedSettingsRef.current.delete(name);
}
throw error;
}
}, []);
const fetchSetting = useCallback(async (key: InstanceSetting_Key) => {
const name = buildInstanceSettingName(key);
if (fetchedSettingsRef.current.has(name)) {
@ -178,6 +209,7 @@ export function InstanceProvider({ children }: { children: ReactNode }) {
aiSetting,
initialize,
fetchSetting,
fetchSettings,
updateSetting,
}),
[
@ -190,6 +222,7 @@ export function InstanceProvider({ children }: { children: ReactNode }) {
aiSetting,
initialize,
fetchSetting,
fetchSettings,
updateSetting,
],
);

@ -8,6 +8,7 @@ export const instanceKeys = {
profile: () => [...instanceKeys.all, "profile"] as const,
settings: () => [...instanceKeys.all, "settings"] as const,
setting: (key: InstanceSetting_Key) => [...instanceKeys.settings(), key] as const,
settingsBatch: (keys: InstanceSetting_Key[]) => [...instanceKeys.settings(), "batch", ...keys] as const,
stats: () => [...instanceKeys.all, "stats"] as const,
};
@ -52,6 +53,20 @@ export function useInstanceSetting(key: InstanceSetting_Key) {
});
}
// Hook to fetch multiple instance settings
export function useInstanceSettings(keys: InstanceSetting_Key[]) {
return useQuery({
queryKey: instanceKeys.settingsBatch(keys),
queryFn: async () => {
const response = await instanceServiceClient.batchGetInstanceSettings({
names: keys.map(buildInstanceSettingName),
});
return response.settings;
},
staleTime: 1000 * 60 * 5, // 5 minutes
});
}
// Hook to update instance setting
export function useUpdateInstanceSetting() {
const queryClient = useQueryClient();

@ -25,7 +25,7 @@ const Setting = () => {
const sm = useMediaQuery("sm");
const location = useLocation();
const user = useCurrentUser();
const { profile, fetchSetting } = useInstance();
const { profile, fetchSettings } = useInstance();
const [selectedSection, setSelectedSection] = useState<SettingSectionKey>(DEFAULT_SETTING_SECTION);
const isHost = user?.role === User_Role.ADMIN;
const commitUrl = isCommitSha(profile.commit) ? `${GITHUB_COMMIT_URL_PREFIX}${profile.commit}` : "";
@ -52,10 +52,8 @@ const Setting = () => {
return;
}
const preloadSettingKeys = new Set(sectionGroups.admin.flatMap((section) => section.preloadSettingKeys ?? []));
for (const key of preloadSettingKeys) {
fetchSetting(key);
}
}, [fetchSetting, isHost, sectionGroups.admin]);
void fetchSettings([...preloadSettingKeys]);
}, [fetchSettings, isHost, sectionGroups.admin]);
const handleSectionSelectorItemClick = (section: SettingSectionKey) => {
window.location.hash = section;

File diff suppressed because one or more lines are too long

@ -4,6 +4,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
// Mock dependencies BEFORE importing the hook under test.
vi.mock("@/hooks/useUserQueries", () => ({
useAllUserStats: vi.fn(),
useUserStats: vi.fn(),
}));
vi.mock("@/hooks/useMemoQueries", () => ({
@ -22,7 +23,7 @@ vi.mock("@/contexts/ViewContext", async () => {
};
});
import { useUserStats } from "@/hooks/useUserQueries";
import { useAllUserStats, useUserStats } from "@/hooks/useUserQueries";
import { useFilteredMemoStats } from "@/hooks/useFilteredMemoStats";
const wrapper = ({ children }: { children: ReactNode }) => children as never;
@ -34,6 +35,10 @@ const ts = (year: number, month: number, day: number) => ({
describe("useFilteredMemoStats", () => {
beforeEach(() => {
vi.mocked(useAllUserStats).mockReturnValue({
data: [],
isLoading: false,
} as ReturnType<typeof useAllUserStats>);
vi.mocked(useUserStats).mockReturnValue({
data: {
memoCreatedTimestamps: [ts(2026, 5, 1), ts(2026, 5, 1), ts(2026, 5, 2)],

Loading…
Cancel
Save