mirror of
https://github.com/usememos/memos.git
synced 2025-12-18 06:41:32 +08:00
Remove work-related terminology by renaming "workspace" to "instance" across the entire application. This change better reflects that Memos is a self-hosted tool suitable for personal and non-work use cases. Breaking Changes: - API endpoints: /api/v1/workspace/* → /api/v1/instance/* - gRPC service: WorkspaceService → InstanceService - Proto types: WorkspaceSetting → InstanceSetting - Frontend translation keys: workspace-section → instance-section Backend Changes: - Renamed proto definitions and regenerated code - Updated all store layer methods and database drivers - Renamed service implementations and API handlers - Updated cache from workspaceSettingCache to instanceSettingCache Frontend Changes: - Renamed service client: workspaceServiceClient → instanceServiceClient - Updated all React components and state management - Refactored stores: workspace.ts → instance.ts - Updated all 32 locale translation files All tests pass and both backend and frontend build successfully. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
157 lines
4.5 KiB
Go
157 lines
4.5 KiB
Go
package v1
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/usememos/memos/internal/util"
|
|
)
|
|
|
|
const (
|
|
InstanceSettingNamePrefix = "instance/settings/"
|
|
UserNamePrefix = "users/"
|
|
MemoNamePrefix = "memos/"
|
|
AttachmentNamePrefix = "attachments/"
|
|
ReactionNamePrefix = "reactions/"
|
|
InboxNamePrefix = "inboxes/"
|
|
IdentityProviderNamePrefix = "identity-providers/"
|
|
ActivityNamePrefix = "activities/"
|
|
WebhookNamePrefix = "webhooks/"
|
|
)
|
|
|
|
// GetNameParentTokens returns the tokens from a resource name.
|
|
func GetNameParentTokens(name string, tokenPrefixes ...string) ([]string, error) {
|
|
parts := strings.Split(name, "/")
|
|
if len(parts) != 2*len(tokenPrefixes) {
|
|
return nil, errors.Errorf("invalid request %q", name)
|
|
}
|
|
|
|
var tokens []string
|
|
for i, tokenPrefix := range tokenPrefixes {
|
|
if fmt.Sprintf("%s/", parts[2*i]) != tokenPrefix {
|
|
return nil, errors.Errorf("invalid prefix %q in request %q", tokenPrefix, name)
|
|
}
|
|
if parts[2*i+1] == "" {
|
|
return nil, errors.Errorf("invalid request %q with empty prefix %q", name, tokenPrefix)
|
|
}
|
|
tokens = append(tokens, parts[2*i+1])
|
|
}
|
|
return tokens, nil
|
|
}
|
|
|
|
func ExtractInstanceSettingKeyFromName(name string) (string, error) {
|
|
const prefix = "instance/settings/"
|
|
if !strings.HasPrefix(name, prefix) {
|
|
return "", errors.Errorf("invalid instance setting name: expected prefix %q, got %q", prefix, name)
|
|
}
|
|
|
|
settingKey := strings.TrimPrefix(name, prefix)
|
|
if settingKey == "" {
|
|
return "", errors.Errorf("invalid instance setting name: empty setting key in %q", name)
|
|
}
|
|
|
|
// Ensure there are no additional path segments
|
|
if strings.Contains(settingKey, "/") {
|
|
return "", errors.Errorf("invalid instance setting name: setting key cannot contain '/' in %q", name)
|
|
}
|
|
|
|
return settingKey, nil
|
|
}
|
|
|
|
// ExtractUserIDFromName returns the uid from a resource name.
|
|
func ExtractUserIDFromName(name string) (int32, error) {
|
|
tokens, err := GetNameParentTokens(name, UserNamePrefix)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
id, err := util.ConvertStringToInt32(tokens[0])
|
|
if err != nil {
|
|
return 0, errors.Errorf("invalid user ID %q", tokens[0])
|
|
}
|
|
return id, nil
|
|
}
|
|
|
|
// extractUserIdentifierFromName extracts the identifier (ID or username) from a user resource name.
|
|
// Supports: "users/101" or "users/steven"
|
|
// Returns the identifier string (e.g., "101" or "steven").
|
|
func extractUserIdentifierFromName(name string) string {
|
|
tokens, err := GetNameParentTokens(name, UserNamePrefix)
|
|
if err != nil || len(tokens) == 0 {
|
|
return ""
|
|
}
|
|
return tokens[0]
|
|
}
|
|
|
|
// ExtractMemoUIDFromName returns the memo UID from a resource name.
|
|
// e.g., "memos/uuid" -> "uuid".
|
|
func ExtractMemoUIDFromName(name string) (string, error) {
|
|
tokens, err := GetNameParentTokens(name, MemoNamePrefix)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
id := tokens[0]
|
|
return id, nil
|
|
}
|
|
|
|
// ExtractAttachmentUIDFromName returns the attachment UID from a resource name.
|
|
func ExtractAttachmentUIDFromName(name string) (string, error) {
|
|
tokens, err := GetNameParentTokens(name, AttachmentNamePrefix)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
id := tokens[0]
|
|
return id, nil
|
|
}
|
|
|
|
// ExtractReactionIDFromName returns the reaction ID from a resource name.
|
|
// e.g., "reactions/123" -> 123.
|
|
func ExtractReactionIDFromName(name string) (int32, error) {
|
|
tokens, err := GetNameParentTokens(name, ReactionNamePrefix)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
id, err := util.ConvertStringToInt32(tokens[0])
|
|
if err != nil {
|
|
return 0, errors.Errorf("invalid reaction ID %q", tokens[0])
|
|
}
|
|
return id, nil
|
|
}
|
|
|
|
// ExtractInboxIDFromName returns the inbox ID from a resource name.
|
|
func ExtractInboxIDFromName(name string) (int32, error) {
|
|
tokens, err := GetNameParentTokens(name, InboxNamePrefix)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
id, err := util.ConvertStringToInt32(tokens[0])
|
|
if err != nil {
|
|
return 0, errors.Errorf("invalid inbox ID %q", tokens[0])
|
|
}
|
|
return id, nil
|
|
}
|
|
|
|
func ExtractIdentityProviderIDFromName(name string) (int32, error) {
|
|
tokens, err := GetNameParentTokens(name, IdentityProviderNamePrefix)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
id, err := util.ConvertStringToInt32(tokens[0])
|
|
if err != nil {
|
|
return 0, errors.Errorf("invalid identity provider ID %q", tokens[0])
|
|
}
|
|
return id, nil
|
|
}
|
|
|
|
func ExtractActivityIDFromName(name string) (int32, error) {
|
|
tokens, err := GetNameParentTokens(name, ActivityNamePrefix)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
id, err := util.ConvertStringToInt32(tokens[0])
|
|
if err != nil {
|
|
return 0, errors.Errorf("invalid activity ID %q", tokens[0])
|
|
}
|
|
return id, nil
|
|
}
|