mirror of
https://github.com/dstotijn/go-notion.git
synced 2024-11-28 08:58:51 +02:00
523 lines
18 KiB
Go
523 lines
18 KiB
Go
package notion
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"time"
|
|
)
|
|
|
|
// Database is a resource on the Notion platform.
|
|
// See: https://developers.notion.com/reference/database
|
|
type Database struct {
|
|
ID string `json:"id"`
|
|
CreatedTime time.Time `json:"created_time"`
|
|
CreatedBy BaseUser `json:"created_by"`
|
|
LastEditedTime time.Time `json:"last_edited_time"`
|
|
LastEditedBy BaseUser `json:"last_edited_by"`
|
|
URL string `json:"url"`
|
|
Title []RichText `json:"title"`
|
|
Properties DatabaseProperties `json:"properties"`
|
|
Parent Parent `json:"parent"`
|
|
Icon *Icon `json:"icon,omitempty"`
|
|
Cover *Cover `json:"cover,omitempty"`
|
|
Archived bool `json:"archived"`
|
|
}
|
|
|
|
// DatabaseProperties is a mapping of properties defined on a database.
|
|
type DatabaseProperties map[string]DatabaseProperty
|
|
|
|
// Database property metadata types.
|
|
type (
|
|
EmptyMetadata struct{}
|
|
NumberMetadata struct {
|
|
Format NumberFormat `json:"format"`
|
|
}
|
|
SelectMetadata struct {
|
|
Options []SelectOptions `json:"options"`
|
|
}
|
|
FormulaMetadata struct {
|
|
Expression string `json:"expression"`
|
|
}
|
|
RelationMetadata struct {
|
|
DatabaseID string `json:"database_id,omitempty"`
|
|
SyncedPropName string `json:"synced_property_name,omitempty"`
|
|
SyncedPropID string `json:"synced_property_id,omitempty"`
|
|
}
|
|
RollupMetadata struct {
|
|
RelationPropName string `json:"relation_property_name,omitempty"`
|
|
RelationPropID string `json:"relation_property_id,omitempty"`
|
|
RollupPropName string `json:"rollup_property_name,omitempty"`
|
|
RollupPropID string `json:"rollup_property_id,omitempty"`
|
|
Function RollupFunction `json:"function,omitempty"`
|
|
}
|
|
)
|
|
|
|
type RollupFunction string
|
|
|
|
const (
|
|
RollupFunctionCountAll RollupFunction = "count_all"
|
|
RollupFunctionCountValues RollupFunction = "count_values"
|
|
RollupFunctionCountUniqueValues RollupFunction = "count_unique_values"
|
|
RollupFunctionCountEmpty RollupFunction = "count_empty"
|
|
RollupFunctionCountNotEmpty RollupFunction = "count_not_empty"
|
|
RollupFunctionPercentEmpty RollupFunction = "percent_empty"
|
|
RollupFunctionPercentNotEmpty RollupFunction = "percent_not_empty"
|
|
RollupFunctionSum RollupFunction = "sum"
|
|
RollupFunctionAverage RollupFunction = "average"
|
|
RollupFunctionMedian RollupFunction = "median"
|
|
RollupFunctionMin RollupFunction = "min"
|
|
RollupFunctionMax RollupFunction = "max"
|
|
RollupFunctionRange RollupFunction = "range"
|
|
RollupFunctionShowOriginal RollupFunction = "show_original"
|
|
)
|
|
|
|
type SelectOptions struct {
|
|
ID string `json:"id,omitempty"`
|
|
Name string `json:"name,omitempty"`
|
|
Color Color `json:"color,omitempty"`
|
|
}
|
|
|
|
type FormulaResult struct {
|
|
Type FormulaResultType `json:"type"`
|
|
|
|
String *string `json:"string,omitempty"`
|
|
Number *float64 `json:"number,omitempty"`
|
|
Boolean *bool `json:"boolean,omitempty"`
|
|
Date *Date `json:"date,omitempty"`
|
|
}
|
|
|
|
type Relation struct {
|
|
ID string `json:"id"`
|
|
}
|
|
|
|
type RollupResult struct {
|
|
Type RollupResultType `json:"type"`
|
|
|
|
Number *float64 `json:"number,omitempty"`
|
|
Date *Date `json:"date,omitempty"`
|
|
Array []DatabasePageProperty `json:"array,omitempty"`
|
|
}
|
|
|
|
type People struct {
|
|
People []User `json:"people"`
|
|
}
|
|
|
|
type File struct {
|
|
Name string `json:"name"`
|
|
Type FileType `json:"type"`
|
|
|
|
File *FileFile `json:"file,omitempty"`
|
|
External *FileExternal `json:"external,omitempty"`
|
|
}
|
|
|
|
type DatabaseProperty struct {
|
|
ID string `json:"id,omitempty"`
|
|
Type DatabasePropertyType `json:"type"`
|
|
Name string `json:"name,omitempty"`
|
|
|
|
Title *EmptyMetadata `json:"title,omitempty"`
|
|
RichText *EmptyMetadata `json:"rich_text,omitempty"`
|
|
Date *EmptyMetadata `json:"date,omitempty"`
|
|
People *EmptyMetadata `json:"people,omitempty"`
|
|
Files *EmptyMetadata `json:"files,omitempty"`
|
|
Checkbox *EmptyMetadata `json:"checkbox,omitempty"`
|
|
URL *EmptyMetadata `json:"url,omitempty"`
|
|
Email *EmptyMetadata `json:"email,omitempty"`
|
|
PhoneNumber *EmptyMetadata `json:"phone_number,omitempty"`
|
|
CreatedTime *EmptyMetadata `json:"created_time,omitempty"`
|
|
CreatedBy *EmptyMetadata `json:"created_by,omitempty"`
|
|
LastEditedTime *EmptyMetadata `json:"last_edited_time,omitempty"`
|
|
LastEditedBy *EmptyMetadata `json:"last_edited_by,omitempty"`
|
|
|
|
Number *NumberMetadata `json:"number,omitempty"`
|
|
Select *SelectMetadata `json:"select,omitempty"`
|
|
MultiSelect *SelectMetadata `json:"multi_select,omitempty"`
|
|
Formula *FormulaMetadata `json:"formula,omitempty"`
|
|
Relation *RelationMetadata `json:"relation,omitempty"`
|
|
Rollup *RollupMetadata `json:"rollup,omitempty"`
|
|
}
|
|
|
|
// DatabaseQuery is used for quering a database.
|
|
type DatabaseQuery struct {
|
|
Filter *DatabaseQueryFilter `json:"filter,omitempty"`
|
|
Sorts []DatabaseQuerySort `json:"sorts,omitempty"`
|
|
StartCursor string `json:"start_cursor,omitempty"`
|
|
PageSize int `json:"page_size,omitempty"`
|
|
}
|
|
|
|
// DatabaseQueryResponse contains the results and pagination data from a query request.
|
|
type DatabaseQueryResponse struct {
|
|
Results []Page `json:"results"`
|
|
HasMore bool `json:"has_more"`
|
|
NextCursor *string `json:"next_cursor"`
|
|
}
|
|
|
|
// DatabaseQueryFilter is used to filter database contents.
|
|
// See: https://developers.notion.com/reference/post-database-query#post-database-query-filter
|
|
type DatabaseQueryFilter struct {
|
|
Property string `json:"property,omitempty"`
|
|
|
|
DatabaseQueryPropertyFilter
|
|
|
|
Timestamp Timestamp `json:"timestamp,omitempty"`
|
|
Or []DatabaseQueryFilter `json:"or,omitempty"`
|
|
And []DatabaseQueryFilter `json:"and,omitempty"`
|
|
}
|
|
|
|
type DatabaseQueryPropertyFilter struct {
|
|
Title *TextPropertyFilter `json:"title,omitempty"`
|
|
RichText *TextPropertyFilter `json:"rich_text,omitempty"`
|
|
URL *TextPropertyFilter `json:"url,omitempty"`
|
|
Email *TextPropertyFilter `json:"email,omitempty"`
|
|
PhoneNumber *TextPropertyFilter `json:"phone_number,omitempty"`
|
|
|
|
Date *DatePropertyFilter `json:"date,omitempty"`
|
|
CreatedTime *DatePropertyFilter `json:"created_time,omitempty"`
|
|
LastEditedTime *DatePropertyFilter `json:"last_edited_time,omitempty"`
|
|
|
|
Number *NumberDatabaseQueryFilter `json:"number,omitempty"`
|
|
Checkbox *CheckboxDatabaseQueryFilter `json:"checkbox,omitempty"`
|
|
Select *SelectDatabaseQueryFilter `json:"select,omitempty"`
|
|
MultiSelect *MultiSelectDatabaseQueryFilter `json:"multi_select,omitempty"`
|
|
People *PeopleDatabaseQueryFilter `json:"people,omitempty"`
|
|
Files *FilesDatabaseQueryFilter `json:"files,omitempty"`
|
|
Relation *RelationDatabaseQueryFilter `json:"relation,omitempty"`
|
|
Formula *FormulaDatabaseQueryFilter `json:"formula,omitempty"`
|
|
Rollup *RollupDatabaseQueryFilter `json:"rollup,omitempty"`
|
|
|
|
CreatedBy *PeopleDatabaseQueryFilter `json:"created_by,omitempty"`
|
|
LastEditedBy *PeopleDatabaseQueryFilter `json:"last_edited_by,omitempty"`
|
|
}
|
|
|
|
type Timestamp string
|
|
|
|
const (
|
|
TimestampCreatedTime = "created_time"
|
|
TimestampLastEditedTime = "last_edited_time"
|
|
)
|
|
|
|
type TextPropertyFilter struct {
|
|
Equals string `json:"equals,omitempty"`
|
|
DoesNotEqual string `json:"does_not_equal,omitempty"`
|
|
Contains string `json:"contains,omitempty"`
|
|
DoesNotContain string `json:"does_not_contain,omitempty"`
|
|
StartsWith string `json:"starts_with,omitempty"`
|
|
EndsWith string `json:"ends_with,omitempty"`
|
|
IsEmpty bool `json:"is_empty,omitempty"`
|
|
IsNotEmpty bool `json:"is_not_empty,omitempty"`
|
|
}
|
|
|
|
type NumberDatabaseQueryFilter struct {
|
|
Equals *int `json:"equals,omitempty"`
|
|
DoesNotEqual *int `json:"does_not_equal,omitempty"`
|
|
GreaterThan *int `json:"greater_than,omitempty"`
|
|
LessThan *int `json:"less_than,omitempty"`
|
|
GreaterThanOrEqualTo *int `json:"greater_than_or_equal_to,omitempty"`
|
|
LessThanOrEqualTo *int `json:"less_than_or_equal_to,omitempty"`
|
|
IsEmpty bool `json:"is_empty,omitempty"`
|
|
IsNotEmpty bool `json:"is_not_empty,omitempty"`
|
|
}
|
|
|
|
type CheckboxDatabaseQueryFilter struct {
|
|
Equals *bool `json:"equals,omitempty"`
|
|
DoesNotEqual *bool `json:"does_not_equal,omitempty"`
|
|
}
|
|
|
|
type SelectDatabaseQueryFilter struct {
|
|
Equals string `json:"equals,omitempty"`
|
|
DoesNotEqual string `json:"does_not_equal,omitempty"`
|
|
IsEmpty bool `json:"is_empty,omitempty"`
|
|
IsNotEmpty bool `json:"is_not_empty,omitempty"`
|
|
}
|
|
|
|
type MultiSelectDatabaseQueryFilter struct {
|
|
Contains string `json:"contains,omitempty"`
|
|
DoesNotContain string `json:"does_not_contain,omitempty"`
|
|
IsEmpty bool `json:"is_empty,omitempty"`
|
|
IsNotEmpty bool `json:"is_not_empty,omitempty"`
|
|
}
|
|
|
|
type DatePropertyFilter struct {
|
|
Equals *time.Time `json:"equals,omitempty"`
|
|
Before *time.Time `json:"before,omitempty"`
|
|
After *time.Time `json:"after,omitempty"`
|
|
OnOrBefore *time.Time `json:"on_or_before,omitempty"`
|
|
OnOrAfter *time.Time `json:"on_or_after,omitempty"`
|
|
IsEmpty bool `json:"is_empty,omitempty"`
|
|
IsNotEmpty bool `json:"is_not_empty,omitempty"`
|
|
PastWeek *struct{} `json:"past_week,omitempty"`
|
|
PastMonth *struct{} `json:"past_month,omitempty"`
|
|
PastYear *struct{} `json:"past_year,omitempty"`
|
|
NextWeek *struct{} `json:"next_week,omitempty"`
|
|
NextMonth *struct{} `json:"next_month,omitempty"`
|
|
NextYear *struct{} `json:"next_year,omitempty"`
|
|
}
|
|
|
|
type PeopleDatabaseQueryFilter struct {
|
|
Contains string `json:"contains,omitempty"`
|
|
DoesNotContain string `json:"does_not_contain,omitempty"`
|
|
IsEmpty bool `json:"is_empty,omitempty"`
|
|
IsNotEmpty bool `json:"is_not_empty,omitempty"`
|
|
}
|
|
|
|
type FilesDatabaseQueryFilter struct {
|
|
IsEmpty bool `json:"is_empty,omitempty"`
|
|
IsNotEmpty bool `json:"is_not_empty,omitempty"`
|
|
}
|
|
|
|
type RelationDatabaseQueryFilter struct {
|
|
Contains string `json:"contains,omitempty"`
|
|
DoesNotContain string `json:"does_not_contain,omitempty"`
|
|
IsEmpty bool `json:"is_empty,omitempty"`
|
|
IsNotEmpty bool `json:"is_not_empty,omitempty"`
|
|
}
|
|
|
|
type RollupDatabaseQueryFilter struct {
|
|
Any *DatabaseQueryPropertyFilter `json:"any,omitempty"`
|
|
Every *DatabaseQueryPropertyFilter `json:"every,omitempty"`
|
|
None *DatabaseQueryPropertyFilter `json:"none,omitempty"`
|
|
Number *NumberDatabaseQueryFilter `json:"number,omitempty"`
|
|
Date *DatePropertyFilter `json:"date,omitempty"`
|
|
}
|
|
|
|
type FormulaDatabaseQueryFilter struct {
|
|
String *TextPropertyFilter `json:"string,omitempty"`
|
|
Checkbox *CheckboxDatabaseQueryFilter `json:"checkbox,omitempty"`
|
|
Number *NumberDatabaseQueryFilter `json:"number,omitempty"`
|
|
Date *DatePropertyFilter `json:"date,omitempty"`
|
|
}
|
|
|
|
type DatabaseQuerySort struct {
|
|
Property string `json:"property,omitempty"`
|
|
Timestamp SortTimestamp `json:"timestamp,omitempty"`
|
|
Direction SortDirection `json:"direction,omitempty"`
|
|
}
|
|
|
|
// CreateDatabaseParams are the params used for creating a database.
|
|
type CreateDatabaseParams struct {
|
|
ParentPageID string
|
|
Title []RichText
|
|
Properties DatabaseProperties
|
|
Icon *Icon
|
|
Cover *Cover
|
|
}
|
|
|
|
type (
|
|
DatabasePropertyType string
|
|
NumberFormat string
|
|
FormulaResultType string
|
|
RollupResultType string
|
|
SortTimestamp string
|
|
SortDirection string
|
|
)
|
|
|
|
const (
|
|
// Database property type enums.
|
|
DBPropTypeTitle DatabasePropertyType = "title"
|
|
DBPropTypeRichText DatabasePropertyType = "rich_text"
|
|
DBPropTypeNumber DatabasePropertyType = "number"
|
|
DBPropTypeSelect DatabasePropertyType = "select"
|
|
DBPropTypeMultiSelect DatabasePropertyType = "multi_select"
|
|
DBPropTypeDate DatabasePropertyType = "date"
|
|
DBPropTypePeople DatabasePropertyType = "people"
|
|
DBPropTypeFiles DatabasePropertyType = "files"
|
|
DBPropTypeCheckbox DatabasePropertyType = "checkbox"
|
|
DBPropTypeURL DatabasePropertyType = "url"
|
|
DBPropTypeEmail DatabasePropertyType = "email"
|
|
DBPropTypePhoneNumber DatabasePropertyType = "phone_number"
|
|
DBPropTypeFormula DatabasePropertyType = "formula"
|
|
DBPropTypeRelation DatabasePropertyType = "relation"
|
|
DBPropTypeRollup DatabasePropertyType = "rollup"
|
|
DBPropTypeCreatedTime DatabasePropertyType = "created_time"
|
|
DBPropTypeCreatedBy DatabasePropertyType = "created_by"
|
|
DBPropTypeLastEditedTime DatabasePropertyType = "last_edited_time"
|
|
DBPropTypeLastEditedBy DatabasePropertyType = "last_edited_by"
|
|
|
|
// Used for paginated property values.
|
|
// See: https://developers.notion.com/reference/property-item-object#paginated-property-values
|
|
DBPropTypePropertyItem DatabasePropertyType = "property_item"
|
|
|
|
// Number format enums.
|
|
NumberFormatNumber NumberFormat = "number"
|
|
NumberFormatNumberWithCommas NumberFormat = "number_with_commas"
|
|
NumberFormatPercent NumberFormat = "percent"
|
|
NumberFormatDollar NumberFormat = "dollar"
|
|
NumberFormatEuro NumberFormat = "euro"
|
|
NumberFormatPound NumberFormat = "pound"
|
|
NumberFormatPonud NumberFormat = "yen"
|
|
NumberFormatRuble NumberFormat = "ruble"
|
|
NumberFormatRupee NumberFormat = "rupee"
|
|
NumberFormatWon NumberFormat = "won"
|
|
NumberFormatYuan NumberFormat = "yuan"
|
|
NumberFormatHongKongDollar NumberFormat = "hong_kong_dollar"
|
|
NumberFormatNewZealandDollar NumberFormat = "new_zealand_dollar"
|
|
NumberFormatKrona NumberFormat = "krona"
|
|
NumberFormatNorwegianKrone NumberFormat = "norwegian_krone"
|
|
NumberFormatMexicanPeso NumberFormat = "mexican_peso"
|
|
NumberFormatRand NumberFormat = "rand"
|
|
NumberFormatNewTaiwanDollar NumberFormat = "new_taiwan_dollar"
|
|
NumberFormatDanishKrone NumberFormat = "danish_krone"
|
|
NumberFormatZloty NumberFormat = "zloty"
|
|
NumberFormatBaht NumberFormat = "baht"
|
|
NumberFormatForint NumberFormat = "forint"
|
|
NumberFormatKoruna NumberFormat = "koruna"
|
|
NumberFormatShekel NumberFormat = "shekel"
|
|
NumberFormatChileanPeso NumberFormat = "chilean_peso"
|
|
NumberFormatPhilippinePeso NumberFormat = "philippine_peso"
|
|
NumberFormatDirham NumberFormat = "dirham"
|
|
NumberFormatColombianPeso NumberFormat = "colombian_peso"
|
|
NumberFormatRiyal NumberFormat = "riyal"
|
|
NumberFormatRinggit NumberFormat = "ringgit"
|
|
NumberFormatLeu NumberFormat = "leu"
|
|
|
|
// Formula result type enums.
|
|
FormulaResultTypeString FormulaResultType = "string"
|
|
FormulaResultTypeNumber FormulaResultType = "number"
|
|
FormulaResultTypeBoolean FormulaResultType = "boolean"
|
|
FormulaResultTypeDate FormulaResultType = "date"
|
|
|
|
// Rollup result type enums.
|
|
RollupResultTypeNumber RollupResultType = "number"
|
|
RollupResultTypeDate RollupResultType = "date"
|
|
RollupResultTypeArray RollupResultType = "array"
|
|
RollupResultTypeUnsupported RollupResultType = "unsupported"
|
|
RollupResultTypeIncomplete RollupResultType = "incomplete"
|
|
|
|
// Sort timestamp enums.
|
|
SortTimeStampCreatedTime SortTimestamp = "created_time"
|
|
SortTimeStampLastEditedTime SortTimestamp = "last_edited_time"
|
|
|
|
// Sort direction enums.
|
|
SortDirAsc SortDirection = "ascending"
|
|
SortDirDesc SortDirection = "descending"
|
|
)
|
|
|
|
// Metadata returns the underlying property metadata, based on its `type` field.
|
|
// When type is unknown/unmapped or doesn't have additional properies, `nil` is returned.
|
|
func (prop DatabaseProperty) Metadata() interface{} {
|
|
switch prop.Type {
|
|
case "title":
|
|
return prop.Title
|
|
case "number":
|
|
return prop.Number
|
|
case "select":
|
|
return prop.Select
|
|
case "multi_select":
|
|
return prop.MultiSelect
|
|
case "formula":
|
|
return prop.Formula
|
|
case "relation":
|
|
return prop.Relation
|
|
case "rollup":
|
|
return prop.Rollup
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// Value returns the underlying result value of an evaluated formula.
|
|
func (f FormulaResult) Value() interface{} {
|
|
switch f.Type {
|
|
case FormulaResultTypeString:
|
|
return f.String
|
|
case FormulaResultTypeNumber:
|
|
return f.Number
|
|
case FormulaResultTypeBoolean:
|
|
return f.Boolean
|
|
case FormulaResultTypeDate:
|
|
return f.Date
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// Value returns the underlying result value of an evaluated rollup.
|
|
func (r RollupResult) Value() interface{} {
|
|
switch r.Type {
|
|
case RollupResultTypeNumber:
|
|
return r.Number
|
|
case RollupResultTypeDate:
|
|
return r.Date
|
|
case RollupResultTypeArray:
|
|
return r.Array
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// Validate validates params for creating a database.
|
|
func (p CreateDatabaseParams) Validate() error {
|
|
if p.ParentPageID == "" {
|
|
return errors.New("parent page ID is required")
|
|
}
|
|
if p.Properties == nil {
|
|
return errors.New("database properties are required")
|
|
}
|
|
if p.Icon != nil {
|
|
if err := p.Icon.Validate(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if p.Cover != nil {
|
|
if err := p.Cover.Validate(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// MarshalJSON implements json.Marshaler.
|
|
func (p CreateDatabaseParams) MarshalJSON() ([]byte, error) {
|
|
type CreatePageParamsDTO struct {
|
|
Parent Parent `json:"parent"`
|
|
Title []RichText `json:"title,omitempty"`
|
|
Properties DatabaseProperties `json:"properties"`
|
|
Icon *Icon `json:"icon,omitempty"`
|
|
Cover *Cover `json:"cover,omitempty"`
|
|
}
|
|
|
|
parent := Parent{
|
|
Type: ParentTypePage,
|
|
PageID: p.ParentPageID,
|
|
}
|
|
|
|
dto := CreatePageParamsDTO{
|
|
Parent: parent,
|
|
Title: p.Title,
|
|
Properties: p.Properties,
|
|
Icon: p.Icon,
|
|
Cover: p.Cover,
|
|
}
|
|
|
|
return json.Marshal(dto)
|
|
}
|
|
|
|
// UpdateDatabaseParams are the params used for updating a database.
|
|
type UpdateDatabaseParams struct {
|
|
Title []RichText `json:"title,omitempty"`
|
|
Properties map[string]*DatabaseProperty `json:"properties,omitempty"`
|
|
Icon *Icon `json:"icon,omitempty"`
|
|
Cover *Cover `json:"cover,omitempty"`
|
|
Archived *bool `json:"archived,omitempty"`
|
|
}
|
|
|
|
// Validate validates params for updating a database.
|
|
func (p UpdateDatabaseParams) Validate() error {
|
|
if len(p.Title) == 0 && len(p.Properties) == 0 {
|
|
return errors.New("either title or properties are required")
|
|
}
|
|
if p.Icon != nil {
|
|
if err := p.Icon.Validate(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if p.Cover != nil {
|
|
if err := p.Cover.Validate(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|