1
0
Fork 0
mirror of https://github.com/anyproto/anytype-heart.git synced 2025-06-10 10:00:46 +09:00

GO-4969: Deprecate template model, treat as object

This commit is contained in:
Jannis Metrikat 2025-04-27 13:24:07 +02:00
parent ab1cae7aff
commit fa92a6cbbf
No known key found for this signature in database
GPG key ID: B223CAC5AAF85615
8 changed files with 83 additions and 148 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -548,32 +548,10 @@ components:
tag:
$ref: '#/components/schemas/object.Tag'
type: object
object.Template:
description: The template
properties:
archived:
description: Whether the template is archived
example: false
type: boolean
icon:
$ref: '#/components/schemas/object.Icon'
id:
description: The id of the template
example: bafyreictrp3obmnf6dwejy5o4p7bderaaia4bdg2psxbfzf44yya5uutge
type: string
name:
description: The name of the template
example: My template
type: string
object:
description: The data model of the object
example: template
type: string
type: object
object.TemplateResponse:
properties:
template:
$ref: '#/components/schemas/object.Template'
$ref: '#/components/schemas/object.ObjectWithBlocks'
type: object
object.Text:
description: The text of the block, if applicable
@ -661,13 +639,11 @@ components:
object.UpdateObjectRequest:
properties:
description:
description: The description of the object
description: The description to set for the object
example: This is a description of the object.
type: string
id:
description: The id of the object to update
example: bafyreie6n5l5nkbjal37su54cha4coy7qzuhrnajluzv5qd5jvtsrxkequ
type: string
icon:
$ref: '#/components/schemas/object.Icon'
name:
description: The name of the object
example: My object
@ -678,37 +654,24 @@ components:
example:
'{"property_key"': ' "value"}'
type: object
required:
- id
type: object
object.UpdatePropertyRequest:
properties:
id:
description: The id of the property to update
example: bafyreids36kpw5ppuwm3ce2p4ezb3ab7cihhkq6yfbwzwpp4mln7rcgw7a
type: string
name:
description: the name to set for the property
description: The name to set for the property
example: Last modified date
type: string
required:
- id
- name
type: object
object.UpdateTagRequest:
properties:
color:
$ref: '#/components/schemas/object.Color'
id:
description: The id of the tag to update
example: bafyreiaixlnaefu3ci22zdenjhsdlyaeeoyjrsid5qhfeejzlccijbj7sq
type: string
name:
description: The name to set for the tag
example: In progress
type: string
required:
- id
type: object
pagination.PaginatedResponse-list_View:
properties:
@ -754,17 +717,6 @@ components:
pagination:
$ref: '#/components/schemas/pagination.PaginationMeta'
type: object
pagination.PaginatedResponse-object_Template:
properties:
data:
description: The list of items in the current result set
items:
$ref: '#/components/schemas/object.Template'
type: array
uniqueItems: false
pagination:
$ref: '#/components/schemas/pagination.PaginationMeta'
type: object
pagination.PaginatedResponse-object_Type:
properties:
data:
@ -3176,7 +3128,7 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/pagination.PaginatedResponse-object_Template'
$ref: '#/components/schemas/pagination.PaginatedResponse-object_Object'
description: List of templates
"401":
content:

View file

@ -794,7 +794,7 @@ func GetTypeHandler(s Service) gin.HandlerFunc {
// @Param type_id path string true "Type ID"
// @Param offset query int false "The number of items to skip before starting to collect the result set" default(0)
// @Param limit query int false "The number of items to return" default(100) maximum(1000)
// @Success 200 {object} pagination.PaginatedResponse[Template] "List of templates"
// @Success 200 {object} pagination.PaginatedResponse[Object] "List of templates"
// @Failure 401 {object} util.UnauthorizedError "Unauthorized"
// @Failure 500 {object} util.ServerError "Internal server error"
// @Security bearerauth
@ -848,7 +848,7 @@ func GetTemplateHandler(s Service) gin.HandlerFunc {
typeId := c.Param("type_id")
templateId := c.Param("template_id")
object, err := s.GetTemplate(c.Request.Context(), spaceId, typeId, templateId)
template, err := s.GetTemplate(c.Request.Context(), spaceId, typeId, templateId)
code := util.MapErrorCode(err,
util.ErrToCode(ErrTemplateNotFound, http.StatusNotFound),
util.ErrToCode(ErrTemplateDeleted, http.StatusGone),
@ -861,6 +861,6 @@ func GetTemplateHandler(s Service) gin.HandlerFunc {
return
}
c.JSON(http.StatusOK, TemplateResponse{Template: object})
c.JSON(http.StatusOK, TemplateResponse{Template: template})
}
}

View file

@ -49,10 +49,10 @@ type CreateObjectRequest struct {
}
type UpdateObjectRequest struct {
Id string `json:"id" binding:"required" example:"bafyreie6n5l5nkbjal37su54cha4coy7qzuhrnajluzv5qd5jvtsrxkequ"` // The id of the object to update
Name string `json:"name" example:"My object"` // The name of the object
Description string `json:"description" example:"This is a description of the object."` // The description of the object
Properties map[string]interface{} `json:"properties" example:"{\"property_key\": \"value\"}"` // The properties to update on the object
Name string `json:"name" example:"My object"` // The name of the object
Icon Icon `json:"icon"` // The icon to set for the object
Description string `json:"description" example:"This is a description of the object."` // The description to set for the object
Properties map[string]interface{} `json:"properties" example:"{\"property_key\": \"value\"}"` // The properties to update on the object
}
type ObjectResponse struct {
@ -134,7 +134,7 @@ type CreatePropertyRequest struct {
}
type UpdatePropertyRequest struct {
Name string `json:"name" binding:"required" example:"Last modified date"` // the name to set for the property
Name string `json:"name" binding:"required" example:"Last modified date"` // The name to set for the property
}
type Property struct {
@ -194,13 +194,5 @@ type Type struct {
}
type TemplateResponse struct {
Template Template `json:"template"` // The template
}
type Template struct {
Object string `json:"object" example:"template"` // The data model of the object
Id string `json:"id" example:"bafyreictrp3obmnf6dwejy5o4p7bderaaia4bdg2psxbfzf44yya5uutge"` // The id of the template
Name string `json:"name" example:"My template"` // The name of the template
Icon Icon `json:"icon"` // The icon of the template
Archived bool `json:"archived" example:"false"` // Whether the template is archived
Template ObjectWithBlocks `json:"template"` // The template
}

View file

@ -119,31 +119,20 @@ func (s *service) GetObject(ctx context.Context, spaceId string, objectId string
}
}
// pre-fetch properties to fill the object
propertyMap, err := s.GetPropertyMapFromStore(spaceId)
if err != nil {
return ObjectWithBlocks{}, err
}
typeMap, err := s.GetTypeMapFromStore(spaceId, propertyMap)
if err != nil {
return ObjectWithBlocks{}, err
}
tagMap, err := s.GetTagMapFromStore(spaceId)
if err != nil {
return ObjectWithBlocks{}, err
}
object := ObjectWithBlocks{
Object: "object",
Id: resp.ObjectView.Details[0].Details.Fields[bundle.RelationKeyId.String()].GetStringValue(),
Name: resp.ObjectView.Details[0].Details.Fields[bundle.RelationKeyName.String()].GetStringValue(),
Icon: GetIcon(s.gatewayUrl, resp.ObjectView.Details[0].Details.Fields[bundle.RelationKeyIconEmoji.String()].GetStringValue(), resp.ObjectView.Details[0].Details.Fields[bundle.RelationKeyIconImage.String()].GetStringValue(), resp.ObjectView.Details[0].Details.Fields[bundle.RelationKeyIconName.String()].GetStringValue(), resp.ObjectView.Details[0].Details.Fields[bundle.RelationKeyIconOption.String()].GetNumberValue()),
Archived: resp.ObjectView.Details[0].Details.Fields[bundle.RelationKeyIsArchived.String()].GetBoolValue(),
SpaceId: resp.ObjectView.Details[0].Details.Fields[bundle.RelationKeySpaceId.String()].GetStringValue(),
Snippet: resp.ObjectView.Details[0].Details.Fields[bundle.RelationKeySnippet.String()].GetStringValue(),
Layout: model.ObjectTypeLayout_name[int32(resp.ObjectView.Details[0].Details.Fields[bundle.RelationKeyResolvedLayout.String()].GetNumberValue())],
Type: s.GetTypeFromDetails(resp.ObjectView.Details, resp.ObjectView.Details[0].Details.Fields[bundle.RelationKeyType.String()].GetStringValue(), propertyMap),
Properties: s.getPropertiesFromStruct(resp.ObjectView.Details[0].Details, propertyMap, tagMap),
Blocks: s.getBlocksFromDetails(resp),
}
return object, nil
return s.GetObjectWithBlocksFromStruct(resp.ObjectView.Details[0].Details, resp.ObjectView.Blocks, propertyMap, typeMap, tagMap), nil
}
// DeleteObject deletes an existing object in a specific space.
@ -350,10 +339,10 @@ func (s *service) buildObjectDetails(ctx context.Context, spaceId string, reques
}
// getBlocksFromDetails returns the list of blocks from the ObjectShowResponse.
func (s *service) getBlocksFromDetails(resp *pb.RpcObjectShowResponse) []Block {
blocks := []Block{}
func (s *service) getBlocksFromDetails(blocks []*model.Block) []Block {
b := make([]Block, 0, len(blocks))
for _, block := range resp.ObjectView.Blocks {
for _, block := range blocks {
var text *Text
var file *File
var property *Property
@ -390,7 +379,7 @@ func (s *service) getBlocksFromDetails(resp *pb.RpcObjectShowResponse) []Block {
}
// TODO: other content types?
blocks = append(blocks, Block{
b = append(b, Block{
Object: "block",
Id: block.Id,
ChildrenIds: block.ChildrenIds,
@ -403,10 +392,10 @@ func (s *service) getBlocksFromDetails(resp *pb.RpcObjectShowResponse) []Block {
})
}
return blocks
return b
}
// GetObjectFromStruct creates an ObjectWithBlocks without blocks from the details.
// GetObjectFromStruct creates an Object without blocks from the details.
func (s *service) GetObjectFromStruct(details *types.Struct, propertyMap map[string]Property, typeMap map[string]Type, tagMap map[string]Tag) Object {
return Object{
Object: "object",
@ -422,6 +411,23 @@ func (s *service) GetObjectFromStruct(details *types.Struct, propertyMap map[str
}
}
// GetObjectWithBlocksFromStruct creates an ObjectWithBlocks from the details.
func (s *service) GetObjectWithBlocksFromStruct(details *types.Struct, blocks []*model.Block, propertyMap map[string]Property, typeMap map[string]Type, tagMap map[string]Tag) ObjectWithBlocks {
return ObjectWithBlocks{
Object: "object",
Id: details.Fields[bundle.RelationKeyId.String()].GetStringValue(),
Name: details.Fields[bundle.RelationKeyName.String()].GetStringValue(),
Icon: GetIcon(s.gatewayUrl, details.Fields[bundle.RelationKeyIconEmoji.String()].GetStringValue(), details.Fields[bundle.RelationKeyIconImage.String()].GetStringValue(), details.Fields[bundle.RelationKeyIconName.String()].GetStringValue(), details.Fields[bundle.RelationKeyIconOption.String()].GetNumberValue()),
Archived: details.Fields[bundle.RelationKeyIsArchived.String()].GetBoolValue(),
SpaceId: details.Fields[bundle.RelationKeySpaceId.String()].GetStringValue(),
Snippet: details.Fields[bundle.RelationKeySnippet.String()].GetStringValue(),
Layout: model.ObjectTypeLayout_name[int32(details.Fields[bundle.RelationKeyResolvedLayout.String()].GetNumberValue())],
Type: s.getTypeFromStruct(details, typeMap),
Properties: s.getPropertiesFromStruct(details, propertyMap, tagMap),
Blocks: s.getBlocksFromDetails(blocks),
}
}
// isMissingObject returns true if val indicates a "_missing_object" placeholder.
func (s *service) isMissingObject(val interface{}) bool {
switch v := val.(type) {

View file

@ -6,7 +6,6 @@ import (
"github.com/gogo/protobuf/types"
"github.com/anyproto/anytype-heart/core/api/apicore"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
)
type Service interface {
@ -31,15 +30,14 @@ type Service interface {
ListTypes(ctx context.Context, spaceId string, offset int, limit int) ([]Type, int, bool, error)
GetType(ctx context.Context, spaceId string, typeId string) (Type, error)
ListTemplates(ctx context.Context, spaceId string, typeId string, offset int, limit int) ([]Template, int, bool, error)
GetTemplate(ctx context.Context, spaceId string, typeId string, templateId string) (Template, error)
ListTemplates(ctx context.Context, spaceId string, typeId string, offset int, limit int) ([]Object, int, bool, error)
GetTemplate(ctx context.Context, spaceId string, typeId string, templateId string) (ObjectWithBlocks, error)
GetObjectFromStruct(details *types.Struct, propertyMap map[string]Property, typeMap map[string]Type, tagMap map[string]Tag) Object
GetPropertyMapFromStore(spaceId string) (map[string]Property, error)
GetPropertyMapsFromStore(spaceIds []string) (map[string]map[string]Property, error)
GetTypeMapFromStore(spaceId string, propertyMap map[string]Property) (map[string]Type, error)
GetTypeMapsFromStore(spaceIds []string, propertyMap map[string]map[string]Property) (map[string]map[string]Type, error)
GetTypeFromDetails(details []*model.ObjectViewDetailsSet, typeId string, propertyMap map[string]Property) Type
GetTagMapFromStore(spaceId string) (map[string]Tag, error)
GetTagMapsFromStore(spaceIds []string) (map[string]map[string]Tag, error)
}

View file

@ -130,7 +130,7 @@ func (s *service) GetType(ctx context.Context, spaceId string, typeId string) (T
}
// ListTemplates returns a paginated list of templates in a specific space.
func (s *service) ListTemplates(ctx context.Context, spaceId string, typeId string, offset int, limit int) (templates []Template, total int, hasMore bool, err error) {
func (s *service) ListTemplates(ctx context.Context, spaceId string, typeId string, offset int, limit int) (templates []Object, total int, hasMore bool, err error) {
// First, determine the type ID of "ot-template" in the space
templateTypeIdResp := s.mw.ObjectSearch(ctx, &pb.RpcObjectSearchRequest{
SpaceId: spaceId,
@ -168,7 +168,6 @@ func (s *service) ListTemplates(ctx context.Context, spaceId string, typeId stri
Value: pbtypes.String(typeId),
},
},
Keys: []string{bundle.RelationKeyId.String(), bundle.RelationKeyTargetObjectType.String(), bundle.RelationKeyName.String(), bundle.RelationKeyIconEmoji.String(), bundle.RelationKeyIsArchived.String()},
})
if templateObjectsResp.Error.Code != pb.RpcObjectSearchResponseError_NULL {
@ -177,24 +176,30 @@ func (s *service) ListTemplates(ctx context.Context, spaceId string, typeId stri
total = len(templateObjectsResp.Records)
paginatedTemplates, hasMore := pagination.Paginate(templateObjectsResp.Records, offset, limit)
templates = make([]Template, 0, len(paginatedTemplates))
templates = make([]Object, 0, len(paginatedTemplates))
propertyMap, err := s.GetPropertyMapFromStore(spaceId)
if err != nil {
return nil, 0, false, err
}
typeMap, err := s.GetTypeMapFromStore(spaceId, propertyMap)
if err != nil {
return nil, 0, false, err
}
tagMap, err := s.GetTagMapFromStore(spaceId)
if err != nil {
return nil, 0, false, err
}
// Finally, open each template and populate the response
for _, record := range paginatedTemplates {
templates = append(templates, Template{
Object: "template",
Id: record.Fields[bundle.RelationKeyId.String()].GetStringValue(),
Name: record.Fields[bundle.RelationKeyName.String()].GetStringValue(),
Icon: GetIcon(s.gatewayUrl, record.Fields[bundle.RelationKeyIconEmoji.String()].GetStringValue(), "", "", 0),
Archived: record.Fields[bundle.RelationKeyIsArchived.String()].GetBoolValue(),
})
templates = append(templates, s.GetObjectFromStruct(record, propertyMap, typeMap, tagMap))
}
return templates, total, hasMore, nil
}
// GetTemplate returns a single template by its ID in a specific space.
func (s *service) GetTemplate(ctx context.Context, spaceId string, _ string, templateId string) (Template, error) {
func (s *service) GetTemplate(ctx context.Context, spaceId string, _ string, templateId string) (ObjectWithBlocks, error) {
resp := s.mw.ObjectShow(ctx, &pb.RpcObjectShowRequest{
SpaceId: spaceId,
ObjectId: templateId,
@ -202,25 +207,32 @@ func (s *service) GetTemplate(ctx context.Context, spaceId string, _ string, tem
if resp.Error != nil {
if resp.Error.Code == pb.RpcObjectShowResponseError_NOT_FOUND {
return Template{}, ErrTemplateNotFound
return ObjectWithBlocks{}, ErrTemplateNotFound
}
if resp.Error.Code == pb.RpcObjectShowResponseError_OBJECT_DELETED {
return Template{}, ErrTemplateDeleted
return ObjectWithBlocks{}, ErrTemplateDeleted
}
if resp.Error.Code != pb.RpcObjectShowResponseError_NULL {
return Template{}, ErrFailedRetrieveTemplate
return ObjectWithBlocks{}, ErrFailedRetrieveTemplate
}
}
return Template{
Object: "template",
Id: templateId,
Name: resp.ObjectView.Details[0].Details.Fields[bundle.RelationKeyName.String()].GetStringValue(),
Icon: GetIcon(s.gatewayUrl, resp.ObjectView.Details[0].Details.Fields[bundle.RelationKeyIconEmoji.String()].GetStringValue(), "", "", 0),
Archived: resp.ObjectView.Details[0].Details.Fields[bundle.RelationKeyIsArchived.String()].GetBoolValue(),
}, nil
propertyMap, err := s.GetPropertyMapFromStore(spaceId)
if err != nil {
return ObjectWithBlocks{}, err
}
typeMap, err := s.GetTypeMapFromStore(spaceId, propertyMap)
if err != nil {
return ObjectWithBlocks{}, err
}
tagMap, err := s.GetTagMapFromStore(spaceId)
if err != nil {
return ObjectWithBlocks{}, err
}
return s.GetObjectWithBlocksFromStruct(resp.ObjectView.Details[0].Details, resp.ObjectView.Blocks, propertyMap, typeMap, tagMap), nil
}
// GetTypeMapsFromStore retrieves all types from all spaces.
@ -287,31 +299,6 @@ func (s *service) GetTypeMapFromStore(spaceId string, propertyMap map[string]Pro
return typeMap, nil
}
// GetTypeFromDetails retrieves the type from the details.
func (s *service) GetTypeFromDetails(details []*model.ObjectViewDetailsSet, typeId string, propertyMap map[string]Property) Type {
var objectTypeDetail *types.Struct
for _, detail := range details {
if detail.Id == typeId {
objectTypeDetail = detail.GetDetails()
break
}
}
if objectTypeDetail == nil {
return Type{}
}
return Type{
Object: "type",
Id: typeId,
Key: objectTypeDetail.Fields[bundle.RelationKeyUniqueKey.String()].GetStringValue(),
Name: objectTypeDetail.Fields[bundle.RelationKeyName.String()].GetStringValue(),
Icon: GetIcon(s.gatewayUrl, objectTypeDetail.Fields[bundle.RelationKeyIconEmoji.String()].GetStringValue(), "", objectTypeDetail.Fields[bundle.RelationKeyIconName.String()].GetStringValue(), objectTypeDetail.Fields[bundle.RelationKeyIconOption.String()].GetNumberValue()),
Layout: model.ObjectTypeLayout_name[int32(objectTypeDetail.Fields[bundle.RelationKeyRecommendedLayout.String()].GetNumberValue())],
Properties: s.getRecommendedPropertiesFromLists(objectTypeDetail.Fields[bundle.RelationKeyRecommendedFeaturedRelations.String()].GetListValue(), objectTypeDetail.Fields[bundle.RelationKeyRecommendedRelations.String()].GetListValue(), propertyMap),
}
}
// getTypeFromStruct retrieves the type from the details.
func (s *service) getTypeFromStruct(details *types.Struct, typeMap map[string]Type) Type {
return typeMap[details.Fields[bundle.RelationKeyType.String()].GetStringValue()]