diff --git a/pkg/items/convert.go b/pkg/items/convert.go new file mode 100644 index 0000000000000000000000000000000000000000..b2bdb3b30d1514284ad3b9b57ff7ef64838ac359 --- /dev/null +++ b/pkg/items/convert.go @@ -0,0 +1,81 @@ +package items + +import ( + "errors" + "io" + "io/fs" + "path/filepath" + + jsoniter "github.com/json-iterator/go" + "gopkg.in/yaml.v3" +) + +func FromYAML(r io.Reader) (result []*Item, err error) { + decoder := yaml.NewDecoder(r) + for { + var item *Item + err = decoder.Decode(&item) + if errors.Is(err, io.EOF) { + break + } + if err != nil { + return nil, err + } + + result = append(result, item) + } + + return result, nil +} + +func FromJSON(r io.Reader) (*Item, error) { + data, err := io.ReadAll(r) + if err != nil { + return nil, err + } + + result := new(Item) + err = jsoniter.Unmarshal(data, result) + return result, err +} + +func FromFile(file fs.File) ([]*Item, error) { + stat, err := file.Stat() + if err != nil { + return nil, err + } + + switch filepath.Ext(stat.Name()) { + case ".json": + item, err := FromJSON(file) + if err != nil { + return nil, err + } + return []*Item{item}, nil + + case ".yaml", ".yml": + return FromYAML(file) + } + + return nil, errors.New("item must be in JSON or YAML format") +} + +// FromFS возвращает все валидные записи в переданной файловой системе +func FromFS(fsys fs.FS) (result []*Item, err error) { + if err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, _ error) error { + file, err := fsys.Open(path) + if err != nil { + return err + } + defer file.Close() + + if items, err := FromFile(file); err == nil { + result = append(result, items...) + } + return nil + }); err != nil { + return nil, err + } + + return result, nil +} diff --git a/pkg/items/item.go b/pkg/items/item.go index c808c719628eb512d71589be53c9cd2f073b9c3d..de1cd0e8063b775b1c203bcaf94827c0cb38baab 100644 --- a/pkg/items/item.go +++ b/pkg/items/item.go @@ -92,15 +92,15 @@ type Permissions struct { type Item struct { ID string `json:"id" bson:"_id"` // ID - Идентификатор записи. Автоматически генерируется системой при сохранении первой ревизии. - SpaceID string `json:"spaceId" bson:"-"` - EnvID string `json:"envId" bson:"-"` - CollectionID string `json:"collectionId" bson:"-"` + SpaceID string `json:"spaceId" bson:"-" yaml:"space_id"` + EnvID string `json:"envId" bson:"-" yaml:"env_id"` + CollectionID string `json:"collectionId" bson:"-" yaml:"collection_id"` State State `json:"state" bson:"state"` - CreatedRevAt time.Time `json:"createdRevAt,omitempty" bson:"created_rev_at,omitempty"` - CreatedBy string `json:"createdBy,omitempty" bson:"created_by,omitempty"` - CreatedAt time.Time `json:"createdAt,omitempty" bson:"created_at,omitempty"` - UpdatedAt time.Time `json:"updatedAt,omitempty" bson:"updated_at,omitempty"` - UpdatedBy string `json:"updatedBy,omitempty" bson:"updated_by,omitempty"` + CreatedRevAt time.Time `json:"createdRevAt,omitempty" bson:"created_rev_at,omitempty" yaml:"created_rev_at,omitempty"` + CreatedBy string `json:"createdBy,omitempty" bson:"created_by,omitempty" yaml:"created_by,omitempty"` + CreatedAt time.Time `json:"createdAt,omitempty" bson:"created_at,omitempty" yaml:"created_at,omitempty"` + UpdatedAt time.Time `json:"updatedAt,omitempty" bson:"updated_at,omitempty" yaml:"updated_at,omitempty"` + UpdatedBy string `json:"updatedBy,omitempty" bson:"updated_by,omitempty" yaml:"updated_by,omitempty"` Data map[string]interface{} `json:"data" bson:"data"` // При создании или обновлении идентификатор локали в котором создается запись, опционально. diff --git a/pkg/items/test/assets/invalid.txt b/pkg/items/test/assets/invalid.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/pkg/items/test/assets/item.json b/pkg/items/test/assets/item.json new file mode 100644 index 0000000000000000000000000000000000000000..8a60d91c6adc6324521c1e924d0205a510f84871 --- /dev/null +++ b/pkg/items/test/assets/item.json @@ -0,0 +1,25 @@ +{ + "id": "item3", + "collectionId": "collID", + "envId": "envID", + "spaceId": "spaceID", + "state": 1, + "data": { + "obj": { + "str": "Hello" + }, + "arr": [ + "str1", + "str2" + ] + }, + "translations": { + "ru": { + "obj": { + "str": "Привет" + } + } + }, + "hidden": true, + "template": true +} \ No newline at end of file diff --git a/pkg/items/test/assets/items.yaml b/pkg/items/test/assets/items.yaml new file mode 100644 index 0000000000000000000000000000000000000000..19c49de570fa61c953def2ff377514ec71b8abc9 --- /dev/null +++ b/pkg/items/test/assets/items.yaml @@ -0,0 +1,37 @@ +--- +id: item1 +collection_id: collID +env_id: envID +space_id: spaceID +state: 1 +data: + obj: + str: Hello + arr: + - str1 + - str2 +translations: + ru: + obj: + str: Привет +hidden: true +template: true + +--- +id: item2 +collection_id: collID +env_id: envID +space_id: spaceID +state: 1 +data: + obj: + str: Hello + arr: + - str1 + - str2 +translations: + ru: + obj: + str: Привет +hidden: true +template: true \ No newline at end of file diff --git a/pkg/items/test/convert_test.go b/pkg/items/test/convert_test.go new file mode 100644 index 0000000000000000000000000000000000000000..6a63a7e777b019f71d004c8245fed53946ab4edb --- /dev/null +++ b/pkg/items/test/convert_test.go @@ -0,0 +1,40 @@ +package test + +import ( + "os" + "testing" + + "git.perx.ru/perxis/perxis-go/pkg/items" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestFromFS(t *testing.T) { + i1 := &items.Item{ + ID: "item1", + CollectionID: "collID", + EnvID: "envID", + SpaceID: "spaceID", + State: items.StatePublished, + Data: map[string]interface{}{ + "obj": map[string]interface{}{"str": "Hello"}, + "arr": []interface{}{"str1", "str2"}, + }, + Translations: map[string]map[string]interface{}{ + "ru": {"obj": map[string]interface{}{"str": "Привет"}}, + }, + Hidden: true, + Template: true, + } + + i2 := *i1 + i2.ID = "item2" + + i3 := *i1 + i3.ID = "item3" + + r, err := items.FromFS(os.DirFS("assets")) + require.NoError(t, err) + require.Len(t, r, 3) + assert.ElementsMatch(t, []*items.Item{i1, &i2, &i3}, r) +} diff --git a/pkg/schema/schema.go b/pkg/schema/schema.go index 5de8e1c7752e4e191c157f064dfa13fd585e4bb9..b05b8fc3e6df26a1153f6df9031add14d653b858 100644 --- a/pkg/schema/schema.go +++ b/pkg/schema/schema.go @@ -59,8 +59,8 @@ func FromFS(fsys fs.FS) (result []*Schema, err error) { } defer file.Close() - if schema, err := FromFile(file); err == nil { - result = append(result, schema...) + if schemas, err := FromFile(file); err == nil { + result = append(result, schemas...) } return nil }); err != nil {