mirror of
https://github.com/usememos/memos.git
synced 2025-09-09 15:24:55 +08:00
fix: get user by username
This commit is contained in:
parent
fa2fa8a5d7
commit
506b477d50
15 changed files with 515 additions and 1239 deletions
|
@ -36,6 +36,11 @@ var MemoFilterCELAttributes = []cel.EnvOption{
|
|||
),
|
||||
}
|
||||
|
||||
// UserFilterCELAttributes are the CEL attributes for user.
|
||||
var UserFilterCELAttributes = []cel.EnvOption{
|
||||
cel.Variable("username", cel.StringType),
|
||||
}
|
||||
|
||||
// Parse parses the filter string and returns the parsed expression.
|
||||
// The filter string should be a CEL expression.
|
||||
func Parse(filter string, opts ...cel.EnvOption) (expr *exprv1.ParsedExpr, err error) {
|
||||
|
|
|
@ -50,12 +50,6 @@ service UserService {
|
|||
option (google.api.method_signature) = "name";
|
||||
}
|
||||
|
||||
// SearchUsers searches for users based on query.
|
||||
rpc SearchUsers(SearchUsersRequest) returns (SearchUsersResponse) {
|
||||
option (google.api.http) = {get: "/api/v1/users:search"};
|
||||
option (google.api.method_signature) = "query";
|
||||
}
|
||||
|
||||
// GetUserAvatar gets the avatar of a user.
|
||||
rpc GetUserAvatar(GetUserAvatarRequest) returns (google.api.HttpBody) {
|
||||
option (google.api.http) = {get: "/api/v1/{name=users/*}/avatar"};
|
||||
|
@ -231,12 +225,8 @@ message ListUsersRequest {
|
|||
// Supported fields: username, email, role, state, create_time, update_time
|
||||
string filter = 3 [(google.api.field_behavior) = OPTIONAL];
|
||||
|
||||
// Optional. The order to sort results by.
|
||||
// Example: "create_time desc" or "username asc"
|
||||
string order_by = 4 [(google.api.field_behavior) = OPTIONAL];
|
||||
|
||||
// Optional. If true, show deleted users in the response.
|
||||
bool show_deleted = 5 [(google.api.field_behavior) = OPTIONAL];
|
||||
bool show_deleted = 4 [(google.api.field_behavior) = OPTIONAL];
|
||||
}
|
||||
|
||||
message ListUsersResponse {
|
||||
|
@ -307,28 +297,6 @@ message DeleteUserRequest {
|
|||
bool force = 2 [(google.api.field_behavior) = OPTIONAL];
|
||||
}
|
||||
|
||||
message SearchUsersRequest {
|
||||
// Required. The search query.
|
||||
string query = 1 [(google.api.field_behavior) = REQUIRED];
|
||||
|
||||
// Optional. The maximum number of users to return.
|
||||
int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];
|
||||
|
||||
// Optional. A page token for pagination.
|
||||
string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
|
||||
}
|
||||
|
||||
message SearchUsersResponse {
|
||||
// The list of users matching the search query.
|
||||
repeated User users = 1;
|
||||
|
||||
// A token for the next page of results.
|
||||
string next_page_token = 2;
|
||||
|
||||
// The total count of matching users.
|
||||
int32 total_size = 3;
|
||||
}
|
||||
|
||||
message GetUserAvatarRequest {
|
||||
// Required. The resource name of the user.
|
||||
// Format: users/{user}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -298,41 +298,6 @@ func local_request_UserService_DeleteUser_0(ctx context.Context, marshaler runti
|
|||
return msg, metadata, err
|
||||
}
|
||||
|
||||
var filter_UserService_SearchUsers_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
|
||||
func request_UserService_SearchUsers_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq SearchUsersRequest
|
||||
metadata runtime.ServerMetadata
|
||||
)
|
||||
if req.Body != nil {
|
||||
_, _ = 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_UserService_SearchUsers_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
msg, err := client.SearchUsers(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
func local_request_UserService_SearchUsers_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq SearchUsersRequest
|
||||
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_UserService_SearchUsers_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
msg, err := server.SearchUsers(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
func request_UserService_GetUserAvatar_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq GetUserAvatarRequest
|
||||
|
@ -1144,26 +1109,6 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
|
|||
}
|
||||
forward_UserService_DeleteUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodGet, pattern_UserService_SearchUsers_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.UserService/SearchUsers", runtime.WithHTTPPathPattern("/api/v1/users:search"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_UserService_SearchUsers_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_UserService_SearchUsers_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodGet, pattern_UserService_GetUserAvatar_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
|
@ -1589,23 +1534,6 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
|
|||
}
|
||||
forward_UserService_DeleteUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodGet, pattern_UserService_SearchUsers_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.UserService/SearchUsers", runtime.WithHTTPPathPattern("/api/v1/users:search"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_UserService_SearchUsers_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
forward_UserService_SearchUsers_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodGet, pattern_UserService_GetUserAvatar_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
|
@ -1870,7 +1798,6 @@ var (
|
|||
pattern_UserService_CreateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, ""))
|
||||
pattern_UserService_UpdateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "user.name"}, ""))
|
||||
pattern_UserService_DeleteUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "name"}, ""))
|
||||
pattern_UserService_SearchUsers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, "search"))
|
||||
pattern_UserService_GetUserAvatar_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "name", "avatar"}, ""))
|
||||
pattern_UserService_ListAllUserStats_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, "stats"))
|
||||
pattern_UserService_GetUserStats_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "name"}, "getStats"))
|
||||
|
@ -1894,7 +1821,6 @@ var (
|
|||
forward_UserService_CreateUser_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_UpdateUser_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_DeleteUser_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_SearchUsers_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_GetUserAvatar_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_ListAllUserStats_0 = runtime.ForwardResponseMessage
|
||||
forward_UserService_GetUserStats_0 = runtime.ForwardResponseMessage
|
||||
|
|
|
@ -26,7 +26,6 @@ const (
|
|||
UserService_CreateUser_FullMethodName = "/memos.api.v1.UserService/CreateUser"
|
||||
UserService_UpdateUser_FullMethodName = "/memos.api.v1.UserService/UpdateUser"
|
||||
UserService_DeleteUser_FullMethodName = "/memos.api.v1.UserService/DeleteUser"
|
||||
UserService_SearchUsers_FullMethodName = "/memos.api.v1.UserService/SearchUsers"
|
||||
UserService_GetUserAvatar_FullMethodName = "/memos.api.v1.UserService/GetUserAvatar"
|
||||
UserService_ListAllUserStats_FullMethodName = "/memos.api.v1.UserService/ListAllUserStats"
|
||||
UserService_GetUserStats_FullMethodName = "/memos.api.v1.UserService/GetUserStats"
|
||||
|
@ -58,8 +57,6 @@ type UserServiceClient interface {
|
|||
UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*User, error)
|
||||
// DeleteUser deletes a user.
|
||||
DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
|
||||
// SearchUsers searches for users based on query.
|
||||
SearchUsers(ctx context.Context, in *SearchUsersRequest, opts ...grpc.CallOption) (*SearchUsersResponse, error)
|
||||
// GetUserAvatar gets the avatar of a user.
|
||||
GetUserAvatar(ctx context.Context, in *GetUserAvatarRequest, opts ...grpc.CallOption) (*httpbody.HttpBody, error)
|
||||
// ListAllUserStats returns statistics for all users.
|
||||
|
@ -150,16 +147,6 @@ func (c *userServiceClient) DeleteUser(ctx context.Context, in *DeleteUserReques
|
|||
return out, nil
|
||||
}
|
||||
|
||||
func (c *userServiceClient) SearchUsers(ctx context.Context, in *SearchUsersRequest, opts ...grpc.CallOption) (*SearchUsersResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(SearchUsersResponse)
|
||||
err := c.cc.Invoke(ctx, UserService_SearchUsers_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *userServiceClient) GetUserAvatar(ctx context.Context, in *GetUserAvatarRequest, opts ...grpc.CallOption) (*httpbody.HttpBody, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(httpbody.HttpBody)
|
||||
|
@ -324,8 +311,6 @@ type UserServiceServer interface {
|
|||
UpdateUser(context.Context, *UpdateUserRequest) (*User, error)
|
||||
// DeleteUser deletes a user.
|
||||
DeleteUser(context.Context, *DeleteUserRequest) (*emptypb.Empty, error)
|
||||
// SearchUsers searches for users based on query.
|
||||
SearchUsers(context.Context, *SearchUsersRequest) (*SearchUsersResponse, error)
|
||||
// GetUserAvatar gets the avatar of a user.
|
||||
GetUserAvatar(context.Context, *GetUserAvatarRequest) (*httpbody.HttpBody, error)
|
||||
// ListAllUserStats returns statistics for all users.
|
||||
|
@ -381,9 +366,6 @@ func (UnimplementedUserServiceServer) UpdateUser(context.Context, *UpdateUserReq
|
|||
func (UnimplementedUserServiceServer) DeleteUser(context.Context, *DeleteUserRequest) (*emptypb.Empty, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DeleteUser not implemented")
|
||||
}
|
||||
func (UnimplementedUserServiceServer) SearchUsers(context.Context, *SearchUsersRequest) (*SearchUsersResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SearchUsers not implemented")
|
||||
}
|
||||
func (UnimplementedUserServiceServer) GetUserAvatar(context.Context, *GetUserAvatarRequest) (*httpbody.HttpBody, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetUserAvatar not implemented")
|
||||
}
|
||||
|
@ -540,24 +522,6 @@ func _UserService_DeleteUser_Handler(srv interface{}, ctx context.Context, dec f
|
|||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _UserService_SearchUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(SearchUsersRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(UserServiceServer).SearchUsers(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: UserService_SearchUsers_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(UserServiceServer).SearchUsers(ctx, req.(*SearchUsersRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _UserService_GetUserAvatar_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetUserAvatarRequest)
|
||||
if err := dec(in); err != nil {
|
||||
|
@ -855,10 +819,6 @@ var UserService_ServiceDesc = grpc.ServiceDesc{
|
|||
MethodName: "DeleteUser",
|
||||
Handler: _UserService_DeleteUser_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "SearchUsers",
|
||||
Handler: _UserService_SearchUsers_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetUserAvatar",
|
||||
Handler: _UserService_GetUserAvatar_Handler,
|
||||
|
|
|
@ -15,19 +15,13 @@ paths:
|
|||
parameters:
|
||||
- name: pageSize
|
||||
in: query
|
||||
description: |-
|
||||
The maximum number of activities to return.
|
||||
The service may return fewer than this value.
|
||||
If unspecified, at most 100 activities will be returned.
|
||||
The maximum value is 1000; values above 1000 will be coerced to 1000.
|
||||
description: "The maximum number of activities to return.\r\n The service may return fewer than this value.\r\n If unspecified, at most 100 activities will be returned.\r\n The maximum value is 1000; values above 1000 will be coerced to 1000."
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
- name: pageToken
|
||||
in: query
|
||||
description: |-
|
||||
A page token, received from a previous `ListActivities` call.
|
||||
Provide this to retrieve the subsequent page.
|
||||
description: "A page token, received from a previous `ListActivities` call.\r\n Provide this to retrieve the subsequent page."
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
|
@ -78,35 +72,23 @@ paths:
|
|||
parameters:
|
||||
- name: pageSize
|
||||
in: query
|
||||
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.
|
||||
description: "Optional. The maximum number of attachments to return.\r\n The service may return fewer than this value.\r\n If unspecified, at most 50 attachments will be returned.\r\n The maximum value is 1000; values above 1000 will be coerced to 1000."
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
- name: pageToken
|
||||
in: query
|
||||
description: |-
|
||||
Optional. A page token, received from a previous `ListAttachments` call.
|
||||
Provide this to retrieve the subsequent page.
|
||||
description: "Optional. A page token, received from a previous `ListAttachments` call.\r\n Provide this to retrieve the subsequent page."
|
||||
schema:
|
||||
type: string
|
||||
- name: filter
|
||||
in: query
|
||||
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
|
||||
description: "Optional. Filter to apply to the list results.\r\n Example: \"type=image/png\" or \"filename:*.jpg\"\r\n Supported operators: =, !=, <, <=, >, >=, :\r\n Supported fields: filename, type, size, create_time, memo"
|
||||
schema:
|
||||
type: string
|
||||
- name: orderBy
|
||||
in: query
|
||||
description: |-
|
||||
Optional. The order to sort results by.
|
||||
Example: "create_time desc" or "filename asc"
|
||||
description: "Optional. The order to sort results by.\r\n Example: \"create_time desc\" or \"filename asc\""
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
|
@ -130,9 +112,7 @@ paths:
|
|||
parameters:
|
||||
- name: attachmentId
|
||||
in: query
|
||||
description: |-
|
||||
Optional. The attachment ID to use for this attachment.
|
||||
If empty, a unique ID will be generated.
|
||||
description: "Optional. The attachment ID to use for this attachment.\r\n If empty, a unique ID will be generated."
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
|
@ -243,9 +223,7 @@ paths:
|
|||
post:
|
||||
tags:
|
||||
- AuthService
|
||||
description: |-
|
||||
CreateSession authenticates a user and creates a new session.
|
||||
Returns the authenticated user information upon successful authentication.
|
||||
description: "CreateSession authenticates a user and creates a new session.\r\n Returns the authenticated user information upon successful authentication."
|
||||
operationId: AuthService_CreateSession
|
||||
requestBody:
|
||||
content:
|
||||
|
@ -270,9 +248,7 @@ paths:
|
|||
get:
|
||||
tags:
|
||||
- AuthService
|
||||
description: |-
|
||||
GetCurrentSession returns the current active session information.
|
||||
This method is idempotent and safe, suitable for checking current session state.
|
||||
description: "GetCurrentSession returns the current active session information.\r\n This method is idempotent and safe, suitable for checking current session state."
|
||||
operationId: AuthService_GetCurrentSession
|
||||
responses:
|
||||
"200":
|
||||
|
@ -290,9 +266,7 @@ paths:
|
|||
delete:
|
||||
tags:
|
||||
- AuthService
|
||||
description: |-
|
||||
DeleteSession terminates the current user session.
|
||||
This is an idempotent operation that invalidates the user's authentication.
|
||||
description: "DeleteSession terminates the current user session.\r\n This is an idempotent operation that invalidates the user's authentication."
|
||||
operationId: AuthService_DeleteSession
|
||||
responses:
|
||||
"200":
|
||||
|
@ -331,9 +305,7 @@ paths:
|
|||
parameters:
|
||||
- name: identityProviderId
|
||||
in: query
|
||||
description: |-
|
||||
Optional. The ID to use for the identity provider, which will become the final component of the resource name.
|
||||
If not provided, the system will generate one.
|
||||
description: "Optional. The ID to use for the identity provider, which will become the final component of the resource name.\r\n If not provided, the system will generate one."
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
|
@ -417,9 +389,7 @@ paths:
|
|||
type: string
|
||||
- name: updateMask
|
||||
in: query
|
||||
description: |-
|
||||
Required. The update mask applies to the resource. Only the top level fields of
|
||||
IdentityProvider are supported.
|
||||
description: "Required. The update mask applies to the resource. Only the top level fields of\r\n IdentityProvider are supported."
|
||||
schema:
|
||||
type: string
|
||||
format: field-mask
|
||||
|
@ -511,9 +481,7 @@ paths:
|
|||
get:
|
||||
tags:
|
||||
- MarkdownService
|
||||
description: |-
|
||||
GetLinkMetadata returns metadata for a given link.
|
||||
This is useful for generating link previews.
|
||||
description: "GetLinkMetadata returns metadata for a given link.\r\n This is useful for generating link previews."
|
||||
operationId: MarkdownService_GetLinkMetadata
|
||||
parameters:
|
||||
- name: link
|
||||
|
@ -538,9 +506,7 @@ paths:
|
|||
post:
|
||||
tags:
|
||||
- MarkdownService
|
||||
description: |-
|
||||
ParseMarkdown parses the given markdown content and returns a list of nodes.
|
||||
This is a utility method that transforms markdown text into structured nodes.
|
||||
description: "ParseMarkdown parses the given markdown content and returns a list of nodes.\r\n This is a utility method that transforms markdown text into structured nodes."
|
||||
operationId: MarkdownService_ParseMarkdown
|
||||
requestBody:
|
||||
content:
|
||||
|
@ -565,9 +531,7 @@ paths:
|
|||
post:
|
||||
tags:
|
||||
- MarkdownService
|
||||
description: |-
|
||||
RestoreMarkdownNodes restores the given nodes to markdown content.
|
||||
This is the inverse operation of ParseMarkdown.
|
||||
description: "RestoreMarkdownNodes restores the given nodes to markdown content.\r\n This is the inverse operation of ParseMarkdown."
|
||||
operationId: MarkdownService_RestoreMarkdownNodes
|
||||
requestBody:
|
||||
content:
|
||||
|
@ -592,9 +556,7 @@ paths:
|
|||
post:
|
||||
tags:
|
||||
- MarkdownService
|
||||
description: |-
|
||||
StringifyMarkdownNodes stringify the given nodes to plain text content.
|
||||
This removes all markdown formatting and returns plain text.
|
||||
description: "StringifyMarkdownNodes stringify the given nodes to plain text content.\r\n This removes all markdown formatting and returns plain text."
|
||||
operationId: MarkdownService_StringifyMarkdownNodes
|
||||
requestBody:
|
||||
content:
|
||||
|
@ -624,26 +586,18 @@ paths:
|
|||
parameters:
|
||||
- name: pageSize
|
||||
in: query
|
||||
description: |-
|
||||
Optional. The maximum number of memos to return.
|
||||
The service may return fewer than this value.
|
||||
If unspecified, at most 50 memos will be returned.
|
||||
The maximum value is 1000; values above 1000 will be coerced to 1000.
|
||||
description: "Optional. The maximum number of memos to return.\r\n The service may return fewer than this value.\r\n If unspecified, at most 50 memos will be returned.\r\n The maximum value is 1000; values above 1000 will be coerced to 1000."
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
- name: pageToken
|
||||
in: query
|
||||
description: |-
|
||||
Optional. A page token, received from a previous `ListMemos` call.
|
||||
Provide this to retrieve the subsequent page.
|
||||
description: "Optional. A page token, received from a previous `ListMemos` call.\r\n Provide this to retrieve the subsequent page."
|
||||
schema:
|
||||
type: string
|
||||
- name: state
|
||||
in: query
|
||||
description: |-
|
||||
Optional. The state of the memos to list.
|
||||
Default to `NORMAL`. Set to `ARCHIVED` to list archived memos.
|
||||
description: "Optional. The state of the memos to list.\r\n Default to `NORMAL`. Set to `ARCHIVED` to list archived memos."
|
||||
schema:
|
||||
enum:
|
||||
- STATE_UNSPECIFIED
|
||||
|
@ -653,18 +607,12 @@ paths:
|
|||
format: enum
|
||||
- name: orderBy
|
||||
in: query
|
||||
description: |-
|
||||
Optional. The order to sort results by.
|
||||
Default to "display_time desc".
|
||||
Example: "display_time desc" or "create_time asc"
|
||||
description: "Optional. The order to sort results by.\r\n Default to \"display_time desc\".\r\n Example: \"display_time desc\" or \"create_time asc\""
|
||||
schema:
|
||||
type: string
|
||||
- name: filter
|
||||
in: query
|
||||
description: |-
|
||||
Optional. Filter to apply to the list results.
|
||||
Filter is a CEL expression to filter memos.
|
||||
Refer to `Shortcut.filter`.
|
||||
description: "Optional. Filter to apply to the list results.\r\n Filter is a CEL expression to filter memos.\r\n Refer to `Shortcut.filter`."
|
||||
schema:
|
||||
type: string
|
||||
- name: showDeleted
|
||||
|
@ -693,9 +641,7 @@ paths:
|
|||
parameters:
|
||||
- name: memoId
|
||||
in: query
|
||||
description: |-
|
||||
Optional. The memo ID to use for this memo.
|
||||
If empty, a unique ID will be generated.
|
||||
description: "Optional. The memo ID to use for this memo.\r\n If empty, a unique ID will be generated."
|
||||
schema:
|
||||
type: string
|
||||
- name: validateOnly
|
||||
|
@ -742,9 +688,7 @@ paths:
|
|||
type: string
|
||||
- name: readMask
|
||||
in: query
|
||||
description: |-
|
||||
Optional. The fields to return in the response.
|
||||
If not specified, all fields are returned.
|
||||
description: "Optional. The fields to return in the response.\r\n If not specified, all fields are returned."
|
||||
schema:
|
||||
type: string
|
||||
format: field-mask
|
||||
|
@ -1207,35 +1151,18 @@ paths:
|
|||
parameters:
|
||||
- name: pageSize
|
||||
in: query
|
||||
description: |-
|
||||
Optional. The maximum number of users to return.
|
||||
The service may return fewer than this value.
|
||||
If unspecified, at most 50 users will be returned.
|
||||
The maximum value is 1000; values above 1000 will be coerced to 1000.
|
||||
description: "Optional. The maximum number of users to return.\r\n The service may return fewer than this value.\r\n If unspecified, at most 50 users will be returned.\r\n The maximum value is 1000; values above 1000 will be coerced to 1000."
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
- name: pageToken
|
||||
in: query
|
||||
description: |-
|
||||
Optional. A page token, received from a previous `ListUsers` call.
|
||||
Provide this to retrieve the subsequent page.
|
||||
description: "Optional. A page token, received from a previous `ListUsers` call.\r\n Provide this to retrieve the subsequent page."
|
||||
schema:
|
||||
type: string
|
||||
- name: filter
|
||||
in: query
|
||||
description: |-
|
||||
Optional. Filter to apply to the list results.
|
||||
Example: "state=ACTIVE" or "role=USER" or "email:@example.com"
|
||||
Supported operators: =, !=, <, <=, >, >=, :
|
||||
Supported fields: username, email, role, state, create_time, update_time
|
||||
schema:
|
||||
type: string
|
||||
- name: orderBy
|
||||
in: query
|
||||
description: |-
|
||||
Optional. The order to sort results by.
|
||||
Example: "create_time desc" or "username asc"
|
||||
description: "Optional. Filter to apply to the list results.\r\n Example: \"state=ACTIVE\" or \"role=USER\" or \"email:@example.com\"\r\n Supported operators: =, !=, <, <=, >, >=, :\r\n Supported fields: username, email, role, state, create_time, update_time"
|
||||
schema:
|
||||
type: string
|
||||
- name: showDeleted
|
||||
|
@ -1264,10 +1191,7 @@ paths:
|
|||
parameters:
|
||||
- name: userId
|
||||
in: query
|
||||
description: |-
|
||||
Optional. The user ID to use for this user.
|
||||
If empty, a unique ID will be generated.
|
||||
Must match the pattern [a-z0-9-]+
|
||||
description: "Optional. The user ID to use for this user.\r\n If empty, a unique ID will be generated.\r\n Must match the pattern [a-z0-9-]+"
|
||||
schema:
|
||||
type: string
|
||||
- name: validateOnly
|
||||
|
@ -1277,9 +1201,7 @@ paths:
|
|||
type: boolean
|
||||
- name: requestId
|
||||
in: query
|
||||
description: |-
|
||||
Optional. An idempotency token that can be used to ensure that multiple
|
||||
requests to create a user have the same result.
|
||||
description: "Optional. An idempotency token that can be used to ensure that multiple\r\n requests to create a user have the same result."
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
|
@ -1316,9 +1238,7 @@ paths:
|
|||
type: string
|
||||
- name: readMask
|
||||
in: query
|
||||
description: |-
|
||||
Optional. The fields to return in the response.
|
||||
If not specified, all fields are returned.
|
||||
description: "Optional. The fields to return in the response.\r\n If not specified, all fields are returned."
|
||||
schema:
|
||||
type: string
|
||||
format: field-mask
|
||||
|
@ -1545,35 +1465,23 @@ paths:
|
|||
type: string
|
||||
- name: pageSize
|
||||
in: query
|
||||
description: |-
|
||||
Optional. The maximum number of inboxes to return.
|
||||
The service may return fewer than this value.
|
||||
If unspecified, at most 50 inboxes will be returned.
|
||||
The maximum value is 1000; values above 1000 will be coerced to 1000.
|
||||
description: "Optional. The maximum number of inboxes to return.\r\n The service may return fewer than this value.\r\n If unspecified, at most 50 inboxes will be returned.\r\n The maximum value is 1000; values above 1000 will be coerced to 1000."
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
- name: pageToken
|
||||
in: query
|
||||
description: |-
|
||||
Optional. A page token, received from a previous `ListInboxes` call.
|
||||
Provide this to retrieve the subsequent page.
|
||||
description: "Optional. A page token, received from a previous `ListInboxes` call.\r\n Provide this to retrieve the subsequent page."
|
||||
schema:
|
||||
type: string
|
||||
- name: filter
|
||||
in: query
|
||||
description: |-
|
||||
Optional. Filter to apply to the list results.
|
||||
Example: "status=UNREAD" or "type=MEMO_COMMENT"
|
||||
Supported operators: =, !=
|
||||
Supported fields: status, type, sender, create_time
|
||||
description: "Optional. Filter to apply to the list results.\r\n Example: \"status=UNREAD\" or \"type=MEMO_COMMENT\"\r\n Supported operators: =, !=\r\n Supported fields: status, type, sender, create_time"
|
||||
schema:
|
||||
type: string
|
||||
- name: orderBy
|
||||
in: query
|
||||
description: |-
|
||||
Optional. The order to sort results by.
|
||||
Example: "create_time desc" or "status asc"
|
||||
description: "Optional. The order to sort results by.\r\n Example: \"create_time desc\" or \"status asc\""
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
|
@ -1659,19 +1567,13 @@ paths:
|
|||
type: string
|
||||
- name: pageSize
|
||||
in: query
|
||||
description: |-
|
||||
Optional. The maximum number of settings to return.
|
||||
The service may return fewer than this value.
|
||||
If unspecified, at most 50 settings will be returned.
|
||||
The maximum value is 1000; values above 1000 will be coerced to 1000.
|
||||
description: "Optional. The maximum number of settings to return.\r\n The service may return fewer than this value.\r\n If unspecified, at most 50 settings will be returned.\r\n The maximum value is 1000; values above 1000 will be coerced to 1000."
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
- name: pageToken
|
||||
in: query
|
||||
description: |-
|
||||
Optional. A page token, received from a previous `ListUserSettings` call.
|
||||
Provide this to retrieve the subsequent page.
|
||||
description: "Optional. A page token, received from a previous `ListUserSettings` call.\r\n Provide this to retrieve the subsequent page."
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
|
@ -2082,42 +1984,6 @@ paths:
|
|||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Status'
|
||||
/api/v1/users:search:
|
||||
get:
|
||||
tags:
|
||||
- UserService
|
||||
description: SearchUsers searches for users based on query.
|
||||
operationId: UserService_SearchUsers
|
||||
parameters:
|
||||
- name: query
|
||||
in: query
|
||||
description: Required. The search query.
|
||||
schema:
|
||||
type: string
|
||||
- name: pageSize
|
||||
in: query
|
||||
description: Optional. The maximum number of users to return.
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
- name: pageToken
|
||||
in: query
|
||||
description: Optional. A page token for pagination.
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SearchUsersResponse'
|
||||
default:
|
||||
description: Default error response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Status'
|
||||
/api/v1/users:stats:
|
||||
get:
|
||||
tags:
|
||||
|
@ -2262,15 +2128,11 @@ components:
|
|||
name:
|
||||
readOnly: true
|
||||
type: string
|
||||
description: |-
|
||||
The name of the activity.
|
||||
Format: activities/{id}
|
||||
description: "The name of the activity.\r\n Format: activities/{id}"
|
||||
creator:
|
||||
readOnly: true
|
||||
type: string
|
||||
description: |-
|
||||
The name of the creator.
|
||||
Format: users/{user}
|
||||
description: "The name of the creator.\r\n Format: users/{user}"
|
||||
type:
|
||||
readOnly: true
|
||||
enum:
|
||||
|
@ -2305,14 +2167,10 @@ components:
|
|||
properties:
|
||||
memo:
|
||||
type: string
|
||||
description: |-
|
||||
The memo name of comment.
|
||||
Format: memos/{memo}
|
||||
description: "The memo name of comment.\r\n Format: memos/{memo}"
|
||||
relatedMemo:
|
||||
type: string
|
||||
description: |-
|
||||
The name of related memo.
|
||||
Format: memos/{memo}
|
||||
description: "The name of related memo.\r\n Format: memos/{memo}"
|
||||
description: ActivityMemoCommentPayload represents the payload of a memo comment activity.
|
||||
ActivityPayload:
|
||||
type: object
|
||||
|
@ -2329,9 +2187,7 @@ components:
|
|||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: |-
|
||||
The name of the attachment.
|
||||
Format: attachments/{attachment}
|
||||
description: "The name of the attachment.\r\n Format: attachments/{attachment}"
|
||||
createTime:
|
||||
readOnly: true
|
||||
type: string
|
||||
|
@ -2357,9 +2213,7 @@ components:
|
|||
description: Output only. The size of the attachment in bytes.
|
||||
memo:
|
||||
type: string
|
||||
description: |-
|
||||
Optional. The related memo. Refer to `Memo.name`.
|
||||
Format: memos/{memo}
|
||||
description: "Optional. The related memo. Refer to `Memo.name`.\r\n Format: memos/{memo}"
|
||||
AutoLinkNode:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -2421,14 +2275,10 @@ components:
|
|||
properties:
|
||||
username:
|
||||
type: string
|
||||
description: |-
|
||||
The username to sign in with.
|
||||
Required field for password-based authentication.
|
||||
description: "The username to sign in with.\r\n Required field for password-based authentication."
|
||||
password:
|
||||
type: string
|
||||
description: |-
|
||||
The password to sign in with.
|
||||
Required field for password-based authentication.
|
||||
description: "The password to sign in with.\r\n Required field for password-based authentication."
|
||||
description: Nested message for password-based authentication credentials.
|
||||
CreateSessionRequest_SSOCredentials:
|
||||
required:
|
||||
|
@ -2439,20 +2289,14 @@ components:
|
|||
properties:
|
||||
idpId:
|
||||
type: integer
|
||||
description: |-
|
||||
The ID of the SSO provider.
|
||||
Required field to identify the SSO provider.
|
||||
description: "The ID of the SSO provider.\r\n Required field to identify the SSO provider."
|
||||
format: int32
|
||||
code:
|
||||
type: string
|
||||
description: |-
|
||||
The authorization code from the SSO provider.
|
||||
Required field for completing the SSO flow.
|
||||
description: "The authorization code from the SSO provider.\r\n Required field for completing the SSO flow."
|
||||
redirectUri:
|
||||
type: string
|
||||
description: |-
|
||||
The redirect URI used in the SSO flow.
|
||||
Required field for security validation.
|
||||
description: "The redirect URI used in the SSO flow.\r\n Required field for security validation."
|
||||
description: Nested message for SSO authentication credentials.
|
||||
CreateSessionResponse:
|
||||
type: object
|
||||
|
@ -2463,9 +2307,7 @@ components:
|
|||
description: The authenticated user information.
|
||||
lastAccessedAt:
|
||||
type: string
|
||||
description: |-
|
||||
Last time the session was accessed.
|
||||
Used for sliding expiration calculation (last_accessed_time + 2 weeks).
|
||||
description: "Last time the session was accessed.\r\n Used for sliding expiration calculation (last_accessed_time + 2 weeks)."
|
||||
format: date-time
|
||||
EmbeddedContentNode:
|
||||
type: object
|
||||
|
@ -2513,9 +2355,7 @@ components:
|
|||
$ref: '#/components/schemas/User'
|
||||
lastAccessedAt:
|
||||
type: string
|
||||
description: |-
|
||||
Last time the session was accessed.
|
||||
Used for sliding expiration calculation (last_accessed_time + 2 weeks).
|
||||
description: "Last time the session was accessed.\r\n Used for sliding expiration calculation (last_accessed_time + 2 weeks)."
|
||||
format: date-time
|
||||
GoogleProtobufAny:
|
||||
type: object
|
||||
|
@ -2563,9 +2403,7 @@ components:
|
|||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: |-
|
||||
The resource name of the identity provider.
|
||||
Format: identityProviders/{idp}
|
||||
description: "The resource name of the identity provider.\r\n Format: identityProviders/{idp}"
|
||||
type:
|
||||
enum:
|
||||
- TYPE_UNSPECIFIED
|
||||
|
@ -2600,21 +2438,15 @@ components:
|
|||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: |-
|
||||
The resource name of the inbox.
|
||||
Format: inboxes/{inbox}
|
||||
description: "The resource name of the inbox.\r\n Format: inboxes/{inbox}"
|
||||
sender:
|
||||
readOnly: true
|
||||
type: string
|
||||
description: |-
|
||||
The sender of the inbox notification.
|
||||
Format: users/{user}
|
||||
description: "The sender of the inbox notification.\r\n Format: users/{user}"
|
||||
receiver:
|
||||
readOnly: true
|
||||
type: string
|
||||
description: |-
|
||||
The receiver of the inbox notification.
|
||||
Format: users/{user}
|
||||
description: "The receiver of the inbox notification.\r\n Format: users/{user}"
|
||||
status:
|
||||
enum:
|
||||
- STATUS_UNSPECIFIED
|
||||
|
@ -2684,10 +2516,7 @@ components:
|
|||
description: The activities.
|
||||
nextPageToken:
|
||||
type: string
|
||||
description: |-
|
||||
A token to retrieve the next page of results.
|
||||
Pass this value in the page_token field in the subsequent call to `ListActivities`
|
||||
method to retrieve the next page of results.
|
||||
description: "A token to retrieve the next page of results.\r\n Pass this value in the page_token field in the subsequent call to `ListActivities`\r\n method to retrieve the next page of results."
|
||||
ListAllUserStatsResponse:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -2706,9 +2535,7 @@ components:
|
|||
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.
|
||||
description: "A token that can be sent as `page_token` to retrieve the next page.\r\n If this field is omitted, there are no subsequent pages."
|
||||
totalSize:
|
||||
type: integer
|
||||
description: The total count of attachments (may be approximate).
|
||||
|
@ -2731,9 +2558,7 @@ components:
|
|||
description: The list of inboxes.
|
||||
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.
|
||||
description: "A token that can be sent as `page_token` to retrieve the next page.\r\n If this field is omitted, there are no subsequent pages."
|
||||
totalSize:
|
||||
type: integer
|
||||
description: The total count of inboxes (may be approximate).
|
||||
|
@ -2808,9 +2633,7 @@ components:
|
|||
description: The list of memos.
|
||||
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.
|
||||
description: "A token that can be sent as `page_token` to retrieve the next page.\r\n If this field is omitted, there are no subsequent pages."
|
||||
totalSize:
|
||||
type: integer
|
||||
description: The total count of memos (may be approximate).
|
||||
|
@ -2874,9 +2697,7 @@ components:
|
|||
description: The list of user settings.
|
||||
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.
|
||||
description: "A token that can be sent as `page_token` to retrieve the next page.\r\n If this field is omitted, there are no subsequent pages."
|
||||
totalSize:
|
||||
type: integer
|
||||
description: The total count of settings (may be approximate).
|
||||
|
@ -2900,9 +2721,7 @@ components:
|
|||
description: The list of users.
|
||||
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.
|
||||
description: "A token that can be sent as `page_token` to retrieve the next page.\r\n If this field is omitted, there are no subsequent pages."
|
||||
totalSize:
|
||||
type: integer
|
||||
description: The total count of users (may be approximate).
|
||||
|
@ -2940,9 +2759,7 @@ components:
|
|||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: |-
|
||||
The resource name of the memo.
|
||||
Format: memos/{memo}, memo is the user defined id or uuid.
|
||||
description: "The resource name of the memo.\r\n Format: memos/{memo}, memo is the user defined id or uuid."
|
||||
state:
|
||||
enum:
|
||||
- STATE_UNSPECIFIED
|
||||
|
@ -2954,9 +2771,7 @@ components:
|
|||
creator:
|
||||
readOnly: true
|
||||
type: string
|
||||
description: |-
|
||||
The name of the creator.
|
||||
Format: users/{user}
|
||||
description: "The name of the creator.\r\n Format: users/{user}"
|
||||
createTime:
|
||||
readOnly: true
|
||||
type: string
|
||||
|
@ -3022,9 +2837,7 @@ components:
|
|||
parent:
|
||||
readOnly: true
|
||||
type: string
|
||||
description: |-
|
||||
Output only. The name of the parent memo.
|
||||
Format: memos/{memo}
|
||||
description: "Output only. The name of the parent memo.\r\n Format: memos/{memo}"
|
||||
snippet:
|
||||
readOnly: true
|
||||
type: string
|
||||
|
@ -3062,9 +2875,7 @@ components:
|
|||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: |-
|
||||
The resource name of the memo.
|
||||
Format: memos/{memo}
|
||||
description: "The resource name of the memo.\r\n Format: memos/{memo}"
|
||||
snippet:
|
||||
readOnly: true
|
||||
type: string
|
||||
|
@ -3250,21 +3061,14 @@ components:
|
|||
name:
|
||||
readOnly: true
|
||||
type: string
|
||||
description: |-
|
||||
The resource name of the reaction.
|
||||
Format: reactions/{reaction}
|
||||
description: "The resource name of the reaction.\r\n Format: reactions/{reaction}"
|
||||
creator:
|
||||
readOnly: true
|
||||
type: string
|
||||
description: |-
|
||||
The resource name of the creator.
|
||||
Format: users/{user}
|
||||
description: "The resource name of the creator.\r\n Format: users/{user}"
|
||||
contentId:
|
||||
type: string
|
||||
description: |-
|
||||
The resource name of the content.
|
||||
For memo reactions, this should be the memo's resource name.
|
||||
Format: memos/{memo}
|
||||
description: "The resource name of the content.\r\n For memo reactions, this should be the memo's resource name.\r\n Format: memos/{memo}"
|
||||
reactionType:
|
||||
type: string
|
||||
description: "Required. The type of reaction (e.g., \"\U0001F44D\", \"❤️\", \"\U0001F604\")."
|
||||
|
@ -3291,9 +3095,7 @@ components:
|
|||
properties:
|
||||
parent:
|
||||
type: string
|
||||
description: |-
|
||||
Required. The parent, who owns the tags.
|
||||
Format: memos/{memo}. Use "memos/-" to rename all tags.
|
||||
description: "Required. The parent, who owns the tags.\r\n Format: memos/{memo}. Use \"memos/-\" to rename all tags."
|
||||
oldTag:
|
||||
type: string
|
||||
description: Required. The old tag name to rename.
|
||||
|
@ -3316,21 +3118,6 @@ components:
|
|||
markdown:
|
||||
type: string
|
||||
description: The restored markdown content.
|
||||
SearchUsersResponse:
|
||||
type: object
|
||||
properties:
|
||||
users:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/User'
|
||||
description: The list of users matching the search query.
|
||||
nextPageToken:
|
||||
type: string
|
||||
description: A token for the next page of results.
|
||||
totalSize:
|
||||
type: integer
|
||||
description: The total count of matching users.
|
||||
format: int32
|
||||
SetMemoAttachmentsRequest:
|
||||
required:
|
||||
- name
|
||||
|
@ -3339,9 +3126,7 @@ components:
|
|||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: |-
|
||||
Required. The resource name of the memo.
|
||||
Format: memos/{memo}
|
||||
description: "Required. The resource name of the memo.\r\n Format: memos/{memo}"
|
||||
attachments:
|
||||
type: array
|
||||
items:
|
||||
|
@ -3355,9 +3140,7 @@ components:
|
|||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: |-
|
||||
Required. The resource name of the memo.
|
||||
Format: memos/{memo}
|
||||
description: "Required. The resource name of the memo.\r\n Format: memos/{memo}"
|
||||
relations:
|
||||
type: array
|
||||
items:
|
||||
|
@ -3370,9 +3153,7 @@ components:
|
|||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: |-
|
||||
The resource name of the shortcut.
|
||||
Format: users/{user}/shortcuts/{shortcut}
|
||||
description: "The resource name of the shortcut.\r\n Format: users/{user}/shortcuts/{shortcut}"
|
||||
title:
|
||||
type: string
|
||||
description: The title of the shortcut.
|
||||
|
@ -3415,9 +3196,7 @@ components:
|
|||
type: string
|
||||
usePathStyle:
|
||||
type: boolean
|
||||
description: |-
|
||||
S3 configuration for cloud storage backend.
|
||||
Reference: https://developers.cloudflare.com/r2/examples/aws/aws-sdk-go/
|
||||
description: "S3 configuration for cloud storage backend.\r\n Reference: https://developers.cloudflare.com/r2/examples/aws/aws-sdk-go/"
|
||||
StrikethroughNode:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -3515,9 +3294,7 @@ components:
|
|||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: |-
|
||||
Required. The resource name of the memo.
|
||||
Format: memos/{memo}
|
||||
description: "Required. The resource name of the memo.\r\n Format: memos/{memo}"
|
||||
reaction:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Reaction'
|
||||
|
@ -3531,9 +3308,7 @@ components:
|
|||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: |-
|
||||
The resource name of the user.
|
||||
Format: users/{user}
|
||||
description: "The resource name of the user.\r\n Format: users/{user}"
|
||||
role:
|
||||
enum:
|
||||
- ROLE_UNSPECIFIED
|
||||
|
@ -3585,9 +3360,7 @@ components:
|
|||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: |-
|
||||
The resource name of the access token.
|
||||
Format: users/{user}/accessTokens/{access_token}
|
||||
description: "The resource name of the access token.\r\n Format: users/{user}/accessTokens/{access_token}"
|
||||
accessToken:
|
||||
readOnly: true
|
||||
type: string
|
||||
|
@ -3610,9 +3383,7 @@ components:
|
|||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: |-
|
||||
The resource name of the session.
|
||||
Format: users/{user}/sessions/{session}
|
||||
description: "The resource name of the session.\r\n Format: users/{user}/sessions/{session}"
|
||||
sessionId:
|
||||
readOnly: true
|
||||
type: string
|
||||
|
@ -3625,9 +3396,7 @@ components:
|
|||
lastAccessedTime:
|
||||
readOnly: true
|
||||
type: string
|
||||
description: |-
|
||||
The timestamp when the session was last accessed.
|
||||
Used for sliding expiration calculation (last_accessed_time + 2 weeks).
|
||||
description: "The timestamp when the session was last accessed.\r\n Used for sliding expiration calculation (last_accessed_time + 2 weeks)."
|
||||
format: date-time
|
||||
clientInfo:
|
||||
readOnly: true
|
||||
|
@ -3657,10 +3426,7 @@ components:
|
|||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: |-
|
||||
The name of the user setting.
|
||||
Format: users/{user}/settings/{setting}, {setting} is the key for the setting.
|
||||
For example, "users/123/settings/GENERAL" for general settings.
|
||||
description: "The name of the user setting.\r\n Format: users/{user}/settings/{setting}, {setting} is the key for the setting.\r\n For example, \"users/123/settings/GENERAL\" for general settings."
|
||||
generalSetting:
|
||||
$ref: '#/components/schemas/UserSetting_GeneralSetting'
|
||||
sessionsSetting:
|
||||
|
@ -3693,10 +3459,7 @@ components:
|
|||
description: The default visibility of the memo.
|
||||
theme:
|
||||
type: string
|
||||
description: |-
|
||||
The preferred theme of the user.
|
||||
This references a CSS file in the web/public/themes/ directory.
|
||||
If not set, the default theme will be used.
|
||||
description: "The preferred theme of the user.\r\n This references a CSS file in the web/public/themes/ directory.\r\n If not set, the default theme will be used."
|
||||
description: General user settings configuration.
|
||||
UserSetting_SessionsSetting:
|
||||
type: object
|
||||
|
@ -3721,9 +3484,7 @@ components:
|
|||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: |-
|
||||
The resource name of the user whose stats these are.
|
||||
Format: users/{user}
|
||||
description: "The resource name of the user whose stats these are.\r\n Format: users/{user}"
|
||||
memoDisplayTimestamps:
|
||||
type: array
|
||||
items:
|
||||
|
@ -3771,9 +3532,7 @@ components:
|
|||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: |-
|
||||
The name of the webhook.
|
||||
Format: users/{user}/webhooks/{webhook}
|
||||
description: "The name of the webhook.\r\n Format: users/{user}/webhooks/{webhook}"
|
||||
url:
|
||||
type: string
|
||||
description: The URL to send the webhook to.
|
||||
|
@ -3796,9 +3555,7 @@ components:
|
|||
properties:
|
||||
owner:
|
||||
type: string
|
||||
description: |-
|
||||
The name of instance owner.
|
||||
Format: users/{user}
|
||||
description: "The name of instance owner.\r\n Format: users/{user}"
|
||||
version:
|
||||
type: string
|
||||
description: Version is the current version of instance.
|
||||
|
@ -3814,9 +3571,7 @@ components:
|
|||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: |-
|
||||
The name of the workspace setting.
|
||||
Format: workspace/settings/{setting}
|
||||
description: "The name of the workspace setting.\r\n Format: workspace/settings/{setting}"
|
||||
generalSetting:
|
||||
$ref: '#/components/schemas/WorkspaceSetting_GeneralSetting'
|
||||
storageSetting:
|
||||
|
@ -3829,9 +3584,7 @@ components:
|
|||
properties:
|
||||
theme:
|
||||
type: string
|
||||
description: |-
|
||||
theme is the name of the selected theme.
|
||||
This references a CSS file in the web/public/themes/ directory.
|
||||
description: "theme is the name of the selected theme.\r\n This references a CSS file in the web/public/themes/ directory."
|
||||
disallowUserRegistration:
|
||||
type: boolean
|
||||
description: disallow_user_registration disallows user registration.
|
||||
|
@ -3850,10 +3603,7 @@ components:
|
|||
description: custom_profile is the custom profile.
|
||||
weekStartDayOffset:
|
||||
type: integer
|
||||
description: |-
|
||||
week_start_day_offset is the week start day offset from Sunday.
|
||||
0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday
|
||||
Default is Sunday.
|
||||
description: "week_start_day_offset is the week start day offset from Sunday.\r\n 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday\r\n Default is Sunday."
|
||||
format: int32
|
||||
disallowChangeUsername:
|
||||
type: boolean
|
||||
|
@ -3912,9 +3662,7 @@ components:
|
|||
format: enum
|
||||
filepathTemplate:
|
||||
type: string
|
||||
description: |-
|
||||
The template of file path.
|
||||
e.g. assets/{timestamp}_{filename}
|
||||
description: "The template of file path.\r\n e.g. assets/{timestamp}_{filename}"
|
||||
uploadSizeLimitMb:
|
||||
type: string
|
||||
description: The max upload size in megabytes.
|
||||
|
|
68
server/router/api/v1/user_filter_test.go
Normal file
68
server/router/api/v1/user_filter_test.go
Normal file
|
@ -0,0 +1,68 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/usememos/memos/plugin/filter"
|
||||
)
|
||||
|
||||
func TestUserFilterValidation(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
filter string
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
name: "valid username filter with equals",
|
||||
filter: `username == "testuser"`,
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
name: "valid username filter with contains",
|
||||
filter: `username.contains("admin")`,
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
name: "invalid filter - unknown field",
|
||||
filter: `invalid_field == "test"`,
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
name: "empty filter",
|
||||
filter: "",
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
name: "invalid syntax",
|
||||
filter: `username ==`,
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
// Test the filter parsing directly
|
||||
_, err := filter.Parse(tc.filter, filter.UserFilterCELAttributes...)
|
||||
|
||||
if tc.expectErr && err == nil {
|
||||
t.Errorf("Expected error for filter %q, but got none", tc.filter)
|
||||
}
|
||||
if !tc.expectErr && err != nil {
|
||||
t.Errorf("Expected no error for filter %q, but got: %v", tc.filter, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserFilterCELAttributes(t *testing.T) {
|
||||
// Test that our UserFilterCELAttributes contains the username variable
|
||||
expectedAttributes := map[string]bool{
|
||||
"username": true,
|
||||
}
|
||||
|
||||
// This is a basic test to ensure the attributes are defined
|
||||
// In a real test, you would create a CEL environment and verify the attributes
|
||||
for attrName := range expectedAttributes {
|
||||
t.Logf("Expected attribute %s should be available in UserFilterCELAttributes", attrName)
|
||||
}
|
||||
}
|
|
@ -25,12 +25,13 @@ import (
|
|||
|
||||
"github.com/usememos/memos/internal/base"
|
||||
"github.com/usememos/memos/internal/util"
|
||||
"github.com/usememos/memos/plugin/filter"
|
||||
v1pb "github.com/usememos/memos/proto/gen/api/v1"
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
func (s *APIV1Service) ListUsers(ctx context.Context, _ *v1pb.ListUsersRequest) (*v1pb.ListUsersResponse, error) {
|
||||
func (s *APIV1Service) ListUsers(ctx context.Context, request *v1pb.ListUsersRequest) (*v1pb.ListUsersResponse, error) {
|
||||
currentUser, err := s.GetCurrentUser(ctx)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
|
||||
|
@ -39,12 +40,21 @@ func (s *APIV1Service) ListUsers(ctx context.Context, _ *v1pb.ListUsersRequest)
|
|||
return nil, status.Errorf(codes.PermissionDenied, "permission denied")
|
||||
}
|
||||
|
||||
users, err := s.Store.ListUsers(ctx, &store.FindUser{})
|
||||
userFind := &store.FindUser{}
|
||||
|
||||
if request.Filter != "" {
|
||||
if err := s.validateUserFilter(ctx, request.Filter); err != nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "invalid filter: %v", err)
|
||||
}
|
||||
userFind.Filters = append(userFind.Filters, request.Filter)
|
||||
}
|
||||
|
||||
users, err := s.Store.ListUsers(ctx, userFind)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to list users: %v", err)
|
||||
}
|
||||
|
||||
// TODO: Implement proper filtering, ordering, and pagination
|
||||
// TODO: Implement proper ordering, and pagination
|
||||
// For now, return all users with basic structure
|
||||
response := &v1pb.ListUsersResponse{
|
||||
Users: []*v1pb.User{},
|
||||
|
@ -70,47 +80,7 @@ func (s *APIV1Service) GetUser(ctx context.Context, request *v1pb.GetUserRequest
|
|||
if user == nil {
|
||||
return nil, status.Errorf(codes.NotFound, "user not found")
|
||||
}
|
||||
userPb := convertUserFromStore(user)
|
||||
|
||||
// TODO: Implement read_mask field filtering
|
||||
// For now, return all fields
|
||||
|
||||
return userPb, nil
|
||||
}
|
||||
|
||||
func (s *APIV1Service) SearchUsers(ctx context.Context, request *v1pb.SearchUsersRequest) (*v1pb.SearchUsersResponse, error) {
|
||||
currentUser, err := s.GetCurrentUser(ctx)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
|
||||
}
|
||||
if currentUser.Role != store.RoleHost && currentUser.Role != store.RoleAdmin {
|
||||
return nil, status.Errorf(codes.PermissionDenied, "permission denied")
|
||||
}
|
||||
|
||||
// Search users by username, email, or display name
|
||||
users, err := s.Store.ListUsers(ctx, &store.FindUser{})
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to list users: %v", err)
|
||||
}
|
||||
|
||||
var filteredUsers []*store.User
|
||||
query := strings.ToLower(request.Query)
|
||||
for _, user := range users {
|
||||
if strings.Contains(strings.ToLower(user.Username), query) ||
|
||||
strings.Contains(strings.ToLower(user.Email), query) ||
|
||||
strings.Contains(strings.ToLower(user.Nickname), query) {
|
||||
filteredUsers = append(filteredUsers, user)
|
||||
}
|
||||
}
|
||||
|
||||
response := &v1pb.SearchUsersResponse{
|
||||
Users: []*v1pb.User{},
|
||||
TotalSize: int32(len(filteredUsers)),
|
||||
}
|
||||
for _, user := range filteredUsers {
|
||||
response.Users = append(response.Users, convertUserFromStore(user))
|
||||
}
|
||||
return response, nil
|
||||
return convertUserFromStore(user), nil
|
||||
}
|
||||
|
||||
func (s *APIV1Service) GetUserAvatar(ctx context.Context, request *v1pb.GetUserAvatarRequest) (*httpbody.HttpBody, error) {
|
||||
|
@ -1316,3 +1286,37 @@ func extractWebhookIDFromName(name string) string {
|
|||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// validateUserFilter validates the user filter string.
|
||||
func (s *APIV1Service) validateUserFilter(_ context.Context, filterStr string) error {
|
||||
if filterStr == "" {
|
||||
return errors.New("filter cannot be empty")
|
||||
}
|
||||
// Validate the filter.
|
||||
parsedExpr, err := filter.Parse(filterStr, filter.UserFilterCELAttributes...)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse filter")
|
||||
}
|
||||
convertCtx := filter.NewConvertContext()
|
||||
|
||||
// Determine the dialect based on the actual database driver
|
||||
var dialect filter.SQLDialect
|
||||
switch s.Profile.Driver {
|
||||
case "sqlite":
|
||||
dialect = &filter.SQLiteDialect{}
|
||||
case "mysql":
|
||||
dialect = &filter.MySQLDialect{}
|
||||
case "postgres":
|
||||
dialect = &filter.PostgreSQLDialect{}
|
||||
default:
|
||||
// Default to SQLite for unknown drivers
|
||||
dialect = &filter.SQLiteDialect{}
|
||||
}
|
||||
|
||||
converter := filter.NewCommonSQLConverter(dialect)
|
||||
err = converter.ConvertExprToSQL(convertCtx, parsedExpr.GetExpr())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to convert filter to SQL")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/usememos/memos/plugin/filter"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
|
@ -84,6 +85,26 @@ func (d *DB) UpdateUser(ctx context.Context, update *store.UpdateUser) (*store.U
|
|||
func (d *DB) ListUsers(ctx context.Context, find *store.FindUser) ([]*store.User, error) {
|
||||
where, args := []string{"1 = 1"}, []any{}
|
||||
|
||||
for _, filterStr := range find.Filters {
|
||||
// Parse filter string and return the parsed expression.
|
||||
// The filter string should be a CEL expression.
|
||||
parsedExpr, err := filter.Parse(filterStr, filter.UserFilterCELAttributes...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
convertCtx := filter.NewConvertContext()
|
||||
// ConvertExprToSQL converts the parsed expression to a SQL condition string.
|
||||
converter := filter.NewCommonSQLConverter(&filter.MySQLDialect{})
|
||||
if err := converter.ConvertExprToSQL(convertCtx, parsedExpr.GetExpr()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
condition := convertCtx.Buffer.String()
|
||||
if condition != "" {
|
||||
where = append(where, fmt.Sprintf("(%s)", condition))
|
||||
args = append(args, convertCtx.Args...)
|
||||
}
|
||||
}
|
||||
|
||||
if v := find.ID; v != nil {
|
||||
where, args = append(where, "`id` = ?"), append(args, *v)
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/usememos/memos/plugin/filter"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
|
@ -85,6 +86,26 @@ func (d *DB) UpdateUser(ctx context.Context, update *store.UpdateUser) (*store.U
|
|||
func (d *DB) ListUsers(ctx context.Context, find *store.FindUser) ([]*store.User, error) {
|
||||
where, args := []string{"1 = 1"}, []any{}
|
||||
|
||||
for _, filterStr := range find.Filters {
|
||||
// Parse filter string and return the parsed expression.
|
||||
// The filter string should be a CEL expression.
|
||||
parsedExpr, err := filter.Parse(filterStr, filter.UserFilterCELAttributes...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
convertCtx := filter.NewConvertContext()
|
||||
// ConvertExprToSQL converts the parsed expression to a SQL condition string.
|
||||
converter := filter.NewCommonSQLConverter(&filter.PostgreSQLDialect{})
|
||||
if err := converter.ConvertExprToSQL(convertCtx, parsedExpr.GetExpr()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
condition := convertCtx.Buffer.String()
|
||||
if condition != "" {
|
||||
where = append(where, fmt.Sprintf("(%s)", condition))
|
||||
args = append(args, convertCtx.Args...)
|
||||
}
|
||||
}
|
||||
|
||||
if v := find.ID; v != nil {
|
||||
where, args = append(where, "id = "+placeholder(len(args)+1)), append(args, *v)
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/usememos/memos/plugin/filter"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
|
@ -86,6 +87,26 @@ func (d *DB) UpdateUser(ctx context.Context, update *store.UpdateUser) (*store.U
|
|||
func (d *DB) ListUsers(ctx context.Context, find *store.FindUser) ([]*store.User, error) {
|
||||
where, args := []string{"1 = 1"}, []any{}
|
||||
|
||||
for _, filterStr := range find.Filters {
|
||||
// Parse filter string and return the parsed expression.
|
||||
// The filter string should be a CEL expression.
|
||||
parsedExpr, err := filter.Parse(filterStr, filter.UserFilterCELAttributes...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
convertCtx := filter.NewConvertContext()
|
||||
// ConvertExprToSQL converts the parsed expression to a SQL condition string.
|
||||
converter := filter.NewCommonSQLConverter(&filter.SQLiteDialect{})
|
||||
if err := converter.ConvertExprToSQL(convertCtx, parsedExpr.GetExpr()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
condition := convertCtx.Buffer.String()
|
||||
if condition != "" {
|
||||
where = append(where, fmt.Sprintf("(%s)", condition))
|
||||
args = append(args, convertCtx.Args...)
|
||||
}
|
||||
}
|
||||
|
||||
if v := find.ID; v != nil {
|
||||
where, args = append(where, "id = ?"), append(args, *v)
|
||||
}
|
||||
|
|
|
@ -83,6 +83,9 @@ type FindUser struct {
|
|||
Email *string
|
||||
Nickname *string
|
||||
|
||||
// Domain specific fields
|
||||
Filters []string
|
||||
|
||||
// The maximum number of users to return.
|
||||
Limit *int
|
||||
}
|
||||
|
|
|
@ -84,8 +84,8 @@ const userStore = (() => {
|
|||
}
|
||||
}
|
||||
// Use search instead of the deprecated getUserByUsername
|
||||
const { users } = await userServiceClient.searchUsers({
|
||||
query: username,
|
||||
const { users } = await userServiceClient.listUsers({
|
||||
filter: `username == "${username}"`,
|
||||
pageSize: 10,
|
||||
});
|
||||
const user = users.find((u) => u.username === username);
|
||||
|
|
|
@ -114,11 +114,6 @@ export interface ListUsersRequest {
|
|||
* Supported fields: username, email, role, state, create_time, update_time
|
||||
*/
|
||||
filter: string;
|
||||
/**
|
||||
* Optional. The order to sort results by.
|
||||
* Example: "create_time desc" or "username asc"
|
||||
*/
|
||||
orderBy: string;
|
||||
/** Optional. If true, show deleted users in the response. */
|
||||
showDeleted: boolean;
|
||||
}
|
||||
|
@ -191,24 +186,6 @@ export interface DeleteUserRequest {
|
|||
force: boolean;
|
||||
}
|
||||
|
||||
export interface SearchUsersRequest {
|
||||
/** Required. The search query. */
|
||||
query: string;
|
||||
/** Optional. The maximum number of users to return. */
|
||||
pageSize: number;
|
||||
/** Optional. A page token for pagination. */
|
||||
pageToken: string;
|
||||
}
|
||||
|
||||
export interface SearchUsersResponse {
|
||||
/** The list of users matching the search query. */
|
||||
users: User[];
|
||||
/** A token for the next page of results. */
|
||||
nextPageToken: string;
|
||||
/** The total count of matching users. */
|
||||
totalSize: number;
|
||||
}
|
||||
|
||||
export interface GetUserAvatarRequest {
|
||||
/**
|
||||
* Required. The resource name of the user.
|
||||
|
@ -780,7 +757,7 @@ export const User: MessageFns<User> = {
|
|||
};
|
||||
|
||||
function createBaseListUsersRequest(): ListUsersRequest {
|
||||
return { pageSize: 0, pageToken: "", filter: "", orderBy: "", showDeleted: false };
|
||||
return { pageSize: 0, pageToken: "", filter: "", showDeleted: false };
|
||||
}
|
||||
|
||||
export const ListUsersRequest: MessageFns<ListUsersRequest> = {
|
||||
|
@ -794,11 +771,8 @@ export const ListUsersRequest: MessageFns<ListUsersRequest> = {
|
|||
if (message.filter !== "") {
|
||||
writer.uint32(26).string(message.filter);
|
||||
}
|
||||
if (message.orderBy !== "") {
|
||||
writer.uint32(34).string(message.orderBy);
|
||||
}
|
||||
if (message.showDeleted !== false) {
|
||||
writer.uint32(40).bool(message.showDeleted);
|
||||
writer.uint32(32).bool(message.showDeleted);
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
|
@ -835,15 +809,7 @@ export const ListUsersRequest: MessageFns<ListUsersRequest> = {
|
|||
continue;
|
||||
}
|
||||
case 4: {
|
||||
if (tag !== 34) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.orderBy = reader.string();
|
||||
continue;
|
||||
}
|
||||
case 5: {
|
||||
if (tag !== 40) {
|
||||
if (tag !== 32) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -867,7 +833,6 @@ export const ListUsersRequest: MessageFns<ListUsersRequest> = {
|
|||
message.pageSize = object.pageSize ?? 0;
|
||||
message.pageToken = object.pageToken ?? "";
|
||||
message.filter = object.filter ?? "";
|
||||
message.orderBy = object.orderBy ?? "";
|
||||
message.showDeleted = object.showDeleted ?? false;
|
||||
return message;
|
||||
},
|
||||
|
@ -1211,146 +1176,6 @@ export const DeleteUserRequest: MessageFns<DeleteUserRequest> = {
|
|||
},
|
||||
};
|
||||
|
||||
function createBaseSearchUsersRequest(): SearchUsersRequest {
|
||||
return { query: "", pageSize: 0, pageToken: "" };
|
||||
}
|
||||
|
||||
export const SearchUsersRequest: MessageFns<SearchUsersRequest> = {
|
||||
encode(message: SearchUsersRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.query !== "") {
|
||||
writer.uint32(10).string(message.query);
|
||||
}
|
||||
if (message.pageSize !== 0) {
|
||||
writer.uint32(16).int32(message.pageSize);
|
||||
}
|
||||
if (message.pageToken !== "") {
|
||||
writer.uint32(26).string(message.pageToken);
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): SearchUsersRequest {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseSearchUsersRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.query = reader.string();
|
||||
continue;
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 16) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.pageSize = reader.int32();
|
||||
continue;
|
||||
}
|
||||
case 3: {
|
||||
if (tag !== 26) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.pageToken = reader.string();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skip(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
|
||||
create(base?: DeepPartial<SearchUsersRequest>): SearchUsersRequest {
|
||||
return SearchUsersRequest.fromPartial(base ?? {});
|
||||
},
|
||||
fromPartial(object: DeepPartial<SearchUsersRequest>): SearchUsersRequest {
|
||||
const message = createBaseSearchUsersRequest();
|
||||
message.query = object.query ?? "";
|
||||
message.pageSize = object.pageSize ?? 0;
|
||||
message.pageToken = object.pageToken ?? "";
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseSearchUsersResponse(): SearchUsersResponse {
|
||||
return { users: [], nextPageToken: "", totalSize: 0 };
|
||||
}
|
||||
|
||||
export const SearchUsersResponse: MessageFns<SearchUsersResponse> = {
|
||||
encode(message: SearchUsersResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
for (const v of message.users) {
|
||||
User.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): SearchUsersResponse {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseSearchUsersResponse();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.users.push(User.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;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skip(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
|
||||
create(base?: DeepPartial<SearchUsersResponse>): SearchUsersResponse {
|
||||
return SearchUsersResponse.fromPartial(base ?? {});
|
||||
},
|
||||
fromPartial(object: DeepPartial<SearchUsersResponse>): SearchUsersResponse {
|
||||
const message = createBaseSearchUsersResponse();
|
||||
message.users = object.users?.map((e) => User.fromPartial(e)) || [];
|
||||
message.nextPageToken = object.nextPageToken ?? "";
|
||||
message.totalSize = object.totalSize ?? 0;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseGetUserAvatarRequest(): GetUserAvatarRequest {
|
||||
return { name: "" };
|
||||
}
|
||||
|
@ -3586,46 +3411,6 @@ export const UserServiceDefinition = {
|
|||
},
|
||||
},
|
||||
},
|
||||
/** SearchUsers searches for users based on query. */
|
||||
searchUsers: {
|
||||
name: "SearchUsers",
|
||||
requestType: SearchUsersRequest,
|
||||
requestStream: false,
|
||||
responseType: SearchUsersResponse,
|
||||
responseStream: false,
|
||||
options: {
|
||||
_unknownFields: {
|
||||
8410: [new Uint8Array([5, 113, 117, 101, 114, 121])],
|
||||
578365826: [
|
||||
new Uint8Array([
|
||||
22,
|
||||
18,
|
||||
20,
|
||||
47,
|
||||
97,
|
||||
112,
|
||||
105,
|
||||
47,
|
||||
118,
|
||||
49,
|
||||
47,
|
||||
117,
|
||||
115,
|
||||
101,
|
||||
114,
|
||||
115,
|
||||
58,
|
||||
115,
|
||||
101,
|
||||
97,
|
||||
114,
|
||||
99,
|
||||
104,
|
||||
]),
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
/** GetUserAvatar gets the avatar of a user. */
|
||||
getUserAvatar: {
|
||||
name: "GetUserAvatar",
|
||||
|
|
|
@ -35,7 +35,7 @@ export enum Edition {
|
|||
EDITION_2024 = "EDITION_2024",
|
||||
/**
|
||||
* EDITION_1_TEST_ONLY - Placeholder editions for testing feature resolution. These should not be
|
||||
* used or relied on outside of tests.
|
||||
* used or relyed on outside of tests.
|
||||
*/
|
||||
EDITION_1_TEST_ONLY = "EDITION_1_TEST_ONLY",
|
||||
EDITION_2_TEST_ONLY = "EDITION_2_TEST_ONLY",
|
||||
|
@ -177,19 +177,11 @@ export interface FileDescriptorProto {
|
|||
* The supported values are "proto2", "proto3", and "editions".
|
||||
*
|
||||
* If `edition` is present, this value must be "editions".
|
||||
* WARNING: This field should only be used by protobuf plugins or special
|
||||
* cases like the proto compiler. Other uses are discouraged and
|
||||
* developers should rely on the protoreflect APIs for their client language.
|
||||
*/
|
||||
syntax?:
|
||||
| string
|
||||
| undefined;
|
||||
/**
|
||||
* The edition of the proto file.
|
||||
* WARNING: This field should only be used by protobuf plugins or special
|
||||
* cases like the proto compiler. Other uses are discouraged and
|
||||
* developers should rely on the protoreflect APIs for their client language.
|
||||
*/
|
||||
/** The edition of the proto file. */
|
||||
edition?: Edition | undefined;
|
||||
}
|
||||
|
||||
|
@ -836,12 +828,7 @@ export interface FileOptions {
|
|||
rubyPackage?:
|
||||
| string
|
||||
| undefined;
|
||||
/**
|
||||
* Any features defined in the specific edition.
|
||||
* WARNING: This field should only be used by protobuf plugins or special
|
||||
* cases like the proto compiler. Other uses are discouraged and
|
||||
* developers should rely on the protoreflect APIs for their client language.
|
||||
*/
|
||||
/** Any features defined in the specific edition. */
|
||||
features?:
|
||||
| FeatureSet
|
||||
| undefined;
|
||||
|
@ -979,12 +966,7 @@ export interface MessageOptions {
|
|||
deprecatedLegacyJsonFieldConflicts?:
|
||||
| boolean
|
||||
| undefined;
|
||||
/**
|
||||
* Any features defined in the specific edition.
|
||||
* WARNING: This field should only be used by protobuf plugins or special
|
||||
* cases like the proto compiler. Other uses are discouraged and
|
||||
* developers should rely on the protoreflect APIs for their client language.
|
||||
*/
|
||||
/** Any features defined in the specific edition. */
|
||||
features?:
|
||||
| FeatureSet
|
||||
| undefined;
|
||||
|
@ -994,13 +976,12 @@ export interface MessageOptions {
|
|||
|
||||
export interface FieldOptions {
|
||||
/**
|
||||
* NOTE: ctype is deprecated. Use `features.(pb.cpp).string_type` instead.
|
||||
* The ctype option instructs the C++ code generator to use a different
|
||||
* representation of the field than it normally would. See the specific
|
||||
* options below. This option is only implemented to support use of
|
||||
* [ctype=CORD] and [ctype=STRING] (the default) on non-repeated fields of
|
||||
* type "bytes" in the open source release.
|
||||
* TODO: make ctype actually deprecated.
|
||||
* type "bytes" in the open source release -- sorry, we'll try to include
|
||||
* other types in a future version!
|
||||
*/
|
||||
ctype?:
|
||||
| FieldOptions_CType
|
||||
|
@ -1089,12 +1070,7 @@ export interface FieldOptions {
|
|||
retention?: FieldOptions_OptionRetention | undefined;
|
||||
targets: FieldOptions_OptionTargetType[];
|
||||
editionDefaults: FieldOptions_EditionDefault[];
|
||||
/**
|
||||
* Any features defined in the specific edition.
|
||||
* WARNING: This field should only be used by protobuf plugins or special
|
||||
* cases like the proto compiler. Other uses are discouraged and
|
||||
* developers should rely on the protoreflect APIs for their client language.
|
||||
*/
|
||||
/** Any features defined in the specific edition. */
|
||||
features?: FeatureSet | undefined;
|
||||
featureSupport?:
|
||||
| FieldOptions_FeatureSupport
|
||||
|
@ -1193,7 +1169,11 @@ export function fieldOptions_JSTypeToNumber(object: FieldOptions_JSType): number
|
|||
}
|
||||
}
|
||||
|
||||
/** If set to RETENTION_SOURCE, the option will be omitted from the binary. */
|
||||
/**
|
||||
* If set to RETENTION_SOURCE, the option will be omitted from the binary.
|
||||
* Note: as of January 2023, support for this is in progress and does not yet
|
||||
* have an effect (b/264593489).
|
||||
*/
|
||||
export enum FieldOptions_OptionRetention {
|
||||
RETENTION_UNKNOWN = "RETENTION_UNKNOWN",
|
||||
RETENTION_RUNTIME = "RETENTION_RUNTIME",
|
||||
|
@ -1236,7 +1216,8 @@ export function fieldOptions_OptionRetentionToNumber(object: FieldOptions_Option
|
|||
/**
|
||||
* This indicates the types of entities that the field may apply to when used
|
||||
* as an option. If it is unset, then the field may be freely used as an
|
||||
* option on any kind of entity.
|
||||
* option on any kind of entity. Note: as of January 2023, support for this is
|
||||
* in progress and does not yet have an effect (b/264593489).
|
||||
*/
|
||||
export enum FieldOptions_OptionTargetType {
|
||||
TARGET_TYPE_UNKNOWN = "TARGET_TYPE_UNKNOWN",
|
||||
|
@ -1360,12 +1341,7 @@ export interface FieldOptions_FeatureSupport {
|
|||
}
|
||||
|
||||
export interface OneofOptions {
|
||||
/**
|
||||
* Any features defined in the specific edition.
|
||||
* WARNING: This field should only be used by protobuf plugins or special
|
||||
* cases like the proto compiler. Other uses are discouraged and
|
||||
* developers should rely on the protoreflect APIs for their client language.
|
||||
*/
|
||||
/** Any features defined in the specific edition. */
|
||||
features?:
|
||||
| FeatureSet
|
||||
| undefined;
|
||||
|
@ -1403,12 +1379,7 @@ export interface EnumOptions {
|
|||
deprecatedLegacyJsonFieldConflicts?:
|
||||
| boolean
|
||||
| undefined;
|
||||
/**
|
||||
* Any features defined in the specific edition.
|
||||
* WARNING: This field should only be used by protobuf plugins or special
|
||||
* cases like the proto compiler. Other uses are discouraged and
|
||||
* developers should rely on the protoreflect APIs for their client language.
|
||||
*/
|
||||
/** Any features defined in the specific edition. */
|
||||
features?:
|
||||
| FeatureSet
|
||||
| undefined;
|
||||
|
@ -1426,12 +1397,7 @@ export interface EnumValueOptions {
|
|||
deprecated?:
|
||||
| boolean
|
||||
| undefined;
|
||||
/**
|
||||
* Any features defined in the specific edition.
|
||||
* WARNING: This field should only be used by protobuf plugins or special
|
||||
* cases like the proto compiler. Other uses are discouraged and
|
||||
* developers should rely on the protoreflect APIs for their client language.
|
||||
*/
|
||||
/** Any features defined in the specific edition. */
|
||||
features?:
|
||||
| FeatureSet
|
||||
| undefined;
|
||||
|
@ -1452,12 +1418,7 @@ export interface EnumValueOptions {
|
|||
}
|
||||
|
||||
export interface ServiceOptions {
|
||||
/**
|
||||
* Any features defined in the specific edition.
|
||||
* WARNING: This field should only be used by protobuf plugins or special
|
||||
* cases like the proto compiler. Other uses are discouraged and
|
||||
* developers should rely on the protoreflect APIs for their client language.
|
||||
*/
|
||||
/** Any features defined in the specific edition. */
|
||||
features?:
|
||||
| FeatureSet
|
||||
| undefined;
|
||||
|
@ -1485,12 +1446,7 @@ export interface MethodOptions {
|
|||
idempotencyLevel?:
|
||||
| MethodOptions_IdempotencyLevel
|
||||
| undefined;
|
||||
/**
|
||||
* Any features defined in the specific edition.
|
||||
* WARNING: This field should only be used by protobuf plugins or special
|
||||
* cases like the proto compiler. Other uses are discouraged and
|
||||
* developers should rely on the protoreflect APIs for their client language.
|
||||
*/
|
||||
/** Any features defined in the specific edition. */
|
||||
features?:
|
||||
| FeatureSet
|
||||
| undefined;
|
||||
|
@ -1593,7 +1549,6 @@ export interface FeatureSet {
|
|||
utf8Validation?: FeatureSet_Utf8Validation | undefined;
|
||||
messageEncoding?: FeatureSet_MessageEncoding | undefined;
|
||||
jsonFormat?: FeatureSet_JsonFormat | undefined;
|
||||
enforceNamingStyle?: FeatureSet_EnforceNamingStyle | undefined;
|
||||
}
|
||||
|
||||
export enum FeatureSet_FieldPresence {
|
||||
|
@ -1836,45 +1791,6 @@ export function featureSet_JsonFormatToNumber(object: FeatureSet_JsonFormat): nu
|
|||
}
|
||||
}
|
||||
|
||||
export enum FeatureSet_EnforceNamingStyle {
|
||||
ENFORCE_NAMING_STYLE_UNKNOWN = "ENFORCE_NAMING_STYLE_UNKNOWN",
|
||||
STYLE2024 = "STYLE2024",
|
||||
STYLE_LEGACY = "STYLE_LEGACY",
|
||||
UNRECOGNIZED = "UNRECOGNIZED",
|
||||
}
|
||||
|
||||
export function featureSet_EnforceNamingStyleFromJSON(object: any): FeatureSet_EnforceNamingStyle {
|
||||
switch (object) {
|
||||
case 0:
|
||||
case "ENFORCE_NAMING_STYLE_UNKNOWN":
|
||||
return FeatureSet_EnforceNamingStyle.ENFORCE_NAMING_STYLE_UNKNOWN;
|
||||
case 1:
|
||||
case "STYLE2024":
|
||||
return FeatureSet_EnforceNamingStyle.STYLE2024;
|
||||
case 2:
|
||||
case "STYLE_LEGACY":
|
||||
return FeatureSet_EnforceNamingStyle.STYLE_LEGACY;
|
||||
case -1:
|
||||
case "UNRECOGNIZED":
|
||||
default:
|
||||
return FeatureSet_EnforceNamingStyle.UNRECOGNIZED;
|
||||
}
|
||||
}
|
||||
|
||||
export function featureSet_EnforceNamingStyleToNumber(object: FeatureSet_EnforceNamingStyle): number {
|
||||
switch (object) {
|
||||
case FeatureSet_EnforceNamingStyle.ENFORCE_NAMING_STYLE_UNKNOWN:
|
||||
return 0;
|
||||
case FeatureSet_EnforceNamingStyle.STYLE2024:
|
||||
return 1;
|
||||
case FeatureSet_EnforceNamingStyle.STYLE_LEGACY:
|
||||
return 2;
|
||||
case FeatureSet_EnforceNamingStyle.UNRECOGNIZED:
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A compiled specification for the defaults of a set of features. These
|
||||
* messages are generated from FeatureSet extensions and can be used to seed
|
||||
|
@ -4998,7 +4914,6 @@ function createBaseFeatureSet(): FeatureSet {
|
|||
utf8Validation: FeatureSet_Utf8Validation.UTF8_VALIDATION_UNKNOWN,
|
||||
messageEncoding: FeatureSet_MessageEncoding.MESSAGE_ENCODING_UNKNOWN,
|
||||
jsonFormat: FeatureSet_JsonFormat.JSON_FORMAT_UNKNOWN,
|
||||
enforceNamingStyle: FeatureSet_EnforceNamingStyle.ENFORCE_NAMING_STYLE_UNKNOWN,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -5033,12 +4948,6 @@ export const FeatureSet: MessageFns<FeatureSet> = {
|
|||
if (message.jsonFormat !== undefined && message.jsonFormat !== FeatureSet_JsonFormat.JSON_FORMAT_UNKNOWN) {
|
||||
writer.uint32(48).int32(featureSet_JsonFormatToNumber(message.jsonFormat));
|
||||
}
|
||||
if (
|
||||
message.enforceNamingStyle !== undefined &&
|
||||
message.enforceNamingStyle !== FeatureSet_EnforceNamingStyle.ENFORCE_NAMING_STYLE_UNKNOWN
|
||||
) {
|
||||
writer.uint32(56).int32(featureSet_EnforceNamingStyleToNumber(message.enforceNamingStyle));
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
|
||||
|
@ -5097,14 +5006,6 @@ export const FeatureSet: MessageFns<FeatureSet> = {
|
|||
message.jsonFormat = featureSet_JsonFormatFromJSON(reader.int32());
|
||||
continue;
|
||||
}
|
||||
case 7: {
|
||||
if (tag !== 56) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.enforceNamingStyle = featureSet_EnforceNamingStyleFromJSON(reader.int32());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
|
@ -5126,8 +5027,6 @@ export const FeatureSet: MessageFns<FeatureSet> = {
|
|||
message.utf8Validation = object.utf8Validation ?? FeatureSet_Utf8Validation.UTF8_VALIDATION_UNKNOWN;
|
||||
message.messageEncoding = object.messageEncoding ?? FeatureSet_MessageEncoding.MESSAGE_ENCODING_UNKNOWN;
|
||||
message.jsonFormat = object.jsonFormat ?? FeatureSet_JsonFormat.JSON_FORMAT_UNKNOWN;
|
||||
message.enforceNamingStyle = object.enforceNamingStyle ??
|
||||
FeatureSet_EnforceNamingStyle.ENFORCE_NAMING_STYLE_UNKNOWN;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue