mirror of
https://github.com/garethgeorge/backrest.git
synced 2025-12-15 10:05:42 +00:00
Add webui
This commit is contained in:
2
.github/workflows/build-and-test.yml
vendored
2
.github/workflows/build-and-test.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
go-version: '1.20'
|
||||
|
||||
- name: Restic
|
||||
run: apt install restic
|
||||
run: sudo apt install -y restic
|
||||
|
||||
- name: Build
|
||||
run: go build -v ./...
|
||||
|
||||
@@ -91,6 +91,61 @@ func (x *Config) GetPlans() []*Plan {
|
||||
return nil
|
||||
}
|
||||
|
||||
type User struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` // plaintext password
|
||||
}
|
||||
|
||||
func (x *User) Reset() {
|
||||
*x = User{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_config_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *User) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*User) ProtoMessage() {}
|
||||
|
||||
func (x *User) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_config_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use User.ProtoReflect.Descriptor instead.
|
||||
func (*User) Descriptor() ([]byte, []int) {
|
||||
return file_v1_config_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *User) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *User) GetPassword() string {
|
||||
if x != nil {
|
||||
return x.Password
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Repo struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -105,7 +160,7 @@ type Repo struct {
|
||||
func (x *Repo) Reset() {
|
||||
*x = Repo{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_config_proto_msgTypes[1]
|
||||
mi := &file_v1_config_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -118,7 +173,7 @@ func (x *Repo) String() string {
|
||||
func (*Repo) ProtoMessage() {}
|
||||
|
||||
func (x *Repo) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_config_proto_msgTypes[1]
|
||||
mi := &file_v1_config_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -131,7 +186,7 @@ func (x *Repo) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use Repo.ProtoReflect.Descriptor instead.
|
||||
func (*Repo) Descriptor() ([]byte, []int) {
|
||||
return file_v1_config_proto_rawDescGZIP(), []int{1}
|
||||
return file_v1_config_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *Repo) GetId() string {
|
||||
@@ -167,16 +222,15 @@ type Plan struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Repo string `protobuf:"bytes,2,opt,name=repo,proto3" json:"repo,omitempty"`
|
||||
RepoPath string `protobuf:"bytes,3,opt,name=repo_path,proto3" json:"repo_path,omitempty"` // subpath of the repo to backup to
|
||||
Paths []string `protobuf:"bytes,4,rep,name=paths,proto3" json:"paths,omitempty"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Repo string `protobuf:"bytes,2,opt,name=repo,proto3" json:"repo,omitempty"`
|
||||
Paths []string `protobuf:"bytes,4,rep,name=paths,proto3" json:"paths,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Plan) Reset() {
|
||||
*x = Plan{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_config_proto_msgTypes[2]
|
||||
mi := &file_v1_config_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -189,7 +243,7 @@ func (x *Plan) String() string {
|
||||
func (*Plan) ProtoMessage() {}
|
||||
|
||||
func (x *Plan) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_config_proto_msgTypes[2]
|
||||
mi := &file_v1_config_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -202,7 +256,7 @@ func (x *Plan) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use Plan.ProtoReflect.Descriptor instead.
|
||||
func (*Plan) Descriptor() ([]byte, []int) {
|
||||
return file_v1_config_proto_rawDescGZIP(), []int{2}
|
||||
return file_v1_config_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *Plan) GetId() string {
|
||||
@@ -219,13 +273,6 @@ func (x *Plan) GetRepo() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Plan) GetRepoPath() string {
|
||||
if x != nil {
|
||||
return x.RepoPath
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Plan) GetPaths() []string {
|
||||
if x != nil {
|
||||
return x.Paths
|
||||
@@ -245,22 +292,23 @@ var file_v1_config_proto_rawDesc = []byte{
|
||||
0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x52, 0x05, 0x72, 0x65,
|
||||
0x70, 0x6f, 0x73, 0x12, 0x1e, 0x0a, 0x05, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x05, 0x70, 0x6c,
|
||||
0x61, 0x6e, 0x73, 0x22, 0x56, 0x0a, 0x04, 0x52, 0x65, 0x70, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75,
|
||||
0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x1a, 0x0a,
|
||||
0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x76,
|
||||
0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x22, 0x5e, 0x0a, 0x04, 0x50,
|
||||
0x6c, 0x61, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x5f,
|
||||
0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f,
|
||||
0x5f, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x04,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x42, 0x2e, 0x5a, 0x2c, 0x67,
|
||||
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x65, 0x74, 0x68,
|
||||
0x67, 0x65, 0x6f, 0x72, 0x67, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x69, 0x63, 0x75, 0x69, 0x2f,
|
||||
0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
0x61, 0x6e, 0x73, 0x22, 0x36, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
|
||||
0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x56, 0x0a, 0x04, 0x52,
|
||||
0x65, 0x70, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
|
||||
0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
|
||||
0x64, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03,
|
||||
0x65, 0x6e, 0x76, 0x22, 0x40, 0x0a, 0x04, 0x50, 0x6c, 0x61, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72,
|
||||
0x65, 0x70, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05,
|
||||
0x70, 0x61, 0x74, 0x68, 0x73, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x65, 0x74, 0x68, 0x67, 0x65, 0x6f, 0x72, 0x67, 0x65,
|
||||
0x2f, 0x72, 0x65, 0x73, 0x74, 0x69, 0x63, 0x75, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -275,15 +323,16 @@ func file_v1_config_proto_rawDescGZIP() []byte {
|
||||
return file_v1_config_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_v1_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||
var file_v1_config_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_v1_config_proto_goTypes = []interface{}{
|
||||
(*Config)(nil), // 0: v1.Config
|
||||
(*Repo)(nil), // 1: v1.Repo
|
||||
(*Plan)(nil), // 2: v1.Plan
|
||||
(*User)(nil), // 1: v1.User
|
||||
(*Repo)(nil), // 2: v1.Repo
|
||||
(*Plan)(nil), // 3: v1.Plan
|
||||
}
|
||||
var file_v1_config_proto_depIdxs = []int32{
|
||||
1, // 0: v1.Config.repos:type_name -> v1.Repo
|
||||
2, // 1: v1.Config.plans:type_name -> v1.Plan
|
||||
2, // 0: v1.Config.repos:type_name -> v1.Repo
|
||||
3, // 1: v1.Config.plans:type_name -> v1.Plan
|
||||
2, // [2:2] is the sub-list for method output_type
|
||||
2, // [2:2] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
@@ -310,7 +359,7 @@ func file_v1_config_proto_init() {
|
||||
}
|
||||
}
|
||||
file_v1_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Repo); i {
|
||||
switch v := v.(*User); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -322,6 +371,18 @@ func file_v1_config_proto_init() {
|
||||
}
|
||||
}
|
||||
file_v1_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Repo); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_v1_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Plan); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -340,7 +401,7 @@ func file_v1_config_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_v1_config_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 3,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
612
gen/go/v1/restic.pb.go
Normal file
612
gen/go/v1/restic.pb.go
Normal file
@@ -0,0 +1,612 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc (unknown)
|
||||
// source: v1/restic.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type ResticSnapshot struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
UnixTimeMs int64 `protobuf:"varint,2,opt,name=unix_time_ms,json=time,proto3" json:"unix_time_ms,omitempty"`
|
||||
Hostname string `protobuf:"bytes,3,opt,name=hostname,proto3" json:"hostname,omitempty"`
|
||||
Username string `protobuf:"bytes,4,opt,name=username,proto3" json:"username,omitempty"`
|
||||
Tree string `protobuf:"bytes,5,opt,name=tree,proto3" json:"tree,omitempty"` // tree hash
|
||||
Parent string `protobuf:"bytes,6,opt,name=parent,proto3" json:"parent,omitempty"` // parent snapshot's id
|
||||
Paths []string `protobuf:"bytes,7,rep,name=paths,proto3" json:"paths,omitempty"`
|
||||
Tags []string `protobuf:"bytes,8,rep,name=tags,proto3" json:"tags,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ResticSnapshot) Reset() {
|
||||
*x = ResticSnapshot{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_restic_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ResticSnapshot) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ResticSnapshot) ProtoMessage() {}
|
||||
|
||||
func (x *ResticSnapshot) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_restic_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ResticSnapshot.ProtoReflect.Descriptor instead.
|
||||
func (*ResticSnapshot) Descriptor() ([]byte, []int) {
|
||||
return file_v1_restic_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *ResticSnapshot) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ResticSnapshot) GetUnixTimeMs() int64 {
|
||||
if x != nil {
|
||||
return x.UnixTimeMs
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ResticSnapshot) GetHostname() string {
|
||||
if x != nil {
|
||||
return x.Hostname
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ResticSnapshot) GetUsername() string {
|
||||
if x != nil {
|
||||
return x.Username
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ResticSnapshot) GetTree() string {
|
||||
if x != nil {
|
||||
return x.Tree
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ResticSnapshot) GetParent() string {
|
||||
if x != nil {
|
||||
return x.Parent
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ResticSnapshot) GetPaths() []string {
|
||||
if x != nil {
|
||||
return x.Paths
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ResticSnapshot) GetTags() []string {
|
||||
if x != nil {
|
||||
return x.Tags
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type BackupProgressEntry struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Types that are assignable to Entry:
|
||||
//
|
||||
// *BackupProgressEntry_Status
|
||||
// *BackupProgressEntry_Summary
|
||||
Entry isBackupProgressEntry_Entry `protobuf_oneof:"entry"`
|
||||
}
|
||||
|
||||
func (x *BackupProgressEntry) Reset() {
|
||||
*x = BackupProgressEntry{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_restic_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *BackupProgressEntry) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*BackupProgressEntry) ProtoMessage() {}
|
||||
|
||||
func (x *BackupProgressEntry) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_restic_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use BackupProgressEntry.ProtoReflect.Descriptor instead.
|
||||
func (*BackupProgressEntry) Descriptor() ([]byte, []int) {
|
||||
return file_v1_restic_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (m *BackupProgressEntry) GetEntry() isBackupProgressEntry_Entry {
|
||||
if m != nil {
|
||||
return m.Entry
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *BackupProgressEntry) GetStatus() *BackupProgressStatusEntry {
|
||||
if x, ok := x.GetEntry().(*BackupProgressEntry_Status); ok {
|
||||
return x.Status
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *BackupProgressEntry) GetSummary() *BackupProgressSummary {
|
||||
if x, ok := x.GetEntry().(*BackupProgressEntry_Summary); ok {
|
||||
return x.Summary
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isBackupProgressEntry_Entry interface {
|
||||
isBackupProgressEntry_Entry()
|
||||
}
|
||||
|
||||
type BackupProgressEntry_Status struct {
|
||||
Status *BackupProgressStatusEntry `protobuf:"bytes,1,opt,name=status,proto3,oneof"`
|
||||
}
|
||||
|
||||
type BackupProgressEntry_Summary struct {
|
||||
Summary *BackupProgressSummary `protobuf:"bytes,2,opt,name=summary,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*BackupProgressEntry_Status) isBackupProgressEntry_Entry() {}
|
||||
|
||||
func (*BackupProgressEntry_Summary) isBackupProgressEntry_Entry() {}
|
||||
|
||||
type BackupProgressStatusEntry struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
PercentDone float64 `protobuf:"fixed64,1,opt,name=percent_done,json=percent,proto3" json:"percent_done,omitempty"` // 0.0 - 1.0
|
||||
TotalFiles int64 `protobuf:"varint,2,opt,name=total_files,proto3" json:"total_files,omitempty"`
|
||||
TotalBytes int64 `protobuf:"varint,3,opt,name=total_bytes,proto3" json:"total_bytes,omitempty"`
|
||||
FilesDone int64 `protobuf:"varint,4,opt,name=files_done,proto3" json:"files_done,omitempty"`
|
||||
BytesDone int64 `protobuf:"varint,5,opt,name=bytes_done,proto3" json:"bytes_done,omitempty"`
|
||||
}
|
||||
|
||||
func (x *BackupProgressStatusEntry) Reset() {
|
||||
*x = BackupProgressStatusEntry{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_restic_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *BackupProgressStatusEntry) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*BackupProgressStatusEntry) ProtoMessage() {}
|
||||
|
||||
func (x *BackupProgressStatusEntry) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_restic_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use BackupProgressStatusEntry.ProtoReflect.Descriptor instead.
|
||||
func (*BackupProgressStatusEntry) Descriptor() ([]byte, []int) {
|
||||
return file_v1_restic_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *BackupProgressStatusEntry) GetPercentDone() float64 {
|
||||
if x != nil {
|
||||
return x.PercentDone
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BackupProgressStatusEntry) GetTotalFiles() int64 {
|
||||
if x != nil {
|
||||
return x.TotalFiles
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BackupProgressStatusEntry) GetTotalBytes() int64 {
|
||||
if x != nil {
|
||||
return x.TotalBytes
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BackupProgressStatusEntry) GetFilesDone() int64 {
|
||||
if x != nil {
|
||||
return x.FilesDone
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BackupProgressStatusEntry) GetBytesDone() int64 {
|
||||
if x != nil {
|
||||
return x.BytesDone
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type BackupProgressSummary struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
FilesNew int64 `protobuf:"varint,1,opt,name=files_new,proto3" json:"files_new,omitempty"`
|
||||
FilesChanged int64 `protobuf:"varint,2,opt,name=files_changed,proto3" json:"files_changed,omitempty"`
|
||||
FilesUnmodified int64 `protobuf:"varint,3,opt,name=files_unmodified,proto3" json:"files_unmodified,omitempty"`
|
||||
DirsNew int64 `protobuf:"varint,4,opt,name=dirs_new,proto3" json:"dirs_new,omitempty"`
|
||||
DirsChanged int64 `protobuf:"varint,5,opt,name=dirs_changed,proto3" json:"dirs_changed,omitempty"`
|
||||
DirsUnmodified int64 `protobuf:"varint,6,opt,name=dirs_unmodified,proto3" json:"dirs_unmodified,omitempty"`
|
||||
DataBlobs int64 `protobuf:"varint,7,opt,name=data_blobs,proto3" json:"data_blobs,omitempty"`
|
||||
TreeBlobs int64 `protobuf:"varint,8,opt,name=tree_blobs,proto3" json:"tree_blobs,omitempty"`
|
||||
DataAdded int64 `protobuf:"varint,9,opt,name=data_added,proto3" json:"data_added,omitempty"`
|
||||
TotalFilesProcessed int64 `protobuf:"varint,10,opt,name=total_files_processed,proto3" json:"total_files_processed,omitempty"`
|
||||
TotalBytesProcessed int64 `protobuf:"varint,11,opt,name=total_bytes_processed,proto3" json:"total_bytes_processed,omitempty"`
|
||||
TotalDuration int64 `protobuf:"varint,12,opt,name=total_duration,proto3" json:"total_duration,omitempty"`
|
||||
SnapshotId string `protobuf:"bytes,13,opt,name=snapshot_id,proto3" json:"snapshot_id,omitempty"`
|
||||
}
|
||||
|
||||
func (x *BackupProgressSummary) Reset() {
|
||||
*x = BackupProgressSummary{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_restic_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *BackupProgressSummary) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*BackupProgressSummary) ProtoMessage() {}
|
||||
|
||||
func (x *BackupProgressSummary) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_restic_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use BackupProgressSummary.ProtoReflect.Descriptor instead.
|
||||
func (*BackupProgressSummary) Descriptor() ([]byte, []int) {
|
||||
return file_v1_restic_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *BackupProgressSummary) GetFilesNew() int64 {
|
||||
if x != nil {
|
||||
return x.FilesNew
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BackupProgressSummary) GetFilesChanged() int64 {
|
||||
if x != nil {
|
||||
return x.FilesChanged
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BackupProgressSummary) GetFilesUnmodified() int64 {
|
||||
if x != nil {
|
||||
return x.FilesUnmodified
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BackupProgressSummary) GetDirsNew() int64 {
|
||||
if x != nil {
|
||||
return x.DirsNew
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BackupProgressSummary) GetDirsChanged() int64 {
|
||||
if x != nil {
|
||||
return x.DirsChanged
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BackupProgressSummary) GetDirsUnmodified() int64 {
|
||||
if x != nil {
|
||||
return x.DirsUnmodified
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BackupProgressSummary) GetDataBlobs() int64 {
|
||||
if x != nil {
|
||||
return x.DataBlobs
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BackupProgressSummary) GetTreeBlobs() int64 {
|
||||
if x != nil {
|
||||
return x.TreeBlobs
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BackupProgressSummary) GetDataAdded() int64 {
|
||||
if x != nil {
|
||||
return x.DataAdded
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BackupProgressSummary) GetTotalFilesProcessed() int64 {
|
||||
if x != nil {
|
||||
return x.TotalFilesProcessed
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BackupProgressSummary) GetTotalBytesProcessed() int64 {
|
||||
if x != nil {
|
||||
return x.TotalBytesProcessed
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BackupProgressSummary) GetTotalDuration() int64 {
|
||||
if x != nil {
|
||||
return x.TotalDuration
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BackupProgressSummary) GetSnapshotId() string {
|
||||
if x != nil {
|
||||
return x.SnapshotId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_v1_restic_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_v1_restic_proto_rawDesc = []byte{
|
||||
0x0a, 0x0f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x12, 0x02, 0x76, 0x31, 0x22, 0xca, 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x74, 0x69, 0x63,
|
||||
0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x0c, 0x75, 0x6e, 0x69, 0x78,
|
||||
0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04,
|
||||
0x74, 0x69, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x74, 0x72, 0x65, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x72, 0x65, 0x65,
|
||||
0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x68,
|
||||
0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61,
|
||||
0x67, 0x73, 0x22, 0x8e, 0x01, 0x0a, 0x13, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x72, 0x6f,
|
||||
0x67, 0x72, 0x65, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x74,
|
||||
0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74,
|
||||
0x61, 0x74, 0x75, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61,
|
||||
0x74, 0x75, 0x73, 0x12, 0x35, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70,
|
||||
0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x48,
|
||||
0x00, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x22, 0xbe, 0x01, 0x0a, 0x19, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x72,
|
||||
0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x79, 0x12, 0x1d, 0x0a, 0x0c, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x6f, 0x6e,
|
||||
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74,
|
||||
0x12, 0x20, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65,
|
||||
0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62,
|
||||
0x79, 0x74, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x64, 0x6f,
|
||||
0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f,
|
||||
0x64, 0x6f, 0x6e, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x64, 0x6f,
|
||||
0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f,
|
||||
0x64, 0x6f, 0x6e, 0x65, 0x22, 0x87, 0x04, 0x0a, 0x15, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x50,
|
||||
0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1c,
|
||||
0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x6e, 0x65, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x03, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x6e, 0x65, 0x77, 0x12, 0x24, 0x0a, 0x0d,
|
||||
0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x03, 0x52, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67,
|
||||
0x65, 0x64, 0x12, 0x2a, 0x0a, 0x10, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x75, 0x6e, 0x6d, 0x6f,
|
||||
0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x66, 0x69,
|
||||
0x6c, 0x65, 0x73, 0x5f, 0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x1a,
|
||||
0x0a, 0x08, 0x64, 0x69, 0x72, 0x73, 0x5f, 0x6e, 0x65, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x08, 0x64, 0x69, 0x72, 0x73, 0x5f, 0x6e, 0x65, 0x77, 0x12, 0x22, 0x0a, 0x0c, 0x64, 0x69,
|
||||
0x72, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x0c, 0x64, 0x69, 0x72, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x28,
|
||||
0x0a, 0x0f, 0x64, 0x69, 0x72, 0x73, 0x5f, 0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65,
|
||||
0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x64, 0x69, 0x72, 0x73, 0x5f, 0x75, 0x6e,
|
||||
0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61,
|
||||
0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x64, 0x61,
|
||||
0x74, 0x61, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x72, 0x65, 0x65,
|
||||
0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x72,
|
||||
0x65, 0x65, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61,
|
||||
0x5f, 0x61, 0x64, 0x64, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x64, 0x61,
|
||||
0x74, 0x61, 0x5f, 0x61, 0x64, 0x64, 0x65, 0x64, 0x12, 0x34, 0x0a, 0x15, 0x74, 0x6f, 0x74, 0x61,
|
||||
0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65,
|
||||
0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x12, 0x34,
|
||||
0x0a, 0x15, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x70, 0x72,
|
||||
0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x74,
|
||||
0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65,
|
||||
0x73, 0x73, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x75,
|
||||
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x74, 0x6f,
|
||||
0x74, 0x61, 0x6c, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b,
|
||||
0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0b, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x69, 0x64, 0x42, 0x2e,
|
||||
0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x72,
|
||||
0x65, 0x74, 0x68, 0x67, 0x65, 0x6f, 0x72, 0x67, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x69, 0x63,
|
||||
0x75, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_v1_restic_proto_rawDescOnce sync.Once
|
||||
file_v1_restic_proto_rawDescData = file_v1_restic_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_v1_restic_proto_rawDescGZIP() []byte {
|
||||
file_v1_restic_proto_rawDescOnce.Do(func() {
|
||||
file_v1_restic_proto_rawDescData = protoimpl.X.CompressGZIP(file_v1_restic_proto_rawDescData)
|
||||
})
|
||||
return file_v1_restic_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_v1_restic_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_v1_restic_proto_goTypes = []interface{}{
|
||||
(*ResticSnapshot)(nil), // 0: v1.ResticSnapshot
|
||||
(*BackupProgressEntry)(nil), // 1: v1.BackupProgressEntry
|
||||
(*BackupProgressStatusEntry)(nil), // 2: v1.BackupProgressStatusEntry
|
||||
(*BackupProgressSummary)(nil), // 3: v1.BackupProgressSummary
|
||||
}
|
||||
var file_v1_restic_proto_depIdxs = []int32{
|
||||
2, // 0: v1.BackupProgressEntry.status:type_name -> v1.BackupProgressStatusEntry
|
||||
3, // 1: v1.BackupProgressEntry.summary:type_name -> v1.BackupProgressSummary
|
||||
2, // [2:2] is the sub-list for method output_type
|
||||
2, // [2:2] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_v1_restic_proto_init() }
|
||||
func file_v1_restic_proto_init() {
|
||||
if File_v1_restic_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_v1_restic_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ResticSnapshot); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_v1_restic_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BackupProgressEntry); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_v1_restic_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BackupProgressStatusEntry); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_v1_restic_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BackupProgressSummary); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
file_v1_restic_proto_msgTypes[1].OneofWrappers = []interface{}{
|
||||
(*BackupProgressEntry_Status)(nil),
|
||||
(*BackupProgressEntry_Summary)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_v1_restic_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_v1_restic_proto_goTypes,
|
||||
DependencyIndexes: file_v1_restic_proto_depIdxs,
|
||||
MessageInfos: file_v1_restic_proto_msgTypes,
|
||||
}.Build()
|
||||
File_v1_restic_proto = out.File
|
||||
file_v1_restic_proto_rawDesc = nil
|
||||
file_v1_restic_proto_goTypes = nil
|
||||
file_v1_restic_proto_depIdxs = nil
|
||||
}
|
||||
@@ -20,7 +20,7 @@ func serveGRPC(ctx context.Context, socket string) error {
|
||||
return fmt.Errorf("failed to listen: %w", err)
|
||||
}
|
||||
grpcServer := grpc.NewServer()
|
||||
v1.RegisterResticUIServer(grpcServer, &server{})
|
||||
v1.RegisterResticUIServer(grpcServer, NewServer())
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
grpcServer.GracefulStop()
|
||||
|
||||
@@ -3,6 +3,8 @@ package api
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
v1 "github.com/garethgeorge/resticui/gen/go/v1"
|
||||
@@ -11,17 +13,44 @@ import (
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
type server struct {
|
||||
type Server struct {
|
||||
*v1.UnimplementedResticUIServer
|
||||
|
||||
reqId atomic.Uint64
|
||||
eventChannelsMu sync.Mutex
|
||||
eventChannels map[uint64]chan *v1.Event
|
||||
}
|
||||
|
||||
var _ v1.ResticUIServer = &server{}
|
||||
var _ v1.ResticUIServer = &Server{}
|
||||
|
||||
func (s *server) GetConfig(ctx context.Context, empty *emptypb.Empty) (*v1.Config, error) {
|
||||
func NewServer() *Server {
|
||||
s := &Server{
|
||||
eventChannels: make(map[uint64]chan *v1.Event),
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
time.Sleep(3 * time.Second)
|
||||
s.PublishEvent(&v1.Event{
|
||||
Event: &v1.Event_Log{
|
||||
Log: &v1.LogEvent{
|
||||
Message: fmt.Sprintf("event push test, it is %v", time.Now().Format(time.RFC3339)),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
}()
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// GetConfig implements GET /v1/config
|
||||
func (s *Server) GetConfig(ctx context.Context, empty *emptypb.Empty) (*v1.Config, error) {
|
||||
return config.Default.Get()
|
||||
}
|
||||
|
||||
func (s *server) SetConfig(ctx context.Context, c *v1.Config) (*v1.Config, error) {
|
||||
// SetConfig implements PUT /v1/config
|
||||
func (s *Server) SetConfig(ctx context.Context, c *v1.Config) (*v1.Config, error) {
|
||||
err := config.Default.Update(c)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update config: %w", err)
|
||||
@@ -29,27 +58,33 @@ func (s *server) SetConfig(ctx context.Context, c *v1.Config) (*v1.Config, error
|
||||
return config.Default.Get()
|
||||
}
|
||||
|
||||
func (s *server) GetEvents(_ *emptypb.Empty, stream v1.ResticUI_GetEventsServer) error {
|
||||
// GetEvents implements GET /v1/events
|
||||
func (s *Server) GetEvents(_ *emptypb.Empty, stream v1.ResticUI_GetEventsServer) error {
|
||||
reqId := s.reqId.Add(1)
|
||||
|
||||
// Register a channel to receive events for this invocation
|
||||
s.eventChannelsMu.Lock()
|
||||
eventChan := make(chan *v1.Event, 3)
|
||||
s.eventChannels[reqId] = eventChan
|
||||
s.eventChannelsMu.Unlock()
|
||||
defer delete(s.eventChannels, reqId)
|
||||
|
||||
for {
|
||||
zap.S().Info("Sending event")
|
||||
stream.Send(&v1.Event{
|
||||
Timestamp: 0,
|
||||
Event: &v1.Event_BackupStatusChange{
|
||||
BackupStatusChange: &v1.BackupStatusEvent{
|
||||
Status: v1.Status_IN_PROGRESS,
|
||||
Percent: 0,
|
||||
Plan: "myplan",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
timer := time.NewTimer(time.Second * 1)
|
||||
|
||||
select {
|
||||
case <-stream.Context().Done():
|
||||
zap.S().Info("Get events hangup")
|
||||
return nil
|
||||
case <-timer.C:
|
||||
case event := <-eventChan:
|
||||
stream.Send(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PublishEvent publishes an event to all GetEvents streams. It is effectively a multicast.
|
||||
func (s *Server) PublishEvent(event *v1.Event) {
|
||||
zap.S().Debug("Publishing event", zap.Any("event", event))
|
||||
s.eventChannelsMu.Lock()
|
||||
defer s.eventChannelsMu.Unlock()
|
||||
for _, ch := range s.eventChannels {
|
||||
ch <- event
|
||||
}
|
||||
}
|
||||
@@ -23,14 +23,14 @@ type LsEntry struct {
|
||||
}
|
||||
|
||||
type Snapshot struct {
|
||||
Id string `json:"id"`
|
||||
Time string `json:"time"`
|
||||
Tree string `json:"tree"`
|
||||
Paths []string `json:"paths"`
|
||||
Hostname string `json:"hostname"`
|
||||
Username string `json:"username"`
|
||||
Id string `json:"id"`
|
||||
ShortId string `json:"short_id"`
|
||||
Tags []string `json:"tags"`
|
||||
Parent string `json:"parent"`
|
||||
}
|
||||
|
||||
type BackupProgressEntry struct {
|
||||
@@ -58,9 +58,6 @@ type BackupProgressEntry struct {
|
||||
FilesDone int `json:"files_done"`
|
||||
TotalBytes int `json:"total_bytes"`
|
||||
BytesDone int `json:"bytes_done"`
|
||||
|
||||
// Error fields
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
// readBackupProgressEntrys returns the summary event or an error if the command failed.
|
||||
|
||||
@@ -14,6 +14,6 @@ plugins:
|
||||
- paths=source_relative
|
||||
- generate_unbound_methods=true
|
||||
- plugin: grpc-gateway-ts
|
||||
out: ../gen/ts
|
||||
out: ../webui/gen/ts
|
||||
opt:
|
||||
- paths=source_relative
|
||||
@@ -27,4 +27,4 @@ message Plan {
|
||||
string id = 1 [json_name="id"];
|
||||
string repo = 2 [json_name="repo"];
|
||||
repeated string paths = 4 [json_name="paths"];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ message Event {
|
||||
LogEvent log = 3 [json_name="log"];
|
||||
BackupStatusEvent backup_status_change = 4 [json_name="backup_status"];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
message LogEvent {
|
||||
|
||||
47
proto/v1/restic.proto
Normal file
47
proto/v1/restic.proto
Normal file
@@ -0,0 +1,47 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package v1;
|
||||
|
||||
option go_package = "github.com/garethgeorge/resticui/go/proto/v1";
|
||||
|
||||
message ResticSnapshot {
|
||||
string id = 1 [json_name = "id"];
|
||||
int64 unix_time_ms = 2 [json_name = "time"];
|
||||
string hostname = 3 [json_name = "hostname"];
|
||||
string username = 4 [json_name = "username"];
|
||||
string tree = 5 [json_name = "tree"]; // tree hash
|
||||
string parent = 6 [json_name = "parent"]; // parent snapshot's id
|
||||
repeated string paths = 7 [json_name = "paths"];
|
||||
repeated string tags = 8 [json_name = "tags"];
|
||||
}
|
||||
|
||||
message BackupProgressEntry {
|
||||
oneof entry {
|
||||
BackupProgressStatusEntry status = 1 [json_name = "status"];
|
||||
BackupProgressSummary summary = 2 [json_name = "summary"];
|
||||
}
|
||||
}
|
||||
|
||||
message BackupProgressStatusEntry {
|
||||
double percent_done = 1 [json_name = "percent"]; // 0.0 - 1.0
|
||||
int64 total_files = 2 [json_name = "total_files"];
|
||||
int64 total_bytes = 3 [json_name = "total_bytes"];
|
||||
int64 files_done = 4 [json_name = "files_done"];
|
||||
int64 bytes_done = 5 [json_name = "bytes_done"];
|
||||
}
|
||||
|
||||
message BackupProgressSummary {
|
||||
int64 files_new = 1 [json_name = "files_new"];
|
||||
int64 files_changed = 2 [json_name = "files_changed"];
|
||||
int64 files_unmodified = 3 [json_name = "files_unmodified"];
|
||||
int64 dirs_new = 4 [json_name = "dirs_new"];
|
||||
int64 dirs_changed = 5 [json_name = "dirs_changed"];
|
||||
int64 dirs_unmodified = 6 [json_name = "dirs_unmodified"];
|
||||
int64 data_blobs = 7 [json_name = "data_blobs"];
|
||||
int64 tree_blobs = 8 [json_name = "tree_blobs"];
|
||||
int64 data_added = 9 [json_name = "data_added"];
|
||||
int64 total_files_processed = 10 [json_name = "total_files_processed"];
|
||||
int64 total_bytes_processed = 11 [json_name = "total_bytes_processed"];
|
||||
int64 total_duration = 12 [json_name = "total_duration"];
|
||||
string snapshot_id = 13 [json_name = "snapshot_id"];
|
||||
}
|
||||
@@ -15,6 +15,7 @@ service ResticUI {
|
||||
get: "/v1/config"
|
||||
};
|
||||
}
|
||||
|
||||
rpc SetConfig (Config) returns (Config) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/config"
|
||||
|
||||
3
webui/.gitignore
vendored
Normal file
3
webui/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.parcel-cache
|
||||
node_modules
|
||||
dist
|
||||
@@ -10,6 +10,11 @@ export type Config = {
|
||||
plans?: Plan[]
|
||||
}
|
||||
|
||||
export type User = {
|
||||
name?: string
|
||||
password?: string
|
||||
}
|
||||
|
||||
export type Repo = {
|
||||
id?: string
|
||||
uri?: string
|
||||
@@ -20,6 +25,5 @@ export type Repo = {
|
||||
export type Plan = {
|
||||
id?: string
|
||||
repo?: string
|
||||
repoPath?: string
|
||||
paths?: string[]
|
||||
}
|
||||
55
webui/gen/ts/v1/restic.pb.ts
Normal file
55
webui/gen/ts/v1/restic.pb.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
/*
|
||||
* This file is a generated Typescript file for GRPC Gateway, DO NOT MODIFY
|
||||
*/
|
||||
|
||||
type Absent<T, K extends keyof T> = { [k in Exclude<keyof T, K>]?: undefined };
|
||||
type OneOf<T> =
|
||||
| { [k in keyof T]?: undefined }
|
||||
| (
|
||||
keyof T extends infer K ?
|
||||
(K extends string & keyof T ? { [k in K]: T[K] } & Absent<T, K>
|
||||
: never)
|
||||
: never);
|
||||
export type ResticSnapshot = {
|
||||
id?: string
|
||||
unixTimeMs?: string
|
||||
hostname?: string
|
||||
username?: string
|
||||
tree?: string
|
||||
parent?: string
|
||||
paths?: string[]
|
||||
tags?: string[]
|
||||
}
|
||||
|
||||
|
||||
type BaseBackupProgressEntry = {
|
||||
}
|
||||
|
||||
export type BackupProgressEntry = BaseBackupProgressEntry
|
||||
& OneOf<{ status: BackupProgressStatusEntry; summary: BackupProgressSummary }>
|
||||
|
||||
export type BackupProgressStatusEntry = {
|
||||
percentDone?: number
|
||||
totalFiles?: string
|
||||
totalBytes?: string
|
||||
filesDone?: string
|
||||
bytesDone?: string
|
||||
}
|
||||
|
||||
export type BackupProgressSummary = {
|
||||
filesNew?: string
|
||||
filesChanged?: string
|
||||
filesUnmodified?: string
|
||||
dirsNew?: string
|
||||
dirsChanged?: string
|
||||
dirsUnmodified?: string
|
||||
dataBlobs?: string
|
||||
treeBlobs?: string
|
||||
dataAdded?: string
|
||||
totalFilesProcessed?: string
|
||||
totalBytesProcessed?: string
|
||||
totalDuration?: string
|
||||
snapshotId?: string
|
||||
}
|
||||
3589
webui/package-lock.json
generated
Normal file
3589
webui/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,28 @@
|
||||
{
|
||||
"name": "webui",
|
||||
"name": "resticui",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "parcel serve src/index.html",
|
||||
"build": "parcel build src/index.html",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@types/lodash": "^4.14.191",
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/react": "^18.0.26",
|
||||
"@types/react-dom": "^18.0.10",
|
||||
"axios": "^1.2.2",
|
||||
"lodash": "^4.17.21",
|
||||
"parcel": "^2.8.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"typescript": "^4.9.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"buffer": "^5.7.1",
|
||||
"process": "^0.11.10"
|
||||
}
|
||||
}
|
||||
|
||||
5
webui/src/index.css
Normal file
5
webui/src/index.css
Normal file
@@ -0,0 +1,5 @@
|
||||
body {
|
||||
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue",
|
||||
Helvetica, Arial, "Lucida Grande", sans-serif;
|
||||
font-weight: 300;
|
||||
}
|
||||
12
webui/src/index.html
Normal file
12
webui/src/index.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Guidebook FS Search</title>
|
||||
<link rel="stylesheet" href="./index.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<!-- The script tag below is just a place holder.
|
||||
Parcel will perform magic to insert TSC output here: -->
|
||||
<script src="index.tsx" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
6
webui/src/index.tsx
Normal file
6
webui/src/index.tsx
Normal file
@@ -0,0 +1,6 @@
|
||||
import * as React from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { App } from "./views/App";
|
||||
|
||||
const el = document.querySelector("#app");
|
||||
el && createRoot(el).render(<App />);
|
||||
24
webui/src/views/App.tsx
Normal file
24
webui/src/views/App.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import test from "node:test";
|
||||
import * as React from "react";
|
||||
import _ from "lodash";
|
||||
|
||||
export const App = () => {
|
||||
const [searchTerm, setSearchTerm] = React.useState("");
|
||||
const [results, setResults] = React.useState<any>();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>Guidebook FS Search</h1>
|
||||
<div>
|
||||
Search:
|
||||
<input
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
></input>
|
||||
</div>
|
||||
<pre>
|
||||
<code>{"RESULTS: " + JSON.stringify(results, null, 2)}</code>
|
||||
</pre>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
11
webui/tsconfig.json
Normal file
11
webui/tsconfig.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"jsx": "react",
|
||||
"target": "es2016",
|
||||
"module": "commonjs",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user