diff --git a/cmd/memos/main.go b/cmd/memos/main.go index 48dad202d..1c2ab61c5 100644 --- a/cmd/memos/main.go +++ b/cmd/memos/main.go @@ -25,7 +25,7 @@ var ( Short: `An open source, lightweight note-taking service. Easily capture and share your great thoughts.`, Run: func(_ *cobra.Command, _ []string) { instanceProfile := &profile.Profile{ - Mode: viper.GetString("mode"), + Demo: viper.GetBool("demo"), Addr: viper.GetString("addr"), Port: viper.GetInt("port"), UNIXSock: viper.GetString("unix-sock"), @@ -33,10 +33,12 @@ var ( Driver: viper.GetString("driver"), DSN: viper.GetString("dsn"), InstanceURL: viper.GetString("instance-url"), - Version: version.GetCurrentVersion(viper.GetString("mode")), } + instanceProfile.Version = version.GetCurrentVersion() + if err := instanceProfile.Validate(); err != nil { - panic(err) + slog.Error("failed to validate profile", "error", err) + os.Exit(1) } ctx, cancel := context.WithCancel(context.Background()) @@ -44,21 +46,21 @@ var ( if err != nil { cancel() slog.Error("failed to create db driver", "error", err) - return + os.Exit(1) } storeInstance := store.New(dbDriver, instanceProfile) if err := storeInstance.Migrate(ctx); err != nil { cancel() slog.Error("failed to migrate", "error", err) - return + os.Exit(1) } s, err := server.NewServer(ctx, instanceProfile, storeInstance) if err != nil { cancel() slog.Error("failed to create server", "error", err) - return + os.Exit(1) } c := make(chan os.Signal, 1) @@ -71,6 +73,7 @@ var ( if err != http.ErrServerClosed { slog.Error("failed to start server", "error", err) cancel() + os.Exit(1) } } @@ -89,11 +92,11 @@ var ( ) func init() { - viper.SetDefault("mode", "dev") + viper.SetDefault("demo", false) viper.SetDefault("driver", "sqlite") viper.SetDefault("port", 8081) - rootCmd.PersistentFlags().String("mode", "dev", `mode of server, can be "prod" or "dev" or "demo"`) + rootCmd.PersistentFlags().Bool("demo", false, "enable demo mode") rootCmd.PersistentFlags().String("addr", "", "address of server") rootCmd.PersistentFlags().Int("port", 8081, "port of server") rootCmd.PersistentFlags().String("unix-sock", "", "path to the unix socket, overrides --addr and --port") @@ -102,7 +105,7 @@ func init() { rootCmd.PersistentFlags().String("dsn", "", "database source name(aka. DSN)") rootCmd.PersistentFlags().String("instance-url", "", "the url of your memos instance") - if err := viper.BindPFlag("mode", rootCmd.PersistentFlags().Lookup("mode")); err != nil { + if err := viper.BindPFlag("demo", rootCmd.PersistentFlags().Lookup("demo")); err != nil { panic(err) } if err := viper.BindPFlag("addr", rootCmd.PersistentFlags().Lookup("addr")); err != nil { @@ -137,7 +140,7 @@ func init() { func printGreetings(profile *profile.Profile) { fmt.Printf("Memos %s started successfully!\n", profile.Version) - if profile.IsDev() { + if profile.Demo { fmt.Fprint(os.Stderr, "Development mode is enabled\n") if profile.DSN != "" { fmt.Fprintf(os.Stderr, "Database: %s\n", profile.DSN) @@ -147,7 +150,6 @@ func printGreetings(profile *profile.Profile) { // 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 { @@ -170,6 +172,6 @@ func printGreetings(profile *profile.Profile) { func main() { if err := rootCmd.Execute(); err != nil { - panic(err) + os.Exit(1) } } diff --git a/internal/profile/profile.go b/internal/profile/profile.go index 8d551d669..b7e3c582f 100644 --- a/internal/profile/profile.go +++ b/internal/profile/profile.go @@ -13,8 +13,8 @@ import ( // Profile is the configuration to start main server. type Profile struct { - // Mode can be "prod" or "dev" or "demo" - Mode string + // Demo indicates if the server is in demo mode + Demo bool // Addr is the binding address for server Addr string // Port is the binding port for server @@ -34,10 +34,6 @@ type Profile struct { InstanceURL string } -func (p *Profile) IsDev() bool { - return p.Mode != "prod" -} - func checkDataDir(dataDir string) (string, error) { // Convert to absolute path if relative path is supplied. if !filepath.IsAbs(dataDir) { @@ -58,11 +54,7 @@ func checkDataDir(dataDir string) (string, error) { } func (p *Profile) Validate() error { - if p.Mode != "demo" && p.Mode != "dev" && p.Mode != "prod" { - p.Mode = "demo" - } - - if p.Mode == "prod" && p.Data == "" { + if !p.Demo && p.Data == "" { if runtime.GOOS == "windows" { p.Data = filepath.Join(os.Getenv("ProgramData"), "memos") if _, err := os.Stat(p.Data); os.IsNotExist(err) { @@ -84,7 +76,11 @@ func (p *Profile) Validate() error { p.Data = dataDir if p.Driver == "sqlite" && p.DSN == "" { - dbFile := fmt.Sprintf("memos_%s.db", p.Mode) + mode := "prod" + if p.Demo { + mode = "demo" + } + dbFile := fmt.Sprintf("memos_%s.db", mode) p.DSN = filepath.Join(dataDir, dbFile) } diff --git a/internal/version/version.go b/internal/version/version.go index cae194088..af1bbc2ec 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -11,13 +11,7 @@ import ( // Semantic versioning: https://semver.org/ var Version = "0.26.0" -// DevVersion is the service current development version. -var DevVersion = "0.26.0" - -func GetCurrentVersion(mode string) string { - if mode == "dev" || mode == "demo" { - return DevVersion - } +func GetCurrentVersion() string { return Version } diff --git a/proto/api/v1/instance_service.proto b/proto/api/v1/instance_service.proto index ebe9ed2f1..ad0ff146c 100644 --- a/proto/api/v1/instance_service.proto +++ b/proto/api/v1/instance_service.proto @@ -41,8 +41,8 @@ message InstanceProfile { // Version is the current version of instance. string version = 2; - // Mode is the instance mode (e.g. "prod", "dev" or "demo"). - string mode = 3; + // Demo indicates if the instance is in demo mode. + bool demo = 3; // Instance URL is the URL of the instance. string instance_url = 6; diff --git a/proto/gen/api/v1/instance_service.pb.go b/proto/gen/api/v1/instance_service.pb.go index c98eb3b88..bcb03d5b8 100644 --- a/proto/gen/api/v1/instance_service.pb.go +++ b/proto/gen/api/v1/instance_service.pb.go @@ -143,8 +143,8 @@ type InstanceProfile struct { Owner string `protobuf:"bytes,1,opt,name=owner,proto3" json:"owner,omitempty"` // Version is the current version of instance. Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` - // Mode is the instance mode (e.g. "prod", "dev" or "demo"). - Mode string `protobuf:"bytes,3,opt,name=mode,proto3" json:"mode,omitempty"` + // Demo indicates if the instance is in demo mode. + Demo bool `protobuf:"varint,3,opt,name=demo,proto3" json:"demo,omitempty"` // Instance URL is the URL of the instance. InstanceUrl string `protobuf:"bytes,6,opt,name=instance_url,json=instanceUrl,proto3" json:"instance_url,omitempty"` unknownFields protoimpl.UnknownFields @@ -195,11 +195,11 @@ func (x *InstanceProfile) GetVersion() string { return "" } -func (x *InstanceProfile) GetMode() string { +func (x *InstanceProfile) GetDemo() bool { if x != nil { - return x.Mode + return x.Demo } - return "" + return false } func (x *InstanceProfile) GetInstanceUrl() string { @@ -879,7 +879,7 @@ const file_api_v1_instance_service_proto_rawDesc = "" + "\x0fInstanceProfile\x12\x14\n" + "\x05owner\x18\x01 \x01(\tR\x05owner\x12\x18\n" + "\aversion\x18\x02 \x01(\tR\aversion\x12\x12\n" + - "\x04mode\x18\x03 \x01(\tR\x04mode\x12!\n" + + "\x04demo\x18\x03 \x01(\bR\x04demo\x12!\n" + "\finstance_url\x18\x06 \x01(\tR\vinstanceUrl\"\x1b\n" + "\x19GetInstanceProfileRequest\"\x99\x0f\n" + "\x0fInstanceSetting\x12\x17\n" + diff --git a/proto/gen/openapi.yaml b/proto/gen/openapi.yaml index 10b070ef4..a561caafb 100644 --- a/proto/gen/openapi.yaml +++ b/proto/gen/openapi.yaml @@ -2140,9 +2140,9 @@ components: version: type: string description: Version is the current version of instance. - mode: - type: string - description: Mode is the instance mode (e.g. "prod", "dev" or "demo"). + demo: + type: boolean + description: Demo indicates if the instance is in demo mode. instanceUrl: type: string description: Instance URL is the URL of the instance. diff --git a/server/router/api/v1/instance_service.go b/server/router/api/v1/instance_service.go index 049f9f3b6..b83342ede 100644 --- a/server/router/api/v1/instance_service.go +++ b/server/router/api/v1/instance_service.go @@ -17,7 +17,7 @@ import ( func (s *APIV1Service) GetInstanceProfile(ctx context.Context, _ *v1pb.GetInstanceProfileRequest) (*v1pb.InstanceProfile, error) { instanceProfile := &v1pb.InstanceProfile{ Version: s.Profile.Version, - Mode: s.Profile.Mode, + Demo: s.Profile.Demo, InstanceUrl: s.Profile.InstanceURL, } owner, err := s.GetInstanceOwner(ctx) diff --git a/server/router/api/v1/v1.go b/server/router/api/v1/v1.go index 834f054fb..694b5bbc3 100644 --- a/server/router/api/v1/v1.go +++ b/server/router/api/v1/v1.go @@ -126,7 +126,7 @@ func (s *APIV1Service) RegisterGateway(ctx context.Context, echoServer *echo.Ech gwGroup.Any("/file/*", handler) // Connect handlers for browser clients (replaces grpc-web). - logStacktraces := s.Profile.IsDev() + logStacktraces := s.Profile.Demo connectInterceptors := connect.WithInterceptors( NewMetadataInterceptor(), // Convert HTTP headers to gRPC metadata first NewLoggingInterceptor(logStacktraces), diff --git a/server/server.go b/server/server.go index a1fbc1ffe..af09c4bcd 100644 --- a/server/server.go +++ b/server/server.go @@ -52,7 +52,7 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store } secret := "usememos" - if profile.Mode == "prod" { + if !profile.Demo { secret = instanceBasicSetting.SecretKey } s.Secret = secret diff --git a/store/migrator.go b/store/migrator.go index 1a8bb5d39..20878f903 100644 --- a/store/migrator.go +++ b/store/migrator.go @@ -57,10 +57,6 @@ const ( // defaultSchemaVersion is used when schema version is empty or not set. // This handles edge cases for old installations without version tracking. defaultSchemaVersion = "0.0.0" - - // Mode constants for profile mode. - modeProd = "prod" - modeDemo = "demo" ) // getSchemaVersionOrDefault returns the schema version or default if empty. @@ -110,38 +106,36 @@ func (s *Store) Migrate(ctx context.Context) error { return errors.Wrap(err, "failed to pre-migrate") } - switch s.profile.Mode { - case modeProd: - instanceBasicSetting, err := s.GetInstanceBasicSetting(ctx) - if err != nil { - return errors.Wrap(err, "failed to get instance basic setting") + instanceBasicSetting, err := s.GetInstanceBasicSetting(ctx) + if err != nil { + return errors.Wrap(err, "failed to get instance basic setting") + } + currentSchemaVersion, err := s.GetCurrentSchemaVersion() + if err != nil { + return errors.Wrap(err, "failed to get current schema version") + } + // Check for downgrade (but skip if schema version is empty - that means fresh/old installation) + if !isVersionEmpty(instanceBasicSetting.SchemaVersion) && version.IsVersionGreaterThan(instanceBasicSetting.SchemaVersion, currentSchemaVersion) { + slog.Error("cannot downgrade schema version", + slog.String("databaseVersion", instanceBasicSetting.SchemaVersion), + slog.String("currentVersion", currentSchemaVersion), + ) + return errors.Errorf("cannot downgrade schema version from %s to %s", instanceBasicSetting.SchemaVersion, currentSchemaVersion) + } + // Apply migrations if needed (including when schema version is empty) + if isVersionEmpty(instanceBasicSetting.SchemaVersion) || version.IsVersionGreaterThan(currentSchemaVersion, instanceBasicSetting.SchemaVersion) { + if err := s.applyMigrations(ctx, instanceBasicSetting.SchemaVersion, currentSchemaVersion); err != nil { + return errors.Wrap(err, "failed to apply migrations") } - currentSchemaVersion, err := s.GetCurrentSchemaVersion() - if err != nil { - return errors.Wrap(err, "failed to get current schema version") - } - // Check for downgrade (but skip if schema version is empty - that means fresh/old installation) - if !isVersionEmpty(instanceBasicSetting.SchemaVersion) && version.IsVersionGreaterThan(instanceBasicSetting.SchemaVersion, currentSchemaVersion) { - slog.Error("cannot downgrade schema version", - slog.String("databaseVersion", instanceBasicSetting.SchemaVersion), - slog.String("currentVersion", currentSchemaVersion), - ) - return errors.Errorf("cannot downgrade schema version from %s to %s", instanceBasicSetting.SchemaVersion, currentSchemaVersion) - } - // Apply migrations if needed (including when schema version is empty) - if isVersionEmpty(instanceBasicSetting.SchemaVersion) || version.IsVersionGreaterThan(currentSchemaVersion, instanceBasicSetting.SchemaVersion) { - if err := s.applyMigrations(ctx, instanceBasicSetting.SchemaVersion, currentSchemaVersion); err != nil { - return errors.Wrap(err, "failed to apply migrations") - } - } - case modeDemo: + } + + if s.profile.Demo { // In demo mode, we should seed the database. 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 } @@ -250,19 +244,16 @@ func (s *Store) preMigrate(ctx context.Context) error { return errors.Wrap(err, "failed to get current schema version") } slog.Info("database initialized successfully", slog.String("schemaVersion", schemaVersion)) - if err := s.updateCurrentSchemaVersion(ctx, schemaVersion); err != nil { - return errors.Wrap(err, "failed to update current schema version") + if err := s.updateCurrentSchemaVersion(ctx, schemaVersion); err != nil { + return errors.Wrap(err, "failed to update current schema version") + } + } + + if err := s.checkMinimumUpgradeVersion(ctx); err != nil { + return err // Error message is already descriptive, don't wrap it + } + return nil } - } - - if s.profile.Mode == modeProd { - if err := s.checkMinimumUpgradeVersion(ctx); err != nil { - return err // Error message is already descriptive, don't wrap it - } - } - return nil -} - func (s *Store) getMigrationBasePath() string { return fmt.Sprintf("migration/%s/", s.profile.Driver) } @@ -308,7 +299,7 @@ func (s *Store) seed(ctx context.Context) error { } func (s *Store) GetCurrentSchemaVersion() (string, error) { - currentVersion := version.GetCurrentVersion(s.profile.Mode) + currentVersion := version.GetCurrentVersion() minorVersion := version.GetMinorVersion(currentVersion) filePaths, err := fs.Glob(migrationFS, fmt.Sprintf("%s%s/*.sql", s.getMigrationBasePath(), minorVersion)) if err != nil { diff --git a/web/src/components/PasswordSignInForm.tsx b/web/src/components/PasswordSignInForm.tsx index a148fb3af..127636f17 100644 --- a/web/src/components/PasswordSignInForm.tsx +++ b/web/src/components/PasswordSignInForm.tsx @@ -19,8 +19,8 @@ function PasswordSignInForm() { const { profile } = useInstance(); const { initialize } = useAuth(); const actionBtnLoadingState = useLoading(false); - const [username, setUsername] = useState(profile.mode === "demo" ? "demo" : ""); - const [password, setPassword] = useState(profile.mode === "demo" ? "secret" : ""); + const [username, setUsername] = useState(profile.demo ? "demo" : ""); + const [password, setPassword] = useState(profile.demo ? "secret" : ""); const handleUsernameInputChanged = (e: React.ChangeEvent) => { const text = e.target.value as string; diff --git a/web/src/components/Settings/InstanceSection.tsx b/web/src/components/Settings/InstanceSection.tsx index f136ce537..959564012 100644 --- a/web/src/components/Settings/InstanceSection.tsx +++ b/web/src/components/Settings/InstanceSection.tsx @@ -112,7 +112,7 @@ const InstanceSection = () => { updatePartialSetting({ disallowUserRegistration: checked })} /> @@ -120,7 +120,7 @@ const InstanceSection = () => { updatePartialSetting({ disallowPasswordAuth: checked })} /> diff --git a/web/src/types/proto/api/v1/instance_service_pb.ts b/web/src/types/proto/api/v1/instance_service_pb.ts index e860a2356..892976953 100644 --- a/web/src/types/proto/api/v1/instance_service_pb.ts +++ b/web/src/types/proto/api/v1/instance_service_pb.ts @@ -16,7 +16,7 @@ import type { Message } from "@bufbuild/protobuf"; * Describes the file api/v1/instance_service.proto. */ export const file_api_v1_instance_service: GenFile = /*@__PURE__*/ - fileDesc("Ch1hcGkvdjEvaW5zdGFuY2Vfc2VydmljZS5wcm90bxIMbWVtb3MuYXBpLnYxIlUKD0luc3RhbmNlUHJvZmlsZRINCgVvd25lchgBIAEoCRIPCgd2ZXJzaW9uGAIgASgJEgwKBG1vZGUYAyABKAkSFAoMaW5zdGFuY2VfdXJsGAYgASgJIhsKGUdldEluc3RhbmNlUHJvZmlsZVJlcXVlc3QiswsKD0luc3RhbmNlU2V0dGluZxIRCgRuYW1lGAEgASgJQgPgQQgSRwoPZ2VuZXJhbF9zZXR0aW5nGAIgASgLMiwubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5HZW5lcmFsU2V0dGluZ0gAEkcKD3N0b3JhZ2Vfc2V0dGluZxgDIAEoCzIsLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuU3RvcmFnZVNldHRpbmdIABJQChRtZW1vX3JlbGF0ZWRfc2V0dGluZxgEIAEoCzIwLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuTWVtb1JlbGF0ZWRTZXR0aW5nSAAahwMKDkdlbmVyYWxTZXR0aW5nEiIKGmRpc2FsbG93X3VzZXJfcmVnaXN0cmF0aW9uGAIgASgIEh4KFmRpc2FsbG93X3Bhc3N3b3JkX2F1dGgYAyABKAgSGQoRYWRkaXRpb25hbF9zY3JpcHQYBCABKAkSGAoQYWRkaXRpb25hbF9zdHlsZRgFIAEoCRJSCg5jdXN0b21fcHJvZmlsZRgGIAEoCzI6Lm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuR2VuZXJhbFNldHRpbmcuQ3VzdG9tUHJvZmlsZRIdChV3ZWVrX3N0YXJ0X2RheV9vZmZzZXQYByABKAUSIAoYZGlzYWxsb3dfY2hhbmdlX3VzZXJuYW1lGAggASgIEiAKGGRpc2FsbG93X2NoYW5nZV9uaWNrbmFtZRgJIAEoCBpFCg1DdXN0b21Qcm9maWxlEg0KBXRpdGxlGAEgASgJEhMKC2Rlc2NyaXB0aW9uGAIgASgJEhAKCGxvZ29fdXJsGAMgASgJGroDCg5TdG9yYWdlU2V0dGluZxJOCgxzdG9yYWdlX3R5cGUYASABKA4yOC5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLlN0b3JhZ2VTZXR0aW5nLlN0b3JhZ2VUeXBlEhkKEWZpbGVwYXRoX3RlbXBsYXRlGAIgASgJEhwKFHVwbG9hZF9zaXplX2xpbWl0X21iGAMgASgDEkgKCXMzX2NvbmZpZxgEIAEoCzI1Lm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuU3RvcmFnZVNldHRpbmcuUzNDb25maWcahgEKCFMzQ29uZmlnEhUKDWFjY2Vzc19rZXlfaWQYASABKAkSGQoRYWNjZXNzX2tleV9zZWNyZXQYAiABKAkSEAoIZW5kcG9pbnQYAyABKAkSDgoGcmVnaW9uGAQgASgJEg4KBmJ1Y2tldBgFIAEoCRIWCg51c2VfcGF0aF9zdHlsZRgGIAEoCCJMCgtTdG9yYWdlVHlwZRIcChhTVE9SQUdFX1RZUEVfVU5TUEVDSUZJRUQQABIMCghEQVRBQkFTRRABEgkKBUxPQ0FMEAISBgoCUzMQAxqtAQoSTWVtb1JlbGF0ZWRTZXR0aW5nEiIKGmRpc2FsbG93X3B1YmxpY192aXNpYmlsaXR5GAEgASgIEiAKGGRpc3BsYXlfd2l0aF91cGRhdGVfdGltZRgCIAEoCBIcChRjb250ZW50X2xlbmd0aF9saW1pdBgDIAEoBRIgChhlbmFibGVfZG91YmxlX2NsaWNrX2VkaXQYBCABKAgSEQoJcmVhY3Rpb25zGAcgAygJIkYKA0tleRITCg9LRVlfVU5TUEVDSUZJRUQQABILCgdHRU5FUkFMEAESCwoHU1RPUkFHRRACEhAKDE1FTU9fUkVMQVRFRBADOmHqQV4KHG1lbW9zLmFwaS52MS9JbnN0YW5jZVNldHRpbmcSG2luc3RhbmNlL3NldHRpbmdzL3tzZXR0aW5nfSoQaW5zdGFuY2VTZXR0aW5nczIPaW5zdGFuY2VTZXR0aW5nQgcKBXZhbHVlIk8KGUdldEluc3RhbmNlU2V0dGluZ1JlcXVlc3QSMgoEbmFtZRgBIAEoCUIk4EEC+kEeChxtZW1vcy5hcGkudjEvSW5zdGFuY2VTZXR0aW5nIokBChxVcGRhdGVJbnN0YW5jZVNldHRpbmdSZXF1ZXN0EjMKB3NldHRpbmcYASABKAsyHS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nQgPgQQISNAoLdXBkYXRlX21hc2sYAiABKAsyGi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrQgPgQQEy2wMKD0luc3RhbmNlU2VydmljZRJ+ChJHZXRJbnN0YW5jZVByb2ZpbGUSJy5tZW1vcy5hcGkudjEuR2V0SW5zdGFuY2VQcm9maWxlUmVxdWVzdBodLm1lbW9zLmFwaS52MS5JbnN0YW5jZVByb2ZpbGUiIILT5JMCGhIYL2FwaS92MS9pbnN0YW5jZS9wcm9maWxlEo8BChJHZXRJbnN0YW5jZVNldHRpbmcSJy5tZW1vcy5hcGkudjEuR2V0SW5zdGFuY2VTZXR0aW5nUmVxdWVzdBodLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmciMdpBBG5hbWWC0+STAiQSIi9hcGkvdjEve25hbWU9aW5zdGFuY2Uvc2V0dGluZ3MvKn0StQEKFVVwZGF0ZUluc3RhbmNlU2V0dGluZxIqLm1lbW9zLmFwaS52MS5VcGRhdGVJbnN0YW5jZVNldHRpbmdSZXF1ZXN0Gh0ubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZyJR2kETc2V0dGluZyx1cGRhdGVfbWFza4LT5JMCNToHc2V0dGluZzIqL2FwaS92MS97c2V0dGluZy5uYW1lPWluc3RhbmNlL3NldHRpbmdzLyp9QqwBChBjb20ubWVtb3MuYXBpLnYxQhRJbnN0YW5jZVNlcnZpY2VQcm90b1ABWjBnaXRodWIuY29tL3VzZW1lbW9zL21lbW9zL3Byb3RvL2dlbi9hcGkvdjE7YXBpdjGiAgNNQViqAgxNZW1vcy5BcGkuVjHKAgxNZW1vc1xBcGlcVjHiAhhNZW1vc1xBcGlcVjFcR1BCTWV0YWRhdGHqAg5NZW1vczo6QXBpOjpWMWIGcHJvdG8z", [file_google_api_annotations, file_google_api_client, file_google_api_field_behavior, file_google_api_resource, file_google_protobuf_field_mask]); + fileDesc("Ch1hcGkvdjEvaW5zdGFuY2Vfc2VydmljZS5wcm90bxIMbWVtb3MuYXBpLnYxIlUKD0luc3RhbmNlUHJvZmlsZRINCgVvd25lchgBIAEoCRIPCgd2ZXJzaW9uGAIgASgJEgwKBGRlbW8YAyABKAgSFAoMaW5zdGFuY2VfdXJsGAYgASgJIhsKGUdldEluc3RhbmNlUHJvZmlsZVJlcXVlc3QiswsKD0luc3RhbmNlU2V0dGluZxIRCgRuYW1lGAEgASgJQgPgQQgSRwoPZ2VuZXJhbF9zZXR0aW5nGAIgASgLMiwubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5HZW5lcmFsU2V0dGluZ0gAEkcKD3N0b3JhZ2Vfc2V0dGluZxgDIAEoCzIsLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuU3RvcmFnZVNldHRpbmdIABJQChRtZW1vX3JlbGF0ZWRfc2V0dGluZxgEIAEoCzIwLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuTWVtb1JlbGF0ZWRTZXR0aW5nSAAahwMKDkdlbmVyYWxTZXR0aW5nEiIKGmRpc2FsbG93X3VzZXJfcmVnaXN0cmF0aW9uGAIgASgIEh4KFmRpc2FsbG93X3Bhc3N3b3JkX2F1dGgYAyABKAgSGQoRYWRkaXRpb25hbF9zY3JpcHQYBCABKAkSGAoQYWRkaXRpb25hbF9zdHlsZRgFIAEoCRJSCg5jdXN0b21fcHJvZmlsZRgGIAEoCzI6Lm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuR2VuZXJhbFNldHRpbmcuQ3VzdG9tUHJvZmlsZRIdChV3ZWVrX3N0YXJ0X2RheV9vZmZzZXQYByABKAUSIAoYZGlzYWxsb3dfY2hhbmdlX3VzZXJuYW1lGAggASgIEiAKGGRpc2FsbG93X2NoYW5nZV9uaWNrbmFtZRgJIAEoCBpFCg1DdXN0b21Qcm9maWxlEg0KBXRpdGxlGAEgASgJEhMKC2Rlc2NyaXB0aW9uGAIgASgJEhAKCGxvZ29fdXJsGAMgASgJGroDCg5TdG9yYWdlU2V0dGluZxJOCgxzdG9yYWdlX3R5cGUYASABKA4yOC5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLlN0b3JhZ2VTZXR0aW5nLlN0b3JhZ2VUeXBlEhkKEWZpbGVwYXRoX3RlbXBsYXRlGAIgASgJEhwKFHVwbG9hZF9zaXplX2xpbWl0X21iGAMgASgDEkgKCXMzX2NvbmZpZxgEIAEoCzI1Lm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuU3RvcmFnZVNldHRpbmcuUzNDb25maWcahgEKCFMzQ29uZmlnEhUKDWFjY2Vzc19rZXlfaWQYASABKAkSGQoRYWNjZXNzX2tleV9zZWNyZXQYAiABKAkSEAoIZW5kcG9pbnQYAyABKAkSDgoGcmVnaW9uGAQgASgJEg4KBmJ1Y2tldBgFIAEoCRIWCg51c2VfcGF0aF9zdHlsZRgGIAEoCCJMCgtTdG9yYWdlVHlwZRIcChhTVE9SQUdFX1RZUEVfVU5TUEVDSUZJRUQQABIMCghEQVRBQkFTRRABEgkKBUxPQ0FMEAISBgoCUzMQAxqtAQoSTWVtb1JlbGF0ZWRTZXR0aW5nEiIKGmRpc2FsbG93X3B1YmxpY192aXNpYmlsaXR5GAEgASgIEiAKGGRpc3BsYXlfd2l0aF91cGRhdGVfdGltZRgCIAEoCBIcChRjb250ZW50X2xlbmd0aF9saW1pdBgDIAEoBRIgChhlbmFibGVfZG91YmxlX2NsaWNrX2VkaXQYBCABKAgSEQoJcmVhY3Rpb25zGAcgAygJIkYKA0tleRITCg9LRVlfVU5TUEVDSUZJRUQQABILCgdHRU5FUkFMEAESCwoHU1RPUkFHRRACEhAKDE1FTU9fUkVMQVRFRBADOmHqQV4KHG1lbW9zLmFwaS52MS9JbnN0YW5jZVNldHRpbmcSG2luc3RhbmNlL3NldHRpbmdzL3tzZXR0aW5nfSoQaW5zdGFuY2VTZXR0aW5nczIPaW5zdGFuY2VTZXR0aW5nQgcKBXZhbHVlIk8KGUdldEluc3RhbmNlU2V0dGluZ1JlcXVlc3QSMgoEbmFtZRgBIAEoCUIk4EEC+kEeChxtZW1vcy5hcGkudjEvSW5zdGFuY2VTZXR0aW5nIokBChxVcGRhdGVJbnN0YW5jZVNldHRpbmdSZXF1ZXN0EjMKB3NldHRpbmcYASABKAsyHS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nQgPgQQISNAoLdXBkYXRlX21hc2sYAiABKAsyGi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrQgPgQQEy2wMKD0luc3RhbmNlU2VydmljZRJ+ChJHZXRJbnN0YW5jZVByb2ZpbGUSJy5tZW1vcy5hcGkudjEuR2V0SW5zdGFuY2VQcm9maWxlUmVxdWVzdBodLm1lbW9zLmFwaS52MS5JbnN0YW5jZVByb2ZpbGUiIILT5JMCGhIYL2FwaS92MS9pbnN0YW5jZS9wcm9maWxlEo8BChJHZXRJbnN0YW5jZVNldHRpbmcSJy5tZW1vcy5hcGkudjEuR2V0SW5zdGFuY2VTZXR0aW5nUmVxdWVzdBodLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmciMdpBBG5hbWWC0+STAiQSIi9hcGkvdjEve25hbWU9aW5zdGFuY2Uvc2V0dGluZ3MvKn0StQEKFVVwZGF0ZUluc3RhbmNlU2V0dGluZxIqLm1lbW9zLmFwaS52MS5VcGRhdGVJbnN0YW5jZVNldHRpbmdSZXF1ZXN0Gh0ubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZyJR2kETc2V0dGluZyx1cGRhdGVfbWFza4LT5JMCNToHc2V0dGluZzIqL2FwaS92MS97c2V0dGluZy5uYW1lPWluc3RhbmNlL3NldHRpbmdzLyp9QqwBChBjb20ubWVtb3MuYXBpLnYxQhRJbnN0YW5jZVNlcnZpY2VQcm90b1ABWjBnaXRodWIuY29tL3VzZW1lbW9zL21lbW9zL3Byb3RvL2dlbi9hcGkvdjE7YXBpdjGiAgNNQViqAgxNZW1vcy5BcGkuVjHKAgxNZW1vc1xBcGlcVjHiAhhNZW1vc1xBcGlcVjFcR1BCTWV0YWRhdGHqAg5NZW1vczo6QXBpOjpWMWIGcHJvdG8z", [file_google_api_annotations, file_google_api_client, file_google_api_field_behavior, file_google_api_resource, file_google_protobuf_field_mask]); /** * Instance profile message containing basic instance information. @@ -40,11 +40,11 @@ export type InstanceProfile = Message<"memos.api.v1.InstanceProfile"> & { version: string; /** - * Mode is the instance mode (e.g. "prod", "dev" or "demo"). + * Demo indicates if the instance is in demo mode. * - * @generated from field: string mode = 3; + * @generated from field: bool demo = 3; */ - mode: string; + demo: boolean; /** * Instance URL is the URL of the instance.