Files
onspring-api-sdk-go/fields.go
T

242 lines
6.0 KiB
Go
Raw Permalink Normal View History

2026-03-25 16:27:06 -05:00
package onspring
import (
"context"
"encoding/json"
"fmt"
"iter"
"net/http"
)
const (
fieldsPath = "/fields"
)
// FieldsEndpoint provides access to fields in an Onspring instance.
type FieldsEndpoint struct {
client *Client
}
// Field represents an Onspring field
type Field struct {
Id int `json:"id"`
AppId int `json:"appId"`
Name string `json:"name"`
Type string `json:"type"`
Status string `json:"status"`
IsRequired bool `json:"isRequired"`
IsUnique bool `json:"isUnique"`
TypeData any `json:"-"`
}
// FormulaField represents a formula field type in Onspring
type FormulaField struct {
2026-03-26 16:59:49 -05:00
OutputType string `json:"outputType"`
Values []ListValue `json:"values"`
2026-03-25 16:27:06 -05:00
}
// ReferenceField represents a reference field type in Onspring
type ReferenceField struct {
Multiplicity string `json:"multiplicity"`
ReferenceAppId string `json:"referenceAppId"`
}
2026-03-26 16:59:49 -05:00
// ListValue represents a value option within a list field in Onspring.
type ListValue struct {
Id string `json:"id"`
Name string `json:"name"`
SortOrder int `json:"sortOrder"`
NumericValue float64 `json:"numericValue"`
Color string `json:"color"`
}
2026-03-25 16:27:06 -05:00
// ListField represents a list field type in Onspring
type ListField struct {
2026-03-26 16:59:49 -05:00
Multiplicity string `json:"multiplicity"`
Values []ListValue `json:"values"`
ListId int `json:"listId"`
2026-03-25 16:27:06 -05:00
}
// UnmarshalJSON implements the json.Unmarshaler interface for Field.
// This allows for custom deserialization logic based on the 'Type' field.
func (f *Field) UnmarshalJSON(data []byte) error {
type Alias Field
aux := &struct {
*Alias
}{
Alias: (*Alias)(f),
}
if err := json.Unmarshal(data, aux); err != nil {
return err
}
switch f.Type {
case "Formula":
var formulaField FormulaField
if err := json.Unmarshal(data, &formulaField); err != nil {
return err
}
f.TypeData = formulaField
case "Reference":
var referenceField ReferenceField
if err := json.Unmarshal(data, &referenceField); err != nil {
return err
}
f.TypeData = referenceField
case "List":
var listField ListField
if err := json.Unmarshal(data, &listField); err != nil {
return err
}
f.TypeData = listField
default:
}
return nil
}
// FieldBatch represents a batch of Onspring fields
type FieldBatch struct {
Count int `json:"count"`
Items []Field `json:"items"`
}
// Get retrieves a field from the Onspring API.
//
// Parameters:
// - ctx: The context for the request
// - id: The id of the field to retrieve
//
// Returns:
// - Field: A field
// - error: An error if the request fails
func (f *FieldsEndpoint) Get(ctx context.Context, id int) (Field, error) {
path := fmt.Sprintf("%s/id/%d", fieldsPath, id)
req, requestCreationErr := f.client.newRequest(ctx, http.MethodGet, path, nil, nil)
var field Field
if requestCreationErr != nil {
return field, requestCreationErr
}
responseErr := f.client.doWithJsonResponse(req, &field)
if responseErr != nil {
return field, responseErr
}
return field, nil
}
// GetMany retrieves a batch of fields from the Onspring API.
//
// Parameters:
// - ctx: The context for the request
// - ids: The ids of the fields to retrieve
//
// Returns:
// - FieldBatch: A batch of fields
// - error: An error if the request fails
func (f *FieldsEndpoint) GetMany(ctx context.Context, ids []int) (FieldBatch, error) {
path := fmt.Sprintf("%s/batch-get", fieldsPath)
req, requestCreationErr := f.client.newRequest(ctx, http.MethodPost, path, nil, ids)
var fieldBatch FieldBatch
if requestCreationErr != nil {
return fieldBatch, requestCreationErr
}
responseErr := f.client.doWithJsonResponse(req, &fieldBatch)
if responseErr != nil {
return fieldBatch, responseErr
}
return fieldBatch, nil
}
// List retrieves a paginated list of fields from the Onspring API.
//
// Parameters:
// - ctx: The context for the request
// - appId: The id of the app to retrieve fields for
// - pagingOpts: Optional paging configuration functions (e.g., ForPageNumber, WithPageSize)
//
// Returns:
// - Page[Field]: A page of fields with pagination metadata
// - error: An error if the request fails
func (f *FieldsEndpoint) List(ctx context.Context, appId int, pagingOpts ...PagingOption) (Page[Field], error) {
pagingRequest := createPagingRequest(pagingOpts)
path := fmt.Sprintf("%s/appId/%d", fieldsPath, appId)
req, requestCreationErr := f.client.newRequest(ctx, http.MethodGet, path, pagingRequest.ToParams(), nil)
var page Page[Field]
if requestCreationErr != nil {
return page, requestCreationErr
}
responseErr := f.client.doWithJsonResponse(req, &page)
if responseErr != nil {
return page, responseErr
}
return page, nil
}
// ListAll returns an iterator that yields all Fields for an app across all pages.
// It automatically handles pagination by making sequential calls to List
// until all items have been retrieved or the caller stops the iteration.
//
// The iterator yields each Field and any error encountered during fetching.
// If an error occurs during a page request, the error is yielded and
// iteration terminates.
//
// Parameters:
// - ctx: The context for the request
// - appId: The id of the app to retrieve fields for
// - pagingOpts: Optional paging configuration functions (e.g., ForPageNumber, WithPageSize)
//
// Returns:
// - iter.Seq2[Field, error]: An iterator yielding:
// - Field: The individual field record.
// - error: An error if a specific page request fails during iteration.
func (f *FieldsEndpoint) ListAll(ctx context.Context, appId int, pagingOpts ...PagingOption) iter.Seq2[Field, error] {
return func(yield func(Field, error) bool) {
pagingRequest := createPagingRequest(pagingOpts)
for {
page, err := f.List(ctx, appId, ForPageNumber(pagingRequest.PageNumber), WithPageSize(pagingRequest.PageSize))
if err != nil {
yield(Field{}, err)
return
}
for _, item := range page.Items {
if !yield(item, nil) {
return
}
}
if page.PageNumber >= page.TotalPages {
break
}
pagingRequest.PageNumber++
}
}
}