From d733edb9b0c5e5c7a6eebff1a0b93cf5d9ad1199 Mon Sep 17 00:00:00 2001 From: codewithearh Date: Thu, 25 Dec 2025 21:31:19 +0100 Subject: [PATCH] first commit --- README.md | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 5 ++++ go.sum | 2 ++ mapper.go | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 185 insertions(+) create mode 100644 README.md create mode 100644 go.mod create mode 100644 go.sum create mode 100644 mapper.go diff --git a/README.md b/README.md new file mode 100644 index 0000000..1e4928e --- /dev/null +++ b/README.md @@ -0,0 +1,90 @@ +# Notion Mapper + +Libreria Go per mappare pagine e proprietà di Notion a struct Go in modo type-safe e configurabile. + +## Caratteristiche + +- **Type-safe**: Mappa le proprietà di Notion a struct Go con generics +- **Configurabile**: Definisci mapping personalizzati per ogni proprietà +- **Helper functions**: Funzioni di utilità per estrarre valori comuni da proprietà Notion +- **Supporto completo**: Supporta proprietà di pagina e proprietà individuali + +## Installazione + +```bash +go get ceccgit.duckdns.org/simone/notion-mapper +``` + +## Utilizzo + +```go +package main + +import ( + "fmt" + "github.com/jomei/notionapi" + "ceccgit.duckdns.org/simone/notion-mapper" +) + +type Task struct { + ID string + Title string + Priority string + DueDate string +} + +func main() { + // Crea un nuovo mapper per la struct Task + mapper := notionmapper.NewMapper[Task]() + + // Configura i mapping + mapper. + ForMember("Title", func(prop notionapi.Property, dest *Task) { + dest.Title = notionmapper.ExtractTitle(prop) + }). + ForMember("Priority", func(prop notionapi.Property, dest *Task) { + dest.Priority = notionmapper.ExtractSelect(prop) + }). + ForMember("Due Date", func(prop notionapi.Property, dest *Task) { + dest.DueDate = notionmapper.ExtractRichText(prop) + }). + ForPage(func(page notionapi.Page, dest *Task) { + dest.ID = page.ID.String() + }) + + // Esempio di mapping da una pagina Notion + // page := notionapi.Page{...} // la tua pagina Notion + // task := mapper.MapFrom(page) + + fmt.Println("Mapper configurato!") +} +``` + +## API + +### `NewMapper[TDest]()` +Crea un nuovo mapper per il tipo di destinazione specificato. + +### `ForMember(propertyName, setter)` +Configura come mappare una property specifica di Notion. + +### `ForPage(setter)` +Configura un mapping che ha accesso all'intera pagina (utile per ID, timestamps, etc.). + +### `MapFrom(page)` +Esegue il mapping da una pagina Notion alla struct di destinazione. + +## Helper Functions + +- `ExtractTitle(prop)` - Estrae testo da TitleProperty +- `ExtractRichText(prop)` - Estrae testo da RichTextProperty +- `ExtractNumber(prop)` - Estrae numero da NumberProperty +- `ExtractSelect(prop)` - Estrae valore da SelectProperty + +## Dipendenze + +- `github.com/jomei/notionapi` v1.13.3 + +## Licenza + +MIT \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..da7fb7f --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module ceccgit.duckdns.org/simone/notion-mapper + +go 1.25.5 + +require github.com/jomei/notionapi v1.13.3 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..34ae76f --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/jomei/notionapi v1.13.3 h1:pzEN+pVe1T0FjH85sP9TCqqe58rFRL+Fj+F5yvyBNw4= +github.com/jomei/notionapi v1.13.3/go.mod h1:BqzP6JBddpBnXvMSIxiR5dCoCjKngmz5QNl1ONDlDoM= diff --git a/mapper.go b/mapper.go new file mode 100644 index 0000000..7ef4ed8 --- /dev/null +++ b/mapper.go @@ -0,0 +1,88 @@ +package notionmapper + +import "github.com/jomei/notionapi" + +// PropertyExtractor è una funzione che estrae un valore da una Property di Notion +type PropertyExtractor[T any] func(prop notionapi.Property) T + +// NotionMapper mappa le properties di Notion a una struct Go +type NotionMapper[TDest any] struct { + propertyMappings map[string]func(notionapi.Property, *TDest) + pageMappings []func(notionapi.Page, *TDest) +} + +// NewMapper crea un nuovo mapper per il tipo di destinazione specificato +func NewMapper[TDest any]() *NotionMapper[TDest] { + return &NotionMapper[TDest]{ + propertyMappings: make(map[string]func(notionapi.Property, *TDest)), + pageMappings: make([]func(notionapi.Page, *TDest), 0), + } +} + +// ForMember configura come mappare una property specifica +// propertyName: nome della property in Notion +// setter: funzione che setta il valore sulla struct di destinazione usando la Property +func (nm *NotionMapper[TDest]) ForMember(propertyName string, setter func(prop notionapi.Property, dest *TDest)) *NotionMapper[TDest] { + nm.propertyMappings[propertyName] = setter + return nm +} + +// ForPage configura un mapping che ha accesso all'intera Page (utile per ID, timestamps, etc.) +// setter: funzione che setta il valore sulla struct di destinazione usando la Page completa +func (nm *NotionMapper[TDest]) ForPage(setter func(page notionapi.Page, dest *TDest)) *NotionMapper[TDest] { + nm.pageMappings = append(nm.pageMappings, setter) + return nm +} + +// MapFrom mappa una Page di Notion alla struct di destinazione +func (nm *NotionMapper[TDest]) MapFrom(page notionapi.Page) TDest { + var dest TDest + + // Applica i mapping delle properties + for propName, mapping := range nm.propertyMappings { + if prop, ok := page.Properties[propName]; ok { + mapping(prop, &dest) + } + } + + // Applica i mapping che richiedono l'intera page + for _, mapping := range nm.pageMappings { + mapping(page, &dest) + } + + return dest +} + +// Helper functions per estrarre valori comuni da Notion properties + +// ExtractTitle estrae il testo da una TitleProperty +func ExtractTitle(prop notionapi.Property) string { + if title, ok := prop.(*notionapi.TitleProperty); ok && len(title.Title) > 0 { + return title.Title[0].PlainText + } + return "" +} + +// ExtractRichText estrae il testo da una RichTextProperty +func ExtractRichText(prop notionapi.Property) string { + if richText, ok := prop.(*notionapi.RichTextProperty); ok && len(richText.RichText) > 0 { + return richText.RichText[0].PlainText + } + return "" +} + +// ExtractNumber estrae un numero da una NumberProperty +func ExtractNumber(prop notionapi.Property) float64 { + if num, ok := prop.(*notionapi.NumberProperty); ok { + return num.Number + } + return 0 +} + +// ExtractSelect estrae il valore da una SelectProperty +func ExtractSelect(prop notionapi.Property) string { + if sel, ok := prop.(*notionapi.SelectProperty); ok && sel.Select.Name != "" { + return sel.Select.Name + } + return "" +}