diff --git a/bin/memos/main.go b/bin/memos/main.go index e7f94ceca..31c176a61 100644 --- a/bin/memos/main.go +++ b/bin/memos/main.go @@ -12,23 +12,17 @@ import ( "github.com/spf13/cobra" "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/server" "github.com/usememos/memos/store" "github.com/usememos/memos/store/db" ) -const ( - greetingBanner = ` -███╗ ███╗███████╗███╗ ███╗ ██████╗ ███████╗ -████╗ ████║██╔════╝████╗ ████║██╔═══██╗██╔════╝ -██╔████╔██║█████╗ ██╔████╔██║██║ ██║███████╗ -██║╚██╔╝██║██╔══╝ ██║╚██╔╝██║██║ ██║╚════██║ -██║ ╚═╝ ██║███████╗██║ ╚═╝ ██║╚██████╔╝███████║ -╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝ -` -) + var ( rootCmd = &cobra.Command{ @@ -146,38 +140,37 @@ func init() { } func printGreetings(profile *profile.Profile) { + fmt.Printf("Memos %s started successfully!\n", profile.Version) + if profile.IsDev() { - println("Development mode is enabled") - println("DSN: ", profile.DSN) + fmt.Fprintf(os.Stderr, "Development mode is enabled\n") + if profile.DSN != "" { + fmt.Fprintf(os.Stderr, "Database: %s\n", profile.DSN) + } } - fmt.Printf(`--- -Server profile -version: %s -data: %s -addr: %s -port: %d -unix-sock: %s -mode: %s -driver: %s ---- -`, profile.Version, profile.Data, profile.Addr, profile.Port, profile.UNIXSock, profile.Mode, profile.Driver) - - print(greetingBanner) + + // Server information + fmt.Printf("Data directory: %s\n", profile.Data) + fmt.Printf("Database driver: %s\n", profile.Driver) + fmt.Printf("Mode: %s\n", profile.Mode) + + // Connection information if len(profile.UNIXSock) == 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 { - 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 { - 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: -👉Website: %s -👉GitHub: %s ---- -`, "https://usememos.com", "https://github.com/usememos/memos") + + fmt.Println() + fmt.Printf("� Documentation: %s\n", "https://usememos.com") + fmt.Printf("💻 Source code: %s\n", "https://github.com/usememos/memos") + fmt.Println("\n✨ Happy note-taking!") } func main() { diff --git a/internal/util/util_test.go b/internal/util/util_test.go index 20b2b8ae1..9dbdd34b3 100644 --- a/internal/util/util_test.go +++ b/internal/util/util_test.go @@ -1,4 +1,4 @@ -package util +package util //nolint:revive // util is an appropriate package name for utility functions import ( "testing" diff --git a/plugin/cron/parser.go b/plugin/cron/parser.go index e1607a116..203e55770 100644 --- a/plugin/cron/parser.go +++ b/plugin/cron/parser.go @@ -420,6 +420,8 @@ func parseDescriptor(descriptor string, loc *time.Location) (Schedule, error) { Dow: all(dow), Location: loc, }, nil + default: + // Continue to check @every prefix below } const every = "@every " diff --git a/plugin/filter/common_converter.go b/plugin/filter/common_converter.go index 5b277d195..60beb825d 100644 --- a/plugin/filter/common_converter.go +++ b/plugin/filter/common_converter.go @@ -45,6 +45,8 @@ func (c *CommonSQLConverter) ConvertExprToSQL(ctx *ConvertContext, expr *exprv1. return c.handleInOperator(ctx, v.CallExpr) case "contains": 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 { return c.handleIdentifier(ctx, v.IdentExpr) @@ -144,9 +146,9 @@ func (c *CommonSQLConverter) handleComparisonOperator(ctx *ConvertContext, callE return c.handlePinnedComparison(ctx, operator, value) case "has_task_list", "has_link", "has_code", "has_incomplete_tasks": 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 { @@ -567,6 +569,8 @@ func (c *CommonSQLConverter) handleBooleanComparison(ctx *ConvertContext, field, jsonPath = "$.property.hasCode" case "has_incomplete_tasks": jsonPath = "$.property.hasIncompleteTasks" + default: + return errors.Errorf("unsupported boolean field: %s", field) } // Special handling for SQLite based on field diff --git a/proto/gen/api/v1/activity_service.pb.go b/proto/gen/api/v1/activity_service.pb.go index e0d13db09..13635d355 100644 --- a/proto/gen/api/v1/activity_service.pb.go +++ b/proto/gen/api/v1/activity_service.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.7 +// protoc-gen-go v1.36.8 // protoc (unknown) // source: api/v1/activity_service.proto diff --git a/proto/gen/api/v1/attachment_service.pb.go b/proto/gen/api/v1/attachment_service.pb.go index 14eca75e3..a551d5e5f 100644 --- a/proto/gen/api/v1/attachment_service.pb.go +++ b/proto/gen/api/v1/attachment_service.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.7 +// protoc-gen-go v1.36.8 // protoc (unknown) // source: api/v1/attachment_service.proto diff --git a/proto/gen/api/v1/auth_service.pb.go b/proto/gen/api/v1/auth_service.pb.go index f4e4f905f..ebd86c793 100644 --- a/proto/gen/api/v1/auth_service.pb.go +++ b/proto/gen/api/v1/auth_service.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.7 +// protoc-gen-go v1.36.8 // protoc (unknown) // source: api/v1/auth_service.proto diff --git a/proto/gen/api/v1/common.pb.go b/proto/gen/api/v1/common.pb.go index 4024a8593..05b7722af 100644 --- a/proto/gen/api/v1/common.pb.go +++ b/proto/gen/api/v1/common.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.7 +// protoc-gen-go v1.36.8 // protoc (unknown) // source: api/v1/common.proto diff --git a/proto/gen/api/v1/idp_service.pb.go b/proto/gen/api/v1/idp_service.pb.go index 630475e74..818430182 100644 --- a/proto/gen/api/v1/idp_service.pb.go +++ b/proto/gen/api/v1/idp_service.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.7 +// protoc-gen-go v1.36.8 // protoc (unknown) // source: api/v1/idp_service.proto diff --git a/proto/gen/api/v1/inbox_service.pb.go b/proto/gen/api/v1/inbox_service.pb.go index 57e9e295f..cb7ebf161 100644 --- a/proto/gen/api/v1/inbox_service.pb.go +++ b/proto/gen/api/v1/inbox_service.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.7 +// protoc-gen-go v1.36.8 // protoc (unknown) // source: api/v1/inbox_service.proto diff --git a/proto/gen/api/v1/markdown_service.pb.go b/proto/gen/api/v1/markdown_service.pb.go index 0c6d654c9..392ae7afc 100644 --- a/proto/gen/api/v1/markdown_service.pb.go +++ b/proto/gen/api/v1/markdown_service.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.7 +// protoc-gen-go v1.36.8 // protoc (unknown) // source: api/v1/markdown_service.proto diff --git a/proto/gen/api/v1/memo_service.pb.go b/proto/gen/api/v1/memo_service.pb.go index eead3f337..667327bea 100644 --- a/proto/gen/api/v1/memo_service.pb.go +++ b/proto/gen/api/v1/memo_service.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.7 +// protoc-gen-go v1.36.8 // protoc (unknown) // source: api/v1/memo_service.proto diff --git a/proto/gen/api/v1/shortcut_service.pb.go b/proto/gen/api/v1/shortcut_service.pb.go index a4bda5bc5..907fdbfef 100644 --- a/proto/gen/api/v1/shortcut_service.pb.go +++ b/proto/gen/api/v1/shortcut_service.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.7 +// protoc-gen-go v1.36.8 // protoc (unknown) // source: api/v1/shortcut_service.proto diff --git a/proto/gen/api/v1/user_service.pb.go b/proto/gen/api/v1/user_service.pb.go index e2114b51d..80291da17 100644 --- a/proto/gen/api/v1/user_service.pb.go +++ b/proto/gen/api/v1/user_service.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.7 +// protoc-gen-go v1.36.8 // protoc (unknown) // source: api/v1/user_service.proto diff --git a/proto/gen/api/v1/workspace_service.pb.go b/proto/gen/api/v1/workspace_service.pb.go index 60f577086..96047c832 100644 --- a/proto/gen/api/v1/workspace_service.pb.go +++ b/proto/gen/api/v1/workspace_service.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.7 +// protoc-gen-go v1.36.8 // protoc (unknown) // source: api/v1/workspace_service.proto diff --git a/proto/gen/openapi.yaml b/proto/gen/openapi.yaml index 10fa5425e..ad86bc3a9 100644 --- a/proto/gen/openapi.yaml +++ b/proto/gen/openapi.yaml @@ -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 @@ -1196,28 +1140,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 + 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 @@ -1246,10 +1180,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 @@ -1259,9 +1190,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: @@ -1298,9 +1227,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 @@ -1527,35 +1454,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: @@ -1641,19 +1556,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: @@ -2208,15 +2117,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: @@ -2251,14 +2156,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 @@ -2275,9 +2176,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 @@ -2303,9 +2202,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: @@ -2367,14 +2264,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: @@ -2385,20 +2278,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 @@ -2409,9 +2296,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 DeleteMemoTagRequest: required: @@ -2421,9 +2306,7 @@ components: properties: parent: type: string - description: |- - Required. The parent, who owns the tags. - Format: memos/{memo}. Use "memos/-" to delete all tags. + description: "Required. The parent, who owns the tags.\r\n Format: memos/{memo}. Use \"memos/-\" to delete all tags." tag: type: string description: Required. The tag name to delete. @@ -2474,9 +2357,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 @@ -2524,9 +2405,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 @@ -2561,21 +2440,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 @@ -2645,10 +2518,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: @@ -2667,9 +2537,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). @@ -2692,9 +2560,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). @@ -2769,9 +2635,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). @@ -2835,9 +2699,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). @@ -2861,9 +2723,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). @@ -2901,9 +2761,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 @@ -2915,9 +2773,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 @@ -2983,9 +2839,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 @@ -3023,9 +2877,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 @@ -3211,21 +3063,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\")." @@ -3252,9 +3097,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. @@ -3285,9 +3128,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: @@ -3301,9 +3142,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: @@ -3316,9 +3155,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. @@ -3361,9 +3198,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: @@ -3461,9 +3296,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' @@ -3477,9 +3310,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 @@ -3531,9 +3362,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 @@ -3556,9 +3385,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 @@ -3571,9 +3398,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 @@ -3603,10 +3428,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: @@ -3636,10 +3458,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 @@ -3664,9 +3483,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: @@ -3714,9 +3531,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. @@ -3739,9 +3554,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. @@ -3757,9 +3570,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: @@ -3772,9 +3583,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. @@ -3793,10 +3602,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 @@ -3855,9 +3661,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. diff --git a/proto/gen/store/activity.pb.go b/proto/gen/store/activity.pb.go index 8fa00de33..1b62a0f55 100644 --- a/proto/gen/store/activity.pb.go +++ b/proto/gen/store/activity.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.7 +// protoc-gen-go v1.36.8 // protoc (unknown) // source: store/activity.proto diff --git a/proto/gen/store/attachment.pb.go b/proto/gen/store/attachment.pb.go index 70de532fa..b2c445c55 100644 --- a/proto/gen/store/attachment.pb.go +++ b/proto/gen/store/attachment.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.7 +// protoc-gen-go v1.36.8 // protoc (unknown) // source: store/attachment.proto diff --git a/proto/gen/store/idp.pb.go b/proto/gen/store/idp.pb.go index 41e6c3013..80e517e6e 100644 --- a/proto/gen/store/idp.pb.go +++ b/proto/gen/store/idp.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.7 +// protoc-gen-go v1.36.8 // protoc (unknown) // source: store/idp.proto diff --git a/proto/gen/store/inbox.pb.go b/proto/gen/store/inbox.pb.go index afa75eb4a..b7e1f49c9 100644 --- a/proto/gen/store/inbox.pb.go +++ b/proto/gen/store/inbox.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.7 +// protoc-gen-go v1.36.8 // protoc (unknown) // source: store/inbox.proto diff --git a/proto/gen/store/memo.pb.go b/proto/gen/store/memo.pb.go index 67793c97f..b748a00f2 100644 --- a/proto/gen/store/memo.pb.go +++ b/proto/gen/store/memo.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.7 +// protoc-gen-go v1.36.8 // protoc (unknown) // source: store/memo.proto diff --git a/proto/gen/store/user_setting.pb.go b/proto/gen/store/user_setting.pb.go index 37bd9b5db..cda71bd47 100644 --- a/proto/gen/store/user_setting.pb.go +++ b/proto/gen/store/user_setting.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.7 +// protoc-gen-go v1.36.8 // protoc (unknown) // source: store/user_setting.proto diff --git a/proto/gen/store/workspace_setting.pb.go b/proto/gen/store/workspace_setting.pb.go index b1c5fcb86..054ef2f35 100644 --- a/proto/gen/store/workspace_setting.pb.go +++ b/proto/gen/store/workspace_setting.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.7 +// protoc-gen-go v1.36.8 // protoc (unknown) // source: store/workspace_setting.proto diff --git a/server/router/api/v1/attachment_service.go b/server/router/api/v1/attachment_service.go index 3ca6799dc..b774680c8 100644 --- a/server/router/api/v1/attachment_service.go +++ b/server/router/api/v1/attachment_service.go @@ -582,8 +582,9 @@ func replaceFilenameWithPathTemplate(path, filename string) string { return fmt.Sprintf("%02d", t.Second()) case "{uuid}": return util.GenUUID() + default: + return s } - return s }) return path } diff --git a/server/router/api/v1/auth_service_client_info_test.go b/server/router/api/v1/auth_service_client_info_test.go index 82429e711..4d87764e6 100644 --- a/server/router/api/v1/auth_service_client_info_test.go +++ b/server/router/api/v1/auth_service_client_info_test.go @@ -162,7 +162,7 @@ func TestClientInfoExamples(t *testing.T) { t.Logf("Device Type: %s", clientInfo.DeviceType) t.Logf("Operating System: %s", clientInfo.Os) t.Logf("Browser: %s", clientInfo.Browser) - t.Logf("---") + t.Log("---") // Ensure all fields are populated if clientInfo.DeviceType == "" { diff --git a/server/router/api/v1/idp_service.go b/server/router/api/v1/idp_service.go index 2c54ca600..384119b84 100644 --- a/server/router/api/v1/idp_service.go +++ b/server/router/api/v1/idp_service.go @@ -82,6 +82,8 @@ func (s *APIV1Service) UpdateIdentityProvider(ctx context.Context, request *v1pb update.IdentifierFilter = &request.IdentityProvider.IdentifierFilter case "config": update.Config = convertIdentityProviderConfigToStore(request.IdentityProvider.Type, request.IdentityProvider.Config) + default: + // Ignore unsupported fields } } diff --git a/server/router/api/v1/user_service.go b/server/router/api/v1/user_service.go index b963880a0..9bdc5b58f 100644 --- a/server/router/api/v1/user_service.go +++ b/server/router/api/v1/user_service.go @@ -405,6 +405,8 @@ func (s *APIV1Service) UpdateUserSetting(ctx context.Context, request *v1pb.Upda updatedGeneral.Theme = incomingGeneral.Theme case "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": updatedWebhook.Title = request.Webhook.DisplayName + default: + // Ignore unsupported fields } } } else { @@ -1143,6 +1147,11 @@ func convertUserSettingFromStore(storeSetting *storepb.UserSetting, userID int32 Webhooks: []*v1pb.UserWebhook{}, }, } + default: + // Default to general setting + setting.Value = &v1pb.UserSetting_GeneralSetting_{ + GeneralSetting: getDefaultUserGeneralSetting(), + } } return setting } @@ -1223,6 +1232,11 @@ func convertUserSettingFromStore(storeSetting *storepb.UserSetting, userID int32 Webhooks: apiWebhooks, }, } + default: + // Default to general setting if unknown key + setting.Value = &v1pb.UserSetting_GeneralSetting_{ + GeneralSetting: getDefaultUserGeneralSetting(), + } } return setting diff --git a/server/router/api/v1/workspace_service.go b/server/router/api/v1/workspace_service.go index fee1e42c0..2279245ca 100644 --- a/server/router/api/v1/workspace_service.go +++ b/server/router/api/v1/workspace_service.go @@ -141,6 +141,8 @@ func convertWorkspaceSettingToStore(setting *v1pb.WorkspaceSetting) *storepb.Wor workspaceSetting.Value = &storepb.WorkspaceSetting_MemoRelatedSetting{ MemoRelatedSetting: convertWorkspaceMemoRelatedSettingToStore(setting.GetMemoRelatedSetting()), } + default: + // Keep the default GeneralSetting value } return workspaceSetting } diff --git a/store/cache/cache_test.go b/store/cache/cache_test.go index 3ba23306d..1be1eca94 100644 --- a/store/cache/cache_test.go +++ b/store/cache/cache_test.go @@ -31,30 +31,30 @@ func TestCacheBasicOperations(t *testing.T) { // Test Delete cache.Delete(ctx, "key1") 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 time.Sleep(150 * time.Millisecond) 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) 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 time.Sleep(100 * time.Millisecond) if _, ok := cache.Get(ctx, "key2"); ok { - t.Errorf("Key 'key2' should have expired") + t.Error("Key 'key2' should have expired") } // Test Clear cache.Set(ctx, "key3", "value3") cache.Clear(ctx) 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 { - 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 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 { - 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 evictedMu.Lock() if evicted["key1"] != "value1" { - t.Errorf("Eviction callback not triggered for manual deletion") + t.Error("Eviction callback not triggered for manual deletion") } evictedMu.Unlock() @@ -203,7 +203,7 @@ func TestEvictionCallback(t *testing.T) { // Verify TTL expiration triggered callback evictedMu.Lock() if evicted["key2"] != "value2" { - t.Errorf("Eviction callback not triggered for TTL expiration") + t.Error("Eviction callback not triggered for TTL expiration") } evictedMu.Unlock() } diff --git a/store/memo.go b/store/memo.go index bdff1f106..9d075339a 100644 --- a/store/memo.go +++ b/store/memo.go @@ -29,8 +29,9 @@ func (v Visibility) String() string { return "PROTECTED" case Private: return "PRIVATE" + default: + return "PRIVATE" } - return "PRIVATE" } type Memo struct { diff --git a/store/migrator.go b/store/migrator.go index c707dbf25..3e7f10f1d 100644 --- a/store/migrator.go +++ b/store/migrator.go @@ -102,6 +102,8 @@ func (s *Store) Migrate(ctx context.Context) error { if err := s.seed(ctx); err != nil { return errors.Wrap(err, "failed to seed") } + default: + // For other modes (like dev), no special migration handling needed } return nil } diff --git a/store/user.go b/store/user.go index a57990c55..b5f1974e0 100644 --- a/store/user.go +++ b/store/user.go @@ -24,8 +24,9 @@ func (e Role) String() string { return "ADMIN" case RoleUser: return "USER" + default: + return "USER" } - return "USER" } const ( diff --git a/web/src/types/proto/google/protobuf/descriptor.ts b/web/src/types/proto/google/protobuf/descriptor.ts index 89514564e..db1d2d4a3 100644 --- a/web/src/types/proto/google/protobuf/descriptor.ts +++ b/web/src/types/proto/google/protobuf/descriptor.ts @@ -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 * files it parses. @@ -155,6 +201,11 @@ export interface FileDescriptorProto { * For Google-internal migration only. Do not use. */ 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. */ messageType: DescriptorProto[]; enumType: EnumDescriptorProto[]; @@ -209,6 +260,8 @@ export interface DescriptorProto { * A given name may only be reserved once. */ reservedName: string[]; + /** Support for `export` and `local` keywords on enums. */ + visibility?: SymbolVisibility | undefined; } export interface DescriptorProto_ExtensionRange { @@ -632,6 +685,8 @@ export interface EnumDescriptorProto { * be reserved once. */ reservedName: string[]; + /** Support for `export` and `local` keywords on enums. */ + visibility?: SymbolVisibility | undefined; } /** @@ -1594,6 +1649,7 @@ export interface FeatureSet { messageEncoding?: FeatureSet_MessageEncoding | undefined; jsonFormat?: FeatureSet_JsonFormat | undefined; enforceNamingStyle?: FeatureSet_EnforceNamingStyle | undefined; + defaultSymbolVisibility?: FeatureSet_VisibilityFeature_DefaultSymbolVisibility | undefined; } 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 * messages are generated from FeatureSet extensions and can be used to seed @@ -2195,6 +2317,7 @@ function createBaseFileDescriptorProto(): FileDescriptorProto { dependency: [], publicDependency: [], weakDependency: [], + optionDependency: [], messageType: [], enumType: [], service: [], @@ -2227,6 +2350,9 @@ export const FileDescriptorProto: MessageFns = { writer.int32(v); } writer.join(); + for (const v of message.optionDependency) { + writer.uint32(122).string(v!); + } for (const v of message.messageType) { DescriptorProto.encode(v!, writer.uint32(34).fork()).join(); } @@ -2321,6 +2447,14 @@ export const FileDescriptorProto: MessageFns = { break; } + case 15: { + if (tag !== 122) { + break; + } + + message.optionDependency.push(reader.string()); + continue; + } case 4: { if (tag !== 34) { break; @@ -2404,6 +2538,7 @@ export const FileDescriptorProto: MessageFns = { message.dependency = object.dependency?.map((e) => e) || []; message.publicDependency = object.publicDependency?.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.enumType = object.enumType?.map((e) => EnumDescriptorProto.fromPartial(e)) || []; message.service = object.service?.map((e) => ServiceDescriptorProto.fromPartial(e)) || []; @@ -2432,6 +2567,7 @@ function createBaseDescriptorProto(): DescriptorProto { options: undefined, reservedRange: [], reservedName: [], + visibility: SymbolVisibility.VISIBILITY_UNSET, }; } @@ -2467,6 +2603,9 @@ export const DescriptorProto: MessageFns = { for (const v of message.reservedName) { writer.uint32(82).string(v!); } + if (message.visibility !== undefined && message.visibility !== SymbolVisibility.VISIBILITY_UNSET) { + writer.uint32(88).int32(symbolVisibilityToNumber(message.visibility)); + } return writer; }, @@ -2557,6 +2696,14 @@ export const DescriptorProto: MessageFns = { message.reservedName.push(reader.string()); continue; } + case 11: { + if (tag !== 88) { + break; + } + + message.visibility = symbolVisibilityFromJSON(reader.int32()); + continue; + } } if ((tag & 7) === 4 || tag === 0) { break; @@ -2583,6 +2730,7 @@ export const DescriptorProto: MessageFns = { : undefined; message.reservedRange = object.reservedRange?.map((e) => DescriptorProto_ReservedRange.fromPartial(e)) || []; message.reservedName = object.reservedName?.map((e) => e) || []; + message.visibility = object.visibility ?? SymbolVisibility.VISIBILITY_UNSET; return message; }, }; @@ -3143,7 +3291,14 @@ export const OneofDescriptorProto: MessageFns = { }; 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 = { @@ -3163,6 +3318,9 @@ export const EnumDescriptorProto: MessageFns = { for (const v of message.reservedName) { writer.uint32(42).string(v!); } + if (message.visibility !== undefined && message.visibility !== SymbolVisibility.VISIBILITY_UNSET) { + writer.uint32(48).int32(symbolVisibilityToNumber(message.visibility)); + } return writer; }, @@ -3213,6 +3371,14 @@ export const EnumDescriptorProto: MessageFns = { message.reservedName.push(reader.string()); continue; } + case 6: { + if (tag !== 48) { + break; + } + + message.visibility = symbolVisibilityFromJSON(reader.int32()); + continue; + } } if ((tag & 7) === 4 || tag === 0) { break; @@ -3235,6 +3401,7 @@ export const EnumDescriptorProto: MessageFns = { message.reservedRange = object.reservedRange?.map((e) => EnumDescriptorProto_EnumReservedRange.fromPartial(e)) || []; message.reservedName = object.reservedName?.map((e) => e) || []; + message.visibility = object.visibility ?? SymbolVisibility.VISIBILITY_UNSET; return message; }, }; @@ -4999,6 +5166,7 @@ function createBaseFeatureSet(): FeatureSet { messageEncoding: FeatureSet_MessageEncoding.MESSAGE_ENCODING_UNKNOWN, jsonFormat: FeatureSet_JsonFormat.JSON_FORMAT_UNKNOWN, enforceNamingStyle: FeatureSet_EnforceNamingStyle.ENFORCE_NAMING_STYLE_UNKNOWN, + defaultSymbolVisibility: FeatureSet_VisibilityFeature_DefaultSymbolVisibility.DEFAULT_SYMBOL_VISIBILITY_UNKNOWN, }; } @@ -5039,6 +5207,15 @@ export const FeatureSet: MessageFns = { ) { 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; }, @@ -5105,6 +5282,16 @@ export const FeatureSet: MessageFns = { message.enforceNamingStyle = featureSet_EnforceNamingStyleFromJSON(reader.int32()); continue; } + case 8: { + if (tag !== 64) { + break; + } + + message.defaultSymbolVisibility = featureSet_VisibilityFeature_DefaultSymbolVisibilityFromJSON( + reader.int32(), + ); + continue; + } } if ((tag & 7) === 4 || tag === 0) { break; @@ -5128,6 +5315,42 @@ export const FeatureSet: MessageFns = { message.jsonFormat = object.jsonFormat ?? FeatureSet_JsonFormat.JSON_FORMAT_UNKNOWN; message.enforceNamingStyle = object.enforceNamingStyle ?? 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 = { + 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 { + return FeatureSet_VisibilityFeature.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): FeatureSet_VisibilityFeature { + const message = createBaseFeatureSet_VisibilityFeature(); return message; }, };