chore: fix linter

This commit is contained in:
Johnny 2025-08-31 20:22:32 +08:00
parent 3d1c197764
commit 7cc2df9254
33 changed files with 401 additions and 352 deletions

View File

@ -12,23 +12,17 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
"github.com/usememos/memos/internal/profile" "github.com/usem fmt.Println()
fmt.Printf("Documentation: %s\n", "https://usememos.com")
fmt.Printf("Source code: %s\n", "https://github.com/usememos/memos")
fmt.Println("\nHappy note-taking!")/memos/internal/profile"
"github.com/usememos/memos/internal/version" "github.com/usememos/memos/internal/version"
"github.com/usememos/memos/server" "github.com/usememos/memos/server"
"github.com/usememos/memos/store" "github.com/usememos/memos/store"
"github.com/usememos/memos/store/db" "github.com/usememos/memos/store/db"
) )
const (
greetingBanner = `
`
)
var ( var (
rootCmd = &cobra.Command{ rootCmd = &cobra.Command{
@ -146,38 +140,37 @@ func init() {
} }
func printGreetings(profile *profile.Profile) { func printGreetings(profile *profile.Profile) {
fmt.Printf("Memos %s started successfully!\n", profile.Version)
if profile.IsDev() { if profile.IsDev() {
println("Development mode is enabled") fmt.Fprintf(os.Stderr, "Development mode is enabled\n")
println("DSN: ", profile.DSN) if profile.DSN != "" {
fmt.Fprintf(os.Stderr, "Database: %s\n", profile.DSN)
}
} }
fmt.Printf(`---
Server profile // Server information
version: %s fmt.Printf("Data directory: %s\n", profile.Data)
data: %s fmt.Printf("Database driver: %s\n", profile.Driver)
addr: %s fmt.Printf("Mode: %s\n", profile.Mode)
port: %d
unix-sock: %s // Connection information
mode: %s
driver: %s
---
`, profile.Version, profile.Data, profile.Addr, profile.Port, profile.UNIXSock, profile.Mode, profile.Driver)
print(greetingBanner)
if len(profile.UNIXSock) == 0 { if len(profile.UNIXSock) == 0 {
if len(profile.Addr) == 0 { if len(profile.Addr) == 0 {
fmt.Printf("Version %s has been started on port %d\n", profile.Version, profile.Port) fmt.Printf("Server running on port %d\n", profile.Port)
fmt.Printf("Access your memos at: http://localhost:%d\n", profile.Port)
} else { } else {
fmt.Printf("Version %s has been started on address '%s' and port %d\n", profile.Version, profile.Addr, profile.Port) fmt.Printf("Server running on %s:%d\n", profile.Addr, profile.Port)
fmt.Printf("Access your memos at: http://%s:%d\n", profile.Addr, profile.Port)
} }
} else { } else {
fmt.Printf("Version %s has been started on unix socket %s\n", profile.Version, profile.UNIXSock) fmt.Printf("Server running on unix socket: %s\n", profile.UNIXSock)
} }
fmt.Printf(`---
See more in: fmt.Println()
👉Website: %s fmt.Printf("<22> Documentation: %s\n", "https://usememos.com")
👉GitHub: %s fmt.Printf("💻 Source code: %s\n", "https://github.com/usememos/memos")
--- fmt.Println("\n✨ Happy note-taking!")
`, "https://usememos.com", "https://github.com/usememos/memos")
} }
func main() { func main() {

View File

@ -1,4 +1,4 @@
package util package util //nolint:revive // util is an appropriate package name for utility functions
import ( import (
"testing" "testing"

View File

@ -420,6 +420,8 @@ func parseDescriptor(descriptor string, loc *time.Location) (Schedule, error) {
Dow: all(dow), Dow: all(dow),
Location: loc, Location: loc,
}, nil }, nil
default:
// Continue to check @every prefix below
} }
const every = "@every " const every = "@every "

View File

@ -45,6 +45,8 @@ func (c *CommonSQLConverter) ConvertExprToSQL(ctx *ConvertContext, expr *exprv1.
return c.handleInOperator(ctx, v.CallExpr) return c.handleInOperator(ctx, v.CallExpr)
case "contains": case "contains":
return c.handleContainsOperator(ctx, v.CallExpr) return c.handleContainsOperator(ctx, v.CallExpr)
default:
return errors.Errorf("unsupported call expression function: %s", v.CallExpr.Function)
} }
} else if v, ok := expr.ExprKind.(*exprv1.Expr_IdentExpr); ok { } else if v, ok := expr.ExprKind.(*exprv1.Expr_IdentExpr); ok {
return c.handleIdentifier(ctx, v.IdentExpr) return c.handleIdentifier(ctx, v.IdentExpr)
@ -144,9 +146,9 @@ func (c *CommonSQLConverter) handleComparisonOperator(ctx *ConvertContext, callE
return c.handlePinnedComparison(ctx, operator, value) return c.handlePinnedComparison(ctx, operator, value)
case "has_task_list", "has_link", "has_code", "has_incomplete_tasks": case "has_task_list", "has_link", "has_code", "has_incomplete_tasks":
return c.handleBooleanComparison(ctx, identifier, operator, value) return c.handleBooleanComparison(ctx, identifier, operator, value)
default:
return errors.Errorf("unsupported identifier in comparison: %s", identifier)
} }
return nil
} }
func (c *CommonSQLConverter) handleSizeComparison(ctx *ConvertContext, callExpr *exprv1.Expr_Call, sizeCall *exprv1.Expr_Call) error { func (c *CommonSQLConverter) handleSizeComparison(ctx *ConvertContext, callExpr *exprv1.Expr_Call, sizeCall *exprv1.Expr_Call) error {
@ -567,6 +569,8 @@ func (c *CommonSQLConverter) handleBooleanComparison(ctx *ConvertContext, field,
jsonPath = "$.property.hasCode" jsonPath = "$.property.hasCode"
case "has_incomplete_tasks": case "has_incomplete_tasks":
jsonPath = "$.property.hasIncompleteTasks" jsonPath = "$.property.hasIncompleteTasks"
default:
return errors.Errorf("unsupported boolean field: %s", field)
} }
// Special handling for SQLite based on field // Special handling for SQLite based on field

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.7 // protoc-gen-go v1.36.8
// protoc (unknown) // protoc (unknown)
// source: api/v1/activity_service.proto // source: api/v1/activity_service.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.7 // protoc-gen-go v1.36.8
// protoc (unknown) // protoc (unknown)
// source: api/v1/attachment_service.proto // source: api/v1/attachment_service.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.7 // protoc-gen-go v1.36.8
// protoc (unknown) // protoc (unknown)
// source: api/v1/auth_service.proto // source: api/v1/auth_service.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.7 // protoc-gen-go v1.36.8
// protoc (unknown) // protoc (unknown)
// source: api/v1/common.proto // source: api/v1/common.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.7 // protoc-gen-go v1.36.8
// protoc (unknown) // protoc (unknown)
// source: api/v1/idp_service.proto // source: api/v1/idp_service.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.7 // protoc-gen-go v1.36.8
// protoc (unknown) // protoc (unknown)
// source: api/v1/inbox_service.proto // source: api/v1/inbox_service.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.7 // protoc-gen-go v1.36.8
// protoc (unknown) // protoc (unknown)
// source: api/v1/markdown_service.proto // source: api/v1/markdown_service.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.7 // protoc-gen-go v1.36.8
// protoc (unknown) // protoc (unknown)
// source: api/v1/memo_service.proto // source: api/v1/memo_service.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.7 // protoc-gen-go v1.36.8
// protoc (unknown) // protoc (unknown)
// source: api/v1/shortcut_service.proto // source: api/v1/shortcut_service.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.7 // protoc-gen-go v1.36.8
// protoc (unknown) // protoc (unknown)
// source: api/v1/user_service.proto // source: api/v1/user_service.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.7 // protoc-gen-go v1.36.8
// protoc (unknown) // protoc (unknown)
// source: api/v1/workspace_service.proto // source: api/v1/workspace_service.proto

View File

@ -15,19 +15,13 @@ paths:
parameters: parameters:
- name: pageSize - name: pageSize
in: query in: query
description: |- 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."
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.
schema: schema:
type: integer type: integer
format: int32 format: int32
- name: pageToken - name: pageToken
in: query in: query
description: |- description: "A page token, received from a previous `ListActivities` call.\r\n Provide this to retrieve the subsequent page."
A page token, received from a previous `ListActivities` call.
Provide this to retrieve the subsequent page.
schema: schema:
type: string type: string
responses: responses:
@ -78,35 +72,23 @@ paths:
parameters: parameters:
- name: pageSize - name: pageSize
in: query in: query
description: |- 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."
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.
schema: schema:
type: integer type: integer
format: int32 format: int32
- name: pageToken - name: pageToken
in: query in: query
description: |- description: "Optional. A page token, received from a previous `ListAttachments` call.\r\n Provide this to retrieve the subsequent page."
Optional. A page token, received from a previous `ListAttachments` call.
Provide this to retrieve the subsequent page.
schema: schema:
type: string type: string
- name: filter - name: filter
in: query in: query
description: |- 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"
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
schema: schema:
type: string type: string
- name: orderBy - name: orderBy
in: query in: query
description: |- description: "Optional. The order to sort results by.\r\n Example: \"create_time desc\" or \"filename asc\""
Optional. The order to sort results by.
Example: "create_time desc" or "filename asc"
schema: schema:
type: string type: string
responses: responses:
@ -130,9 +112,7 @@ paths:
parameters: parameters:
- name: attachmentId - name: attachmentId
in: query in: query
description: |- description: "Optional. The attachment ID to use for this attachment.\r\n If empty, a unique ID will be generated."
Optional. The attachment ID to use for this attachment.
If empty, a unique ID will be generated.
schema: schema:
type: string type: string
requestBody: requestBody:
@ -243,9 +223,7 @@ paths:
post: post:
tags: tags:
- AuthService - AuthService
description: |- description: "CreateSession authenticates a user and creates a new session.\r\n Returns the authenticated user information upon successful authentication."
CreateSession authenticates a user and creates a new session.
Returns the authenticated user information upon successful authentication.
operationId: AuthService_CreateSession operationId: AuthService_CreateSession
requestBody: requestBody:
content: content:
@ -270,9 +248,7 @@ paths:
get: get:
tags: tags:
- AuthService - AuthService
description: |- description: "GetCurrentSession returns the current active session information.\r\n This method is idempotent and safe, suitable for checking current session state."
GetCurrentSession returns the current active session information.
This method is idempotent and safe, suitable for checking current session state.
operationId: AuthService_GetCurrentSession operationId: AuthService_GetCurrentSession
responses: responses:
"200": "200":
@ -290,9 +266,7 @@ paths:
delete: delete:
tags: tags:
- AuthService - AuthService
description: |- description: "DeleteSession terminates the current user session.\r\n This is an idempotent operation that invalidates the user's authentication."
DeleteSession terminates the current user session.
This is an idempotent operation that invalidates the user's authentication.
operationId: AuthService_DeleteSession operationId: AuthService_DeleteSession
responses: responses:
"200": "200":
@ -331,9 +305,7 @@ paths:
parameters: parameters:
- name: identityProviderId - name: identityProviderId
in: query in: query
description: |- 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."
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.
schema: schema:
type: string type: string
requestBody: requestBody:
@ -417,9 +389,7 @@ paths:
type: string type: string
- name: updateMask - name: updateMask
in: query in: query
description: |- description: "Required. The update mask applies to the resource. Only the top level fields of\r\n IdentityProvider are supported."
Required. The update mask applies to the resource. Only the top level fields of
IdentityProvider are supported.
schema: schema:
type: string type: string
format: field-mask format: field-mask
@ -511,9 +481,7 @@ paths:
get: get:
tags: tags:
- MarkdownService - MarkdownService
description: |- description: "GetLinkMetadata returns metadata for a given link.\r\n This is useful for generating link previews."
GetLinkMetadata returns metadata for a given link.
This is useful for generating link previews.
operationId: MarkdownService_GetLinkMetadata operationId: MarkdownService_GetLinkMetadata
parameters: parameters:
- name: link - name: link
@ -538,9 +506,7 @@ paths:
post: post:
tags: tags:
- MarkdownService - MarkdownService
description: |- 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."
ParseMarkdown parses the given markdown content and returns a list of nodes.
This is a utility method that transforms markdown text into structured nodes.
operationId: MarkdownService_ParseMarkdown operationId: MarkdownService_ParseMarkdown
requestBody: requestBody:
content: content:
@ -565,9 +531,7 @@ paths:
post: post:
tags: tags:
- MarkdownService - MarkdownService
description: |- description: "RestoreMarkdownNodes restores the given nodes to markdown content.\r\n This is the inverse operation of ParseMarkdown."
RestoreMarkdownNodes restores the given nodes to markdown content.
This is the inverse operation of ParseMarkdown.
operationId: MarkdownService_RestoreMarkdownNodes operationId: MarkdownService_RestoreMarkdownNodes
requestBody: requestBody:
content: content:
@ -592,9 +556,7 @@ paths:
post: post:
tags: tags:
- MarkdownService - MarkdownService
description: |- description: "StringifyMarkdownNodes stringify the given nodes to plain text content.\r\n This removes all markdown formatting and returns plain text."
StringifyMarkdownNodes stringify the given nodes to plain text content.
This removes all markdown formatting and returns plain text.
operationId: MarkdownService_StringifyMarkdownNodes operationId: MarkdownService_StringifyMarkdownNodes
requestBody: requestBody:
content: content:
@ -624,26 +586,18 @@ paths:
parameters: parameters:
- name: pageSize - name: pageSize
in: query in: query
description: |- 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."
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.
schema: schema:
type: integer type: integer
format: int32 format: int32
- name: pageToken - name: pageToken
in: query in: query
description: |- description: "Optional. A page token, received from a previous `ListMemos` call.\r\n Provide this to retrieve the subsequent page."
Optional. A page token, received from a previous `ListMemos` call.
Provide this to retrieve the subsequent page.
schema: schema:
type: string type: string
- name: state - name: state
in: query in: query
description: |- description: "Optional. The state of the memos to list.\r\n Default to `NORMAL`. Set to `ARCHIVED` to list archived memos."
Optional. The state of the memos to list.
Default to `NORMAL`. Set to `ARCHIVED` to list archived memos.
schema: schema:
enum: enum:
- STATE_UNSPECIFIED - STATE_UNSPECIFIED
@ -653,18 +607,12 @@ paths:
format: enum format: enum
- name: orderBy - name: orderBy
in: query in: query
description: |- 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\""
Optional. The order to sort results by.
Default to "display_time desc".
Example: "display_time desc" or "create_time asc"
schema: schema:
type: string type: string
- name: filter - name: filter
in: query in: query
description: |- 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`."
Optional. Filter to apply to the list results.
Filter is a CEL expression to filter memos.
Refer to `Shortcut.filter`.
schema: schema:
type: string type: string
- name: showDeleted - name: showDeleted
@ -693,9 +641,7 @@ paths:
parameters: parameters:
- name: memoId - name: memoId
in: query in: query
description: |- description: "Optional. The memo ID to use for this memo.\r\n If empty, a unique ID will be generated."
Optional. The memo ID to use for this memo.
If empty, a unique ID will be generated.
schema: schema:
type: string type: string
- name: validateOnly - name: validateOnly
@ -742,9 +688,7 @@ paths:
type: string type: string
- name: readMask - name: readMask
in: query in: query
description: |- description: "Optional. The fields to return in the response.\r\n If not specified, all fields are returned."
Optional. The fields to return in the response.
If not specified, all fields are returned.
schema: schema:
type: string type: string
format: field-mask format: field-mask
@ -1196,28 +1140,18 @@ paths:
parameters: parameters:
- name: pageSize - name: pageSize
in: query in: query
description: |- 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."
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.
schema: schema:
type: integer type: integer
format: int32 format: int32
- name: pageToken - name: pageToken
in: query in: query
description: |- description: "Optional. A page token, received from a previous `ListUsers` call.\r\n Provide this to retrieve the subsequent page."
Optional. A page token, received from a previous `ListUsers` call.
Provide this to retrieve the subsequent page.
schema: schema:
type: string type: string
- name: filter - name: filter
in: query in: query
description: |- 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"
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: schema:
type: string type: string
- name: showDeleted - name: showDeleted
@ -1246,10 +1180,7 @@ paths:
parameters: parameters:
- name: userId - name: userId
in: query in: query
description: |- 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-]+"
Optional. The user ID to use for this user.
If empty, a unique ID will be generated.
Must match the pattern [a-z0-9-]+
schema: schema:
type: string type: string
- name: validateOnly - name: validateOnly
@ -1259,9 +1190,7 @@ paths:
type: boolean type: boolean
- name: requestId - name: requestId
in: query in: query
description: |- description: "Optional. An idempotency token that can be used to ensure that multiple\r\n requests to create a user have the same result."
Optional. An idempotency token that can be used to ensure that multiple
requests to create a user have the same result.
schema: schema:
type: string type: string
requestBody: requestBody:
@ -1298,9 +1227,7 @@ paths:
type: string type: string
- name: readMask - name: readMask
in: query in: query
description: |- description: "Optional. The fields to return in the response.\r\n If not specified, all fields are returned."
Optional. The fields to return in the response.
If not specified, all fields are returned.
schema: schema:
type: string type: string
format: field-mask format: field-mask
@ -1527,35 +1454,23 @@ paths:
type: string type: string
- name: pageSize - name: pageSize
in: query in: query
description: |- 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."
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.
schema: schema:
type: integer type: integer
format: int32 format: int32
- name: pageToken - name: pageToken
in: query in: query
description: |- description: "Optional. A page token, received from a previous `ListInboxes` call.\r\n Provide this to retrieve the subsequent page."
Optional. A page token, received from a previous `ListInboxes` call.
Provide this to retrieve the subsequent page.
schema: schema:
type: string type: string
- name: filter - name: filter
in: query in: query
description: |- 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"
Optional. Filter to apply to the list results.
Example: "status=UNREAD" or "type=MEMO_COMMENT"
Supported operators: =, !=
Supported fields: status, type, sender, create_time
schema: schema:
type: string type: string
- name: orderBy - name: orderBy
in: query in: query
description: |- description: "Optional. The order to sort results by.\r\n Example: \"create_time desc\" or \"status asc\""
Optional. The order to sort results by.
Example: "create_time desc" or "status asc"
schema: schema:
type: string type: string
responses: responses:
@ -1641,19 +1556,13 @@ paths:
type: string type: string
- name: pageSize - name: pageSize
in: query in: query
description: |- 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."
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.
schema: schema:
type: integer type: integer
format: int32 format: int32
- name: pageToken - name: pageToken
in: query in: query
description: |- description: "Optional. A page token, received from a previous `ListUserSettings` call.\r\n Provide this to retrieve the subsequent page."
Optional. A page token, received from a previous `ListUserSettings` call.
Provide this to retrieve the subsequent page.
schema: schema:
type: string type: string
responses: responses:
@ -2208,15 +2117,11 @@ components:
name: name:
readOnly: true readOnly: true
type: string type: string
description: |- description: "The name of the activity.\r\n Format: activities/{id}"
The name of the activity.
Format: activities/{id}
creator: creator:
readOnly: true readOnly: true
type: string type: string
description: |- description: "The name of the creator.\r\n Format: users/{user}"
The name of the creator.
Format: users/{user}
type: type:
readOnly: true readOnly: true
enum: enum:
@ -2251,14 +2156,10 @@ components:
properties: properties:
memo: memo:
type: string type: string
description: |- description: "The memo name of comment.\r\n Format: memos/{memo}"
The memo name of comment.
Format: memos/{memo}
relatedMemo: relatedMemo:
type: string type: string
description: |- description: "The name of related memo.\r\n Format: memos/{memo}"
The name of related memo.
Format: memos/{memo}
description: ActivityMemoCommentPayload represents the payload of a memo comment activity. description: ActivityMemoCommentPayload represents the payload of a memo comment activity.
ActivityPayload: ActivityPayload:
type: object type: object
@ -2275,9 +2176,7 @@ components:
properties: properties:
name: name:
type: string type: string
description: |- description: "The name of the attachment.\r\n Format: attachments/{attachment}"
The name of the attachment.
Format: attachments/{attachment}
createTime: createTime:
readOnly: true readOnly: true
type: string type: string
@ -2303,9 +2202,7 @@ components:
description: Output only. The size of the attachment in bytes. description: Output only. The size of the attachment in bytes.
memo: memo:
type: string type: string
description: |- description: "Optional. The related memo. Refer to `Memo.name`.\r\n Format: memos/{memo}"
Optional. The related memo. Refer to `Memo.name`.
Format: memos/{memo}
AutoLinkNode: AutoLinkNode:
type: object type: object
properties: properties:
@ -2367,14 +2264,10 @@ components:
properties: properties:
username: username:
type: string type: string
description: |- description: "The username to sign in with.\r\n Required field for password-based authentication."
The username to sign in with.
Required field for password-based authentication.
password: password:
type: string type: string
description: |- description: "The password to sign in with.\r\n Required field for password-based authentication."
The password to sign in with.
Required field for password-based authentication.
description: Nested message for password-based authentication credentials. description: Nested message for password-based authentication credentials.
CreateSessionRequest_SSOCredentials: CreateSessionRequest_SSOCredentials:
required: required:
@ -2385,20 +2278,14 @@ components:
properties: properties:
idpId: idpId:
type: integer type: integer
description: |- description: "The ID of the SSO provider.\r\n Required field to identify the SSO provider."
The ID of the SSO provider.
Required field to identify the SSO provider.
format: int32 format: int32
code: code:
type: string type: string
description: |- description: "The authorization code from the SSO provider.\r\n Required field for completing the SSO flow."
The authorization code from the SSO provider.
Required field for completing the SSO flow.
redirectUri: redirectUri:
type: string type: string
description: |- description: "The redirect URI used in the SSO flow.\r\n Required field for security validation."
The redirect URI used in the SSO flow.
Required field for security validation.
description: Nested message for SSO authentication credentials. description: Nested message for SSO authentication credentials.
CreateSessionResponse: CreateSessionResponse:
type: object type: object
@ -2409,9 +2296,7 @@ components:
description: The authenticated user information. description: The authenticated user information.
lastAccessedAt: lastAccessedAt:
type: string type: string
description: |- description: "Last time the session was accessed.\r\n Used for sliding expiration calculation (last_accessed_time + 2 weeks)."
Last time the session was accessed.
Used for sliding expiration calculation (last_accessed_time + 2 weeks).
format: date-time format: date-time
DeleteMemoTagRequest: DeleteMemoTagRequest:
required: required:
@ -2421,9 +2306,7 @@ components:
properties: properties:
parent: parent:
type: string type: string
description: |- description: "Required. The parent, who owns the tags.\r\n Format: memos/{memo}. Use \"memos/-\" to delete all tags."
Required. The parent, who owns the tags.
Format: memos/{memo}. Use "memos/-" to delete all tags.
tag: tag:
type: string type: string
description: Required. The tag name to delete. description: Required. The tag name to delete.
@ -2474,9 +2357,7 @@ components:
$ref: '#/components/schemas/User' $ref: '#/components/schemas/User'
lastAccessedAt: lastAccessedAt:
type: string type: string
description: |- description: "Last time the session was accessed.\r\n Used for sliding expiration calculation (last_accessed_time + 2 weeks)."
Last time the session was accessed.
Used for sliding expiration calculation (last_accessed_time + 2 weeks).
format: date-time format: date-time
GoogleProtobufAny: GoogleProtobufAny:
type: object type: object
@ -2524,9 +2405,7 @@ components:
properties: properties:
name: name:
type: string type: string
description: |- description: "The resource name of the identity provider.\r\n Format: identityProviders/{idp}"
The resource name of the identity provider.
Format: identityProviders/{idp}
type: type:
enum: enum:
- TYPE_UNSPECIFIED - TYPE_UNSPECIFIED
@ -2561,21 +2440,15 @@ components:
properties: properties:
name: name:
type: string type: string
description: |- description: "The resource name of the inbox.\r\n Format: inboxes/{inbox}"
The resource name of the inbox.
Format: inboxes/{inbox}
sender: sender:
readOnly: true readOnly: true
type: string type: string
description: |- description: "The sender of the inbox notification.\r\n Format: users/{user}"
The sender of the inbox notification.
Format: users/{user}
receiver: receiver:
readOnly: true readOnly: true
type: string type: string
description: |- description: "The receiver of the inbox notification.\r\n Format: users/{user}"
The receiver of the inbox notification.
Format: users/{user}
status: status:
enum: enum:
- STATUS_UNSPECIFIED - STATUS_UNSPECIFIED
@ -2645,10 +2518,7 @@ components:
description: The activities. description: The activities.
nextPageToken: nextPageToken:
type: string type: string
description: |- 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."
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.
ListAllUserStatsResponse: ListAllUserStatsResponse:
type: object type: object
properties: properties:
@ -2667,9 +2537,7 @@ components:
description: The list of attachments. description: The list of attachments.
nextPageToken: nextPageToken:
type: string type: string
description: |- 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."
A token that can be sent as `page_token` to retrieve the next page.
If this field is omitted, there are no subsequent pages.
totalSize: totalSize:
type: integer type: integer
description: The total count of attachments (may be approximate). description: The total count of attachments (may be approximate).
@ -2692,9 +2560,7 @@ components:
description: The list of inboxes. description: The list of inboxes.
nextPageToken: nextPageToken:
type: string type: string
description: |- 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."
A token that can be sent as `page_token` to retrieve the next page.
If this field is omitted, there are no subsequent pages.
totalSize: totalSize:
type: integer type: integer
description: The total count of inboxes (may be approximate). description: The total count of inboxes (may be approximate).
@ -2769,9 +2635,7 @@ components:
description: The list of memos. description: The list of memos.
nextPageToken: nextPageToken:
type: string type: string
description: |- 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."
A token that can be sent as `page_token` to retrieve the next page.
If this field is omitted, there are no subsequent pages.
totalSize: totalSize:
type: integer type: integer
description: The total count of memos (may be approximate). description: The total count of memos (may be approximate).
@ -2835,9 +2699,7 @@ components:
description: The list of user settings. description: The list of user settings.
nextPageToken: nextPageToken:
type: string type: string
description: |- 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."
A token that can be sent as `page_token` to retrieve the next page.
If this field is omitted, there are no subsequent pages.
totalSize: totalSize:
type: integer type: integer
description: The total count of settings (may be approximate). description: The total count of settings (may be approximate).
@ -2861,9 +2723,7 @@ components:
description: The list of users. description: The list of users.
nextPageToken: nextPageToken:
type: string type: string
description: |- 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."
A token that can be sent as `page_token` to retrieve the next page.
If this field is omitted, there are no subsequent pages.
totalSize: totalSize:
type: integer type: integer
description: The total count of users (may be approximate). description: The total count of users (may be approximate).
@ -2901,9 +2761,7 @@ components:
properties: properties:
name: name:
type: string type: string
description: |- description: "The resource name of the memo.\r\n Format: memos/{memo}, memo is the user defined id or uuid."
The resource name of the memo.
Format: memos/{memo}, memo is the user defined id or uuid.
state: state:
enum: enum:
- STATE_UNSPECIFIED - STATE_UNSPECIFIED
@ -2915,9 +2773,7 @@ components:
creator: creator:
readOnly: true readOnly: true
type: string type: string
description: |- description: "The name of the creator.\r\n Format: users/{user}"
The name of the creator.
Format: users/{user}
createTime: createTime:
readOnly: true readOnly: true
type: string type: string
@ -2983,9 +2839,7 @@ components:
parent: parent:
readOnly: true readOnly: true
type: string type: string
description: |- description: "Output only. The name of the parent memo.\r\n Format: memos/{memo}"
Output only. The name of the parent memo.
Format: memos/{memo}
snippet: snippet:
readOnly: true readOnly: true
type: string type: string
@ -3023,9 +2877,7 @@ components:
properties: properties:
name: name:
type: string type: string
description: |- description: "The resource name of the memo.\r\n Format: memos/{memo}"
The resource name of the memo.
Format: memos/{memo}
snippet: snippet:
readOnly: true readOnly: true
type: string type: string
@ -3211,21 +3063,14 @@ components:
name: name:
readOnly: true readOnly: true
type: string type: string
description: |- description: "The resource name of the reaction.\r\n Format: reactions/{reaction}"
The resource name of the reaction.
Format: reactions/{reaction}
creator: creator:
readOnly: true readOnly: true
type: string type: string
description: |- description: "The resource name of the creator.\r\n Format: users/{user}"
The resource name of the creator.
Format: users/{user}
contentId: contentId:
type: string type: string
description: |- 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}"
The resource name of the content.
For memo reactions, this should be the memo's resource name.
Format: memos/{memo}
reactionType: reactionType:
type: string type: string
description: "Required. The type of reaction (e.g., \"\U0001F44D\", \"❤️\", \"\U0001F604\")." description: "Required. The type of reaction (e.g., \"\U0001F44D\", \"❤️\", \"\U0001F604\")."
@ -3252,9 +3097,7 @@ components:
properties: properties:
parent: parent:
type: string type: string
description: |- description: "Required. The parent, who owns the tags.\r\n Format: memos/{memo}. Use \"memos/-\" to rename all tags."
Required. The parent, who owns the tags.
Format: memos/{memo}. Use "memos/-" to rename all tags.
oldTag: oldTag:
type: string type: string
description: Required. The old tag name to rename. description: Required. The old tag name to rename.
@ -3285,9 +3128,7 @@ components:
properties: properties:
name: name:
type: string type: string
description: |- description: "Required. The resource name of the memo.\r\n Format: memos/{memo}"
Required. The resource name of the memo.
Format: memos/{memo}
attachments: attachments:
type: array type: array
items: items:
@ -3301,9 +3142,7 @@ components:
properties: properties:
name: name:
type: string type: string
description: |- description: "Required. The resource name of the memo.\r\n Format: memos/{memo}"
Required. The resource name of the memo.
Format: memos/{memo}
relations: relations:
type: array type: array
items: items:
@ -3316,9 +3155,7 @@ components:
properties: properties:
name: name:
type: string type: string
description: |- description: "The resource name of the shortcut.\r\n Format: users/{user}/shortcuts/{shortcut}"
The resource name of the shortcut.
Format: users/{user}/shortcuts/{shortcut}
title: title:
type: string type: string
description: The title of the shortcut. description: The title of the shortcut.
@ -3361,9 +3198,7 @@ components:
type: string type: string
usePathStyle: usePathStyle:
type: boolean type: boolean
description: |- description: "S3 configuration for cloud storage backend.\r\n Reference: https://developers.cloudflare.com/r2/examples/aws/aws-sdk-go/"
S3 configuration for cloud storage backend.
Reference: https://developers.cloudflare.com/r2/examples/aws/aws-sdk-go/
StrikethroughNode: StrikethroughNode:
type: object type: object
properties: properties:
@ -3461,9 +3296,7 @@ components:
properties: properties:
name: name:
type: string type: string
description: |- description: "Required. The resource name of the memo.\r\n Format: memos/{memo}"
Required. The resource name of the memo.
Format: memos/{memo}
reaction: reaction:
allOf: allOf:
- $ref: '#/components/schemas/Reaction' - $ref: '#/components/schemas/Reaction'
@ -3477,9 +3310,7 @@ components:
properties: properties:
name: name:
type: string type: string
description: |- description: "The resource name of the user.\r\n Format: users/{user}"
The resource name of the user.
Format: users/{user}
role: role:
enum: enum:
- ROLE_UNSPECIFIED - ROLE_UNSPECIFIED
@ -3531,9 +3362,7 @@ components:
properties: properties:
name: name:
type: string type: string
description: |- description: "The resource name of the access token.\r\n Format: users/{user}/accessTokens/{access_token}"
The resource name of the access token.
Format: users/{user}/accessTokens/{access_token}
accessToken: accessToken:
readOnly: true readOnly: true
type: string type: string
@ -3556,9 +3385,7 @@ components:
properties: properties:
name: name:
type: string type: string
description: |- description: "The resource name of the session.\r\n Format: users/{user}/sessions/{session}"
The resource name of the session.
Format: users/{user}/sessions/{session}
sessionId: sessionId:
readOnly: true readOnly: true
type: string type: string
@ -3571,9 +3398,7 @@ components:
lastAccessedTime: lastAccessedTime:
readOnly: true readOnly: true
type: string type: string
description: |- description: "The timestamp when the session was last accessed.\r\n Used for sliding expiration calculation (last_accessed_time + 2 weeks)."
The timestamp when the session was last accessed.
Used for sliding expiration calculation (last_accessed_time + 2 weeks).
format: date-time format: date-time
clientInfo: clientInfo:
readOnly: true readOnly: true
@ -3603,10 +3428,7 @@ components:
properties: properties:
name: name:
type: string type: string
description: |- 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."
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.
generalSetting: generalSetting:
$ref: '#/components/schemas/UserSetting_GeneralSetting' $ref: '#/components/schemas/UserSetting_GeneralSetting'
sessionsSetting: sessionsSetting:
@ -3636,10 +3458,7 @@ components:
description: The default visibility of the memo. description: The default visibility of the memo.
theme: theme:
type: string type: string
description: |- 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."
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: General user settings configuration. description: General user settings configuration.
UserSetting_SessionsSetting: UserSetting_SessionsSetting:
type: object type: object
@ -3664,9 +3483,7 @@ components:
properties: properties:
name: name:
type: string type: string
description: |- description: "The resource name of the user whose stats these are.\r\n Format: users/{user}"
The resource name of the user whose stats these are.
Format: users/{user}
memoDisplayTimestamps: memoDisplayTimestamps:
type: array type: array
items: items:
@ -3714,9 +3531,7 @@ components:
properties: properties:
name: name:
type: string type: string
description: |- description: "The name of the webhook.\r\n Format: users/{user}/webhooks/{webhook}"
The name of the webhook.
Format: users/{user}/webhooks/{webhook}
url: url:
type: string type: string
description: The URL to send the webhook to. description: The URL to send the webhook to.
@ -3739,9 +3554,7 @@ components:
properties: properties:
owner: owner:
type: string type: string
description: |- description: "The name of instance owner.\r\n Format: users/{user}"
The name of instance owner.
Format: users/{user}
version: version:
type: string type: string
description: Version is the current version of instance. description: Version is the current version of instance.
@ -3757,9 +3570,7 @@ components:
properties: properties:
name: name:
type: string type: string
description: |- description: "The name of the workspace setting.\r\n Format: workspace/settings/{setting}"
The name of the workspace setting.
Format: workspace/settings/{setting}
generalSetting: generalSetting:
$ref: '#/components/schemas/WorkspaceSetting_GeneralSetting' $ref: '#/components/schemas/WorkspaceSetting_GeneralSetting'
storageSetting: storageSetting:
@ -3772,9 +3583,7 @@ components:
properties: properties:
theme: theme:
type: string type: string
description: |- description: "theme is the name of the selected theme.\r\n This references a CSS file in the web/public/themes/ directory."
theme is the name of the selected theme.
This references a CSS file in the web/public/themes/ directory.
disallowUserRegistration: disallowUserRegistration:
type: boolean type: boolean
description: disallow_user_registration disallows user registration. description: disallow_user_registration disallows user registration.
@ -3793,10 +3602,7 @@ components:
description: custom_profile is the custom profile. description: custom_profile is the custom profile.
weekStartDayOffset: weekStartDayOffset:
type: integer type: integer
description: |- 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."
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.
format: int32 format: int32
disallowChangeUsername: disallowChangeUsername:
type: boolean type: boolean
@ -3855,9 +3661,7 @@ components:
format: enum format: enum
filepathTemplate: filepathTemplate:
type: string type: string
description: |- description: "The template of file path.\r\n e.g. assets/{timestamp}_{filename}"
The template of file path.
e.g. assets/{timestamp}_{filename}
uploadSizeLimitMb: uploadSizeLimitMb:
type: string type: string
description: The max upload size in megabytes. description: The max upload size in megabytes.

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.7 // protoc-gen-go v1.36.8
// protoc (unknown) // protoc (unknown)
// source: store/activity.proto // source: store/activity.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.7 // protoc-gen-go v1.36.8
// protoc (unknown) // protoc (unknown)
// source: store/attachment.proto // source: store/attachment.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.7 // protoc-gen-go v1.36.8
// protoc (unknown) // protoc (unknown)
// source: store/idp.proto // source: store/idp.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.7 // protoc-gen-go v1.36.8
// protoc (unknown) // protoc (unknown)
// source: store/inbox.proto // source: store/inbox.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.7 // protoc-gen-go v1.36.8
// protoc (unknown) // protoc (unknown)
// source: store/memo.proto // source: store/memo.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.7 // protoc-gen-go v1.36.8
// protoc (unknown) // protoc (unknown)
// source: store/user_setting.proto // source: store/user_setting.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.7 // protoc-gen-go v1.36.8
// protoc (unknown) // protoc (unknown)
// source: store/workspace_setting.proto // source: store/workspace_setting.proto

View File

@ -582,8 +582,9 @@ func replaceFilenameWithPathTemplate(path, filename string) string {
return fmt.Sprintf("%02d", t.Second()) return fmt.Sprintf("%02d", t.Second())
case "{uuid}": case "{uuid}":
return util.GenUUID() return util.GenUUID()
default:
return s
} }
return s
}) })
return path return path
} }

View File

@ -162,7 +162,7 @@ func TestClientInfoExamples(t *testing.T) {
t.Logf("Device Type: %s", clientInfo.DeviceType) t.Logf("Device Type: %s", clientInfo.DeviceType)
t.Logf("Operating System: %s", clientInfo.Os) t.Logf("Operating System: %s", clientInfo.Os)
t.Logf("Browser: %s", clientInfo.Browser) t.Logf("Browser: %s", clientInfo.Browser)
t.Logf("---") t.Log("---")
// Ensure all fields are populated // Ensure all fields are populated
if clientInfo.DeviceType == "" { if clientInfo.DeviceType == "" {

View File

@ -82,6 +82,8 @@ func (s *APIV1Service) UpdateIdentityProvider(ctx context.Context, request *v1pb
update.IdentifierFilter = &request.IdentityProvider.IdentifierFilter update.IdentifierFilter = &request.IdentityProvider.IdentifierFilter
case "config": case "config":
update.Config = convertIdentityProviderConfigToStore(request.IdentityProvider.Type, request.IdentityProvider.Config) update.Config = convertIdentityProviderConfigToStore(request.IdentityProvider.Type, request.IdentityProvider.Config)
default:
// Ignore unsupported fields
} }
} }

View File

@ -405,6 +405,8 @@ func (s *APIV1Service) UpdateUserSetting(ctx context.Context, request *v1pb.Upda
updatedGeneral.Theme = incomingGeneral.Theme updatedGeneral.Theme = incomingGeneral.Theme
case "locale": case "locale":
updatedGeneral.Locale = incomingGeneral.Locale updatedGeneral.Locale = incomingGeneral.Locale
default:
// Ignore unsupported fields
} }
} }
@ -899,6 +901,8 @@ func (s *APIV1Service) UpdateUserWebhook(ctx context.Context, request *v1pb.Upda
} }
case "display_name": case "display_name":
updatedWebhook.Title = request.Webhook.DisplayName updatedWebhook.Title = request.Webhook.DisplayName
default:
// Ignore unsupported fields
} }
} }
} else { } else {
@ -1143,6 +1147,11 @@ func convertUserSettingFromStore(storeSetting *storepb.UserSetting, userID int32
Webhooks: []*v1pb.UserWebhook{}, Webhooks: []*v1pb.UserWebhook{},
}, },
} }
default:
// Default to general setting
setting.Value = &v1pb.UserSetting_GeneralSetting_{
GeneralSetting: getDefaultUserGeneralSetting(),
}
} }
return setting return setting
} }
@ -1223,6 +1232,11 @@ func convertUserSettingFromStore(storeSetting *storepb.UserSetting, userID int32
Webhooks: apiWebhooks, Webhooks: apiWebhooks,
}, },
} }
default:
// Default to general setting if unknown key
setting.Value = &v1pb.UserSetting_GeneralSetting_{
GeneralSetting: getDefaultUserGeneralSetting(),
}
} }
return setting return setting

View File

@ -141,6 +141,8 @@ func convertWorkspaceSettingToStore(setting *v1pb.WorkspaceSetting) *storepb.Wor
workspaceSetting.Value = &storepb.WorkspaceSetting_MemoRelatedSetting{ workspaceSetting.Value = &storepb.WorkspaceSetting_MemoRelatedSetting{
MemoRelatedSetting: convertWorkspaceMemoRelatedSettingToStore(setting.GetMemoRelatedSetting()), MemoRelatedSetting: convertWorkspaceMemoRelatedSettingToStore(setting.GetMemoRelatedSetting()),
} }
default:
// Keep the default GeneralSetting value
} }
return workspaceSetting return workspaceSetting
} }

View File

@ -31,30 +31,30 @@ func TestCacheBasicOperations(t *testing.T) {
// Test Delete // Test Delete
cache.Delete(ctx, "key1") cache.Delete(ctx, "key1")
if _, ok := cache.Get(ctx, "key1"); ok { if _, ok := cache.Get(ctx, "key1"); ok {
t.Errorf("Key 'key1' should have been deleted") t.Error("Key 'key1' should have been deleted")
} }
// Test automatic expiration // Test automatic expiration
time.Sleep(150 * time.Millisecond) time.Sleep(150 * time.Millisecond)
if _, ok := cache.Get(ctx, "key1"); ok { if _, ok := cache.Get(ctx, "key1"); ok {
t.Errorf("Key 'key1' should have expired") t.Error("Key 'key1' should have expired")
} }
// key2 should still be valid (200ms TTL) // key2 should still be valid (200ms TTL)
if _, ok := cache.Get(ctx, "key2"); !ok { if _, ok := cache.Get(ctx, "key2"); !ok {
t.Errorf("Key 'key2' should still be valid") t.Error("Key 'key2' should still be valid")
} }
// Wait for key2 to expire // Wait for key2 to expire
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
if _, ok := cache.Get(ctx, "key2"); ok { if _, ok := cache.Get(ctx, "key2"); ok {
t.Errorf("Key 'key2' should have expired") t.Error("Key 'key2' should have expired")
} }
// Test Clear // Test Clear
cache.Set(ctx, "key3", "value3") cache.Set(ctx, "key3", "value3")
cache.Clear(ctx) cache.Clear(ctx)
if _, ok := cache.Get(ctx, "key3"); ok { if _, ok := cache.Get(ctx, "key3"); ok {
t.Errorf("Cache should be empty after Clear()") t.Error("Cache should be empty after Clear()")
} }
} }
@ -98,15 +98,15 @@ func TestCacheEviction(t *testing.T) {
} }
if evictedCount == 0 { if evictedCount == 0 {
t.Errorf("No keys were evicted despite exceeding max items") t.Error("No keys were evicted despite exceeding max items")
} }
// The newer keys should still be present // The newer keys should still be present
if _, ok := cache.Get(ctx, "keyA"); !ok { if _, ok := cache.Get(ctx, "keyA"); !ok {
t.Errorf("Key 'keyA' should be in the cache") t.Error("Key 'keyA' should be in the cache")
} }
if _, ok := cache.Get(ctx, "keyB"); !ok { if _, ok := cache.Get(ctx, "keyB"); !ok {
t.Errorf("Key 'keyB' should be in the cache") t.Error("Key 'keyB' should be in the cache")
} }
} }
@ -193,7 +193,7 @@ func TestEvictionCallback(t *testing.T) {
time.Sleep(10 * time.Millisecond) // Small delay to ensure callback processed time.Sleep(10 * time.Millisecond) // Small delay to ensure callback processed
evictedMu.Lock() evictedMu.Lock()
if evicted["key1"] != "value1" { if evicted["key1"] != "value1" {
t.Errorf("Eviction callback not triggered for manual deletion") t.Error("Eviction callback not triggered for manual deletion")
} }
evictedMu.Unlock() evictedMu.Unlock()
@ -203,7 +203,7 @@ func TestEvictionCallback(t *testing.T) {
// Verify TTL expiration triggered callback // Verify TTL expiration triggered callback
evictedMu.Lock() evictedMu.Lock()
if evicted["key2"] != "value2" { if evicted["key2"] != "value2" {
t.Errorf("Eviction callback not triggered for TTL expiration") t.Error("Eviction callback not triggered for TTL expiration")
} }
evictedMu.Unlock() evictedMu.Unlock()
} }

View File

@ -29,8 +29,9 @@ func (v Visibility) String() string {
return "PROTECTED" return "PROTECTED"
case Private: case Private:
return "PRIVATE" return "PRIVATE"
default:
return "PRIVATE"
} }
return "PRIVATE"
} }
type Memo struct { type Memo struct {

View File

@ -102,6 +102,8 @@ func (s *Store) Migrate(ctx context.Context) error {
if err := s.seed(ctx); err != nil { if err := s.seed(ctx); err != nil {
return errors.Wrap(err, "failed to seed") return errors.Wrap(err, "failed to seed")
} }
default:
// For other modes (like dev), no special migration handling needed
} }
return nil return nil
} }

View File

@ -24,8 +24,9 @@ func (e Role) String() string {
return "ADMIN" return "ADMIN"
case RoleUser: case RoleUser:
return "USER" return "USER"
default:
return "USER"
} }
return "USER"
} }
const ( const (

View File

@ -128,6 +128,52 @@ export function editionToNumber(object: Edition): number {
} }
} }
/**
* Describes the 'visibility' of a symbol with respect to the proto import
* system. Symbols can only be imported when the visibility rules do not prevent
* it (ex: local symbols cannot be imported). Visibility modifiers can only set
* on `message` and `enum` as they are the only types available to be referenced
* from other files.
*/
export enum SymbolVisibility {
VISIBILITY_UNSET = "VISIBILITY_UNSET",
VISIBILITY_LOCAL = "VISIBILITY_LOCAL",
VISIBILITY_EXPORT = "VISIBILITY_EXPORT",
UNRECOGNIZED = "UNRECOGNIZED",
}
export function symbolVisibilityFromJSON(object: any): SymbolVisibility {
switch (object) {
case 0:
case "VISIBILITY_UNSET":
return SymbolVisibility.VISIBILITY_UNSET;
case 1:
case "VISIBILITY_LOCAL":
return SymbolVisibility.VISIBILITY_LOCAL;
case 2:
case "VISIBILITY_EXPORT":
return SymbolVisibility.VISIBILITY_EXPORT;
case -1:
case "UNRECOGNIZED":
default:
return SymbolVisibility.UNRECOGNIZED;
}
}
export function symbolVisibilityToNumber(object: SymbolVisibility): number {
switch (object) {
case SymbolVisibility.VISIBILITY_UNSET:
return 0;
case SymbolVisibility.VISIBILITY_LOCAL:
return 1;
case SymbolVisibility.VISIBILITY_EXPORT:
return 2;
case SymbolVisibility.UNRECOGNIZED:
default:
return -1;
}
}
/** /**
* The protocol compiler can output a FileDescriptorSet containing the .proto * The protocol compiler can output a FileDescriptorSet containing the .proto
* files it parses. * files it parses.
@ -155,6 +201,11 @@ export interface FileDescriptorProto {
* For Google-internal migration only. Do not use. * For Google-internal migration only. Do not use.
*/ */
weakDependency: number[]; weakDependency: number[];
/**
* Names of files imported by this file purely for the purpose of providing
* option extensions. These are excluded from the dependency list above.
*/
optionDependency: string[];
/** All top-level definitions in this file. */ /** All top-level definitions in this file. */
messageType: DescriptorProto[]; messageType: DescriptorProto[];
enumType: EnumDescriptorProto[]; enumType: EnumDescriptorProto[];
@ -209,6 +260,8 @@ export interface DescriptorProto {
* A given name may only be reserved once. * A given name may only be reserved once.
*/ */
reservedName: string[]; reservedName: string[];
/** Support for `export` and `local` keywords on enums. */
visibility?: SymbolVisibility | undefined;
} }
export interface DescriptorProto_ExtensionRange { export interface DescriptorProto_ExtensionRange {
@ -632,6 +685,8 @@ export interface EnumDescriptorProto {
* be reserved once. * be reserved once.
*/ */
reservedName: string[]; reservedName: string[];
/** Support for `export` and `local` keywords on enums. */
visibility?: SymbolVisibility | undefined;
} }
/** /**
@ -1594,6 +1649,7 @@ export interface FeatureSet {
messageEncoding?: FeatureSet_MessageEncoding | undefined; messageEncoding?: FeatureSet_MessageEncoding | undefined;
jsonFormat?: FeatureSet_JsonFormat | undefined; jsonFormat?: FeatureSet_JsonFormat | undefined;
enforceNamingStyle?: FeatureSet_EnforceNamingStyle | undefined; enforceNamingStyle?: FeatureSet_EnforceNamingStyle | undefined;
defaultSymbolVisibility?: FeatureSet_VisibilityFeature_DefaultSymbolVisibility | undefined;
} }
export enum FeatureSet_FieldPresence { export enum FeatureSet_FieldPresence {
@ -1875,6 +1931,72 @@ export function featureSet_EnforceNamingStyleToNumber(object: FeatureSet_Enforce
} }
} }
export interface FeatureSet_VisibilityFeature {
}
export enum FeatureSet_VisibilityFeature_DefaultSymbolVisibility {
DEFAULT_SYMBOL_VISIBILITY_UNKNOWN = "DEFAULT_SYMBOL_VISIBILITY_UNKNOWN",
/** EXPORT_ALL - Default pre-EDITION_2024, all UNSET visibility are export. */
EXPORT_ALL = "EXPORT_ALL",
/** EXPORT_TOP_LEVEL - All top-level symbols default to export, nested default to local. */
EXPORT_TOP_LEVEL = "EXPORT_TOP_LEVEL",
/** LOCAL_ALL - All symbols default to local. */
LOCAL_ALL = "LOCAL_ALL",
/**
* STRICT - All symbols local by default. Nested types cannot be exported.
* With special case caveat for message { enum {} reserved 1 to max; }
* This is the recommended setting for new protos.
*/
STRICT = "STRICT",
UNRECOGNIZED = "UNRECOGNIZED",
}
export function featureSet_VisibilityFeature_DefaultSymbolVisibilityFromJSON(
object: any,
): FeatureSet_VisibilityFeature_DefaultSymbolVisibility {
switch (object) {
case 0:
case "DEFAULT_SYMBOL_VISIBILITY_UNKNOWN":
return FeatureSet_VisibilityFeature_DefaultSymbolVisibility.DEFAULT_SYMBOL_VISIBILITY_UNKNOWN;
case 1:
case "EXPORT_ALL":
return FeatureSet_VisibilityFeature_DefaultSymbolVisibility.EXPORT_ALL;
case 2:
case "EXPORT_TOP_LEVEL":
return FeatureSet_VisibilityFeature_DefaultSymbolVisibility.EXPORT_TOP_LEVEL;
case 3:
case "LOCAL_ALL":
return FeatureSet_VisibilityFeature_DefaultSymbolVisibility.LOCAL_ALL;
case 4:
case "STRICT":
return FeatureSet_VisibilityFeature_DefaultSymbolVisibility.STRICT;
case -1:
case "UNRECOGNIZED":
default:
return FeatureSet_VisibilityFeature_DefaultSymbolVisibility.UNRECOGNIZED;
}
}
export function featureSet_VisibilityFeature_DefaultSymbolVisibilityToNumber(
object: FeatureSet_VisibilityFeature_DefaultSymbolVisibility,
): number {
switch (object) {
case FeatureSet_VisibilityFeature_DefaultSymbolVisibility.DEFAULT_SYMBOL_VISIBILITY_UNKNOWN:
return 0;
case FeatureSet_VisibilityFeature_DefaultSymbolVisibility.EXPORT_ALL:
return 1;
case FeatureSet_VisibilityFeature_DefaultSymbolVisibility.EXPORT_TOP_LEVEL:
return 2;
case FeatureSet_VisibilityFeature_DefaultSymbolVisibility.LOCAL_ALL:
return 3;
case FeatureSet_VisibilityFeature_DefaultSymbolVisibility.STRICT:
return 4;
case FeatureSet_VisibilityFeature_DefaultSymbolVisibility.UNRECOGNIZED:
default:
return -1;
}
}
/** /**
* A compiled specification for the defaults of a set of features. These * A compiled specification for the defaults of a set of features. These
* messages are generated from FeatureSet extensions and can be used to seed * messages are generated from FeatureSet extensions and can be used to seed
@ -2195,6 +2317,7 @@ function createBaseFileDescriptorProto(): FileDescriptorProto {
dependency: [], dependency: [],
publicDependency: [], publicDependency: [],
weakDependency: [], weakDependency: [],
optionDependency: [],
messageType: [], messageType: [],
enumType: [], enumType: [],
service: [], service: [],
@ -2227,6 +2350,9 @@ export const FileDescriptorProto: MessageFns<FileDescriptorProto> = {
writer.int32(v); writer.int32(v);
} }
writer.join(); writer.join();
for (const v of message.optionDependency) {
writer.uint32(122).string(v!);
}
for (const v of message.messageType) { for (const v of message.messageType) {
DescriptorProto.encode(v!, writer.uint32(34).fork()).join(); DescriptorProto.encode(v!, writer.uint32(34).fork()).join();
} }
@ -2321,6 +2447,14 @@ export const FileDescriptorProto: MessageFns<FileDescriptorProto> = {
break; break;
} }
case 15: {
if (tag !== 122) {
break;
}
message.optionDependency.push(reader.string());
continue;
}
case 4: { case 4: {
if (tag !== 34) { if (tag !== 34) {
break; break;
@ -2404,6 +2538,7 @@ export const FileDescriptorProto: MessageFns<FileDescriptorProto> = {
message.dependency = object.dependency?.map((e) => e) || []; message.dependency = object.dependency?.map((e) => e) || [];
message.publicDependency = object.publicDependency?.map((e) => e) || []; message.publicDependency = object.publicDependency?.map((e) => e) || [];
message.weakDependency = object.weakDependency?.map((e) => e) || []; message.weakDependency = object.weakDependency?.map((e) => e) || [];
message.optionDependency = object.optionDependency?.map((e) => e) || [];
message.messageType = object.messageType?.map((e) => DescriptorProto.fromPartial(e)) || []; message.messageType = object.messageType?.map((e) => DescriptorProto.fromPartial(e)) || [];
message.enumType = object.enumType?.map((e) => EnumDescriptorProto.fromPartial(e)) || []; message.enumType = object.enumType?.map((e) => EnumDescriptorProto.fromPartial(e)) || [];
message.service = object.service?.map((e) => ServiceDescriptorProto.fromPartial(e)) || []; message.service = object.service?.map((e) => ServiceDescriptorProto.fromPartial(e)) || [];
@ -2432,6 +2567,7 @@ function createBaseDescriptorProto(): DescriptorProto {
options: undefined, options: undefined,
reservedRange: [], reservedRange: [],
reservedName: [], reservedName: [],
visibility: SymbolVisibility.VISIBILITY_UNSET,
}; };
} }
@ -2467,6 +2603,9 @@ export const DescriptorProto: MessageFns<DescriptorProto> = {
for (const v of message.reservedName) { for (const v of message.reservedName) {
writer.uint32(82).string(v!); writer.uint32(82).string(v!);
} }
if (message.visibility !== undefined && message.visibility !== SymbolVisibility.VISIBILITY_UNSET) {
writer.uint32(88).int32(symbolVisibilityToNumber(message.visibility));
}
return writer; return writer;
}, },
@ -2557,6 +2696,14 @@ export const DescriptorProto: MessageFns<DescriptorProto> = {
message.reservedName.push(reader.string()); message.reservedName.push(reader.string());
continue; continue;
} }
case 11: {
if (tag !== 88) {
break;
}
message.visibility = symbolVisibilityFromJSON(reader.int32());
continue;
}
} }
if ((tag & 7) === 4 || tag === 0) { if ((tag & 7) === 4 || tag === 0) {
break; break;
@ -2583,6 +2730,7 @@ export const DescriptorProto: MessageFns<DescriptorProto> = {
: undefined; : undefined;
message.reservedRange = object.reservedRange?.map((e) => DescriptorProto_ReservedRange.fromPartial(e)) || []; message.reservedRange = object.reservedRange?.map((e) => DescriptorProto_ReservedRange.fromPartial(e)) || [];
message.reservedName = object.reservedName?.map((e) => e) || []; message.reservedName = object.reservedName?.map((e) => e) || [];
message.visibility = object.visibility ?? SymbolVisibility.VISIBILITY_UNSET;
return message; return message;
}, },
}; };
@ -3143,7 +3291,14 @@ export const OneofDescriptorProto: MessageFns<OneofDescriptorProto> = {
}; };
function createBaseEnumDescriptorProto(): EnumDescriptorProto { function createBaseEnumDescriptorProto(): EnumDescriptorProto {
return { name: "", value: [], options: undefined, reservedRange: [], reservedName: [] }; return {
name: "",
value: [],
options: undefined,
reservedRange: [],
reservedName: [],
visibility: SymbolVisibility.VISIBILITY_UNSET,
};
} }
export const EnumDescriptorProto: MessageFns<EnumDescriptorProto> = { export const EnumDescriptorProto: MessageFns<EnumDescriptorProto> = {
@ -3163,6 +3318,9 @@ export const EnumDescriptorProto: MessageFns<EnumDescriptorProto> = {
for (const v of message.reservedName) { for (const v of message.reservedName) {
writer.uint32(42).string(v!); writer.uint32(42).string(v!);
} }
if (message.visibility !== undefined && message.visibility !== SymbolVisibility.VISIBILITY_UNSET) {
writer.uint32(48).int32(symbolVisibilityToNumber(message.visibility));
}
return writer; return writer;
}, },
@ -3213,6 +3371,14 @@ export const EnumDescriptorProto: MessageFns<EnumDescriptorProto> = {
message.reservedName.push(reader.string()); message.reservedName.push(reader.string());
continue; continue;
} }
case 6: {
if (tag !== 48) {
break;
}
message.visibility = symbolVisibilityFromJSON(reader.int32());
continue;
}
} }
if ((tag & 7) === 4 || tag === 0) { if ((tag & 7) === 4 || tag === 0) {
break; break;
@ -3235,6 +3401,7 @@ export const EnumDescriptorProto: MessageFns<EnumDescriptorProto> = {
message.reservedRange = object.reservedRange?.map((e) => EnumDescriptorProto_EnumReservedRange.fromPartial(e)) || message.reservedRange = object.reservedRange?.map((e) => EnumDescriptorProto_EnumReservedRange.fromPartial(e)) ||
[]; [];
message.reservedName = object.reservedName?.map((e) => e) || []; message.reservedName = object.reservedName?.map((e) => e) || [];
message.visibility = object.visibility ?? SymbolVisibility.VISIBILITY_UNSET;
return message; return message;
}, },
}; };
@ -4999,6 +5166,7 @@ function createBaseFeatureSet(): FeatureSet {
messageEncoding: FeatureSet_MessageEncoding.MESSAGE_ENCODING_UNKNOWN, messageEncoding: FeatureSet_MessageEncoding.MESSAGE_ENCODING_UNKNOWN,
jsonFormat: FeatureSet_JsonFormat.JSON_FORMAT_UNKNOWN, jsonFormat: FeatureSet_JsonFormat.JSON_FORMAT_UNKNOWN,
enforceNamingStyle: FeatureSet_EnforceNamingStyle.ENFORCE_NAMING_STYLE_UNKNOWN, enforceNamingStyle: FeatureSet_EnforceNamingStyle.ENFORCE_NAMING_STYLE_UNKNOWN,
defaultSymbolVisibility: FeatureSet_VisibilityFeature_DefaultSymbolVisibility.DEFAULT_SYMBOL_VISIBILITY_UNKNOWN,
}; };
} }
@ -5039,6 +5207,15 @@ export const FeatureSet: MessageFns<FeatureSet> = {
) { ) {
writer.uint32(56).int32(featureSet_EnforceNamingStyleToNumber(message.enforceNamingStyle)); writer.uint32(56).int32(featureSet_EnforceNamingStyleToNumber(message.enforceNamingStyle));
} }
if (
message.defaultSymbolVisibility !== undefined &&
message.defaultSymbolVisibility !==
FeatureSet_VisibilityFeature_DefaultSymbolVisibility.DEFAULT_SYMBOL_VISIBILITY_UNKNOWN
) {
writer.uint32(64).int32(
featureSet_VisibilityFeature_DefaultSymbolVisibilityToNumber(message.defaultSymbolVisibility),
);
}
return writer; return writer;
}, },
@ -5105,6 +5282,16 @@ export const FeatureSet: MessageFns<FeatureSet> = {
message.enforceNamingStyle = featureSet_EnforceNamingStyleFromJSON(reader.int32()); message.enforceNamingStyle = featureSet_EnforceNamingStyleFromJSON(reader.int32());
continue; continue;
} }
case 8: {
if (tag !== 64) {
break;
}
message.defaultSymbolVisibility = featureSet_VisibilityFeature_DefaultSymbolVisibilityFromJSON(
reader.int32(),
);
continue;
}
} }
if ((tag & 7) === 4 || tag === 0) { if ((tag & 7) === 4 || tag === 0) {
break; break;
@ -5128,6 +5315,42 @@ export const FeatureSet: MessageFns<FeatureSet> = {
message.jsonFormat = object.jsonFormat ?? FeatureSet_JsonFormat.JSON_FORMAT_UNKNOWN; message.jsonFormat = object.jsonFormat ?? FeatureSet_JsonFormat.JSON_FORMAT_UNKNOWN;
message.enforceNamingStyle = object.enforceNamingStyle ?? message.enforceNamingStyle = object.enforceNamingStyle ??
FeatureSet_EnforceNamingStyle.ENFORCE_NAMING_STYLE_UNKNOWN; FeatureSet_EnforceNamingStyle.ENFORCE_NAMING_STYLE_UNKNOWN;
message.defaultSymbolVisibility = object.defaultSymbolVisibility ??
FeatureSet_VisibilityFeature_DefaultSymbolVisibility.DEFAULT_SYMBOL_VISIBILITY_UNKNOWN;
return message;
},
};
function createBaseFeatureSet_VisibilityFeature(): FeatureSet_VisibilityFeature {
return {};
}
export const FeatureSet_VisibilityFeature: MessageFns<FeatureSet_VisibilityFeature> = {
encode(_: FeatureSet_VisibilityFeature, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): FeatureSet_VisibilityFeature {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseFeatureSet_VisibilityFeature();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skip(tag & 7);
}
return message;
},
create(base?: DeepPartial<FeatureSet_VisibilityFeature>): FeatureSet_VisibilityFeature {
return FeatureSet_VisibilityFeature.fromPartial(base ?? {});
},
fromPartial(_: DeepPartial<FeatureSet_VisibilityFeature>): FeatureSet_VisibilityFeature {
const message = createBaseFeatureSet_VisibilityFeature();
return message; return message;
}, },
}; };