2026-01-30 09:36:58 +01:00
|
|
|
package bookstack
|
|
|
|
|
|
|
|
|
|
import (
|
2026-01-30 09:45:35 +01:00
|
|
|
"errors"
|
2026-01-30 09:36:58 +01:00
|
|
|
"net/http"
|
2026-01-30 09:45:35 +01:00
|
|
|
"strings"
|
2026-01-30 09:36:58 +01:00
|
|
|
"time"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Config holds configuration for the Bookstack API client.
|
|
|
|
|
type Config struct {
|
|
|
|
|
// BaseURL is the base URL of the Bookstack instance (e.g., "https://docs.example.com")
|
|
|
|
|
BaseURL string
|
|
|
|
|
|
|
|
|
|
// TokenID is the Bookstack API token ID
|
|
|
|
|
TokenID string
|
|
|
|
|
|
|
|
|
|
// TokenSecret is the Bookstack API token secret
|
|
|
|
|
TokenSecret string
|
|
|
|
|
|
|
|
|
|
// HTTPClient is the HTTP client to use for requests.
|
|
|
|
|
// If nil, a default client with 30s timeout will be used.
|
|
|
|
|
HTTPClient *http.Client
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Client is the main Bookstack API client.
|
|
|
|
|
type Client struct {
|
|
|
|
|
baseURL string
|
|
|
|
|
tokenID string
|
|
|
|
|
tokenSecret string
|
|
|
|
|
httpClient *http.Client
|
|
|
|
|
|
|
|
|
|
// Service instances
|
2026-01-30 09:55:02 +01:00
|
|
|
Attachments *AttachmentsService
|
|
|
|
|
Books *BooksService
|
|
|
|
|
Chapters *ChaptersService
|
2026-01-30 09:55:44 +01:00
|
|
|
Comments *CommentsService
|
2026-01-30 09:55:02 +01:00
|
|
|
Pages *PagesService
|
|
|
|
|
Search *SearchService
|
|
|
|
|
Shelves *ShelvesService
|
2026-01-30 09:36:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewClient creates a new Bookstack API client.
|
2026-01-30 09:45:35 +01:00
|
|
|
// Returns an error if BaseURL, TokenID, or TokenSecret are empty.
|
|
|
|
|
func NewClient(cfg Config) (*Client, error) {
|
|
|
|
|
var errs []string
|
|
|
|
|
if cfg.BaseURL == "" {
|
|
|
|
|
errs = append(errs, "BaseURL is required")
|
|
|
|
|
}
|
|
|
|
|
if cfg.TokenID == "" {
|
|
|
|
|
errs = append(errs, "TokenID is required")
|
|
|
|
|
}
|
|
|
|
|
if cfg.TokenSecret == "" {
|
|
|
|
|
errs = append(errs, "TokenSecret is required")
|
|
|
|
|
}
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
return nil, errors.New(strings.Join(errs, "; "))
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-30 09:36:58 +01:00
|
|
|
httpClient := cfg.HTTPClient
|
|
|
|
|
if httpClient == nil {
|
|
|
|
|
httpClient = &http.Client{
|
|
|
|
|
Timeout: 30 * time.Second,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c := &Client{
|
2026-01-30 09:45:35 +01:00
|
|
|
baseURL: strings.TrimRight(cfg.BaseURL, "/"),
|
2026-01-30 09:36:58 +01:00
|
|
|
tokenID: cfg.TokenID,
|
|
|
|
|
tokenSecret: cfg.TokenSecret,
|
|
|
|
|
httpClient: httpClient,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Initialize services
|
2026-01-30 09:55:02 +01:00
|
|
|
c.Attachments = &AttachmentsService{client: c}
|
2026-01-30 09:36:58 +01:00
|
|
|
c.Books = &BooksService{client: c}
|
|
|
|
|
c.Chapters = &ChaptersService{client: c}
|
2026-01-30 09:55:44 +01:00
|
|
|
c.Comments = &CommentsService{client: c}
|
2026-01-30 09:55:02 +01:00
|
|
|
c.Pages = &PagesService{client: c}
|
2026-01-30 09:36:58 +01:00
|
|
|
c.Search = &SearchService{client: c}
|
2026-01-30 09:55:02 +01:00
|
|
|
c.Shelves = &ShelvesService{client: c}
|
2026-01-30 09:36:58 +01:00
|
|
|
|
2026-01-30 09:45:35 +01:00
|
|
|
return c, nil
|
2026-01-30 09:36:58 +01:00
|
|
|
}
|