provider

package
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 25, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package provider defines the normalized Amazon-Shopping data schema and the pluggable backend interface. The output types here ARE the append-only output contract (spec.md "Output schema") — every backend normalizes into them.

This file ships only the interface + types + a stub backend so the skeleton compiles, runs, and is testable offline. cli-implement registers the real backends (SerpApi default, Rainforest, official Creators API) and wires keyring auth.

Index

Constants

View Source
const (
	CapSearch     = "search"
	CapItem       = "item"
	CapOffers     = "offers"
	CapReviews    = "reviews"
	CapVariations = "variations"
	CapBrowse     = "browse"
)

Capability names the operations a backend can serve. Not all providers serve all capabilities (e.g. the official Creators API returns no review text).

View Source
const SchemaVersion = "1"

SchemaVersion is the output-contract version. Bump only for breaking field changes.

Variables

This section is empty.

Functions

func Cooldown

func Cooldown(provider string) int

Cooldown reports the seconds remaining on a persistent block for a provider (0 if none).

func DefaultName

func DefaultName() string

DefaultName resolves the default backend: --provider flag handling happens in the cli layer; this is the fallback chain when no flag is given (RIVR_PROVIDER env, else the SerpApi third-party backend — the one with a renewing free tier and review text).

func Names

func Names() []string

Names returns the registered provider names, sorted.

func Supports

func Supports(p Provider, cap string) bool

Supports reports whether a provider advertises a capability.

Types

type BrowseNode

type BrowseNode struct {
	SchemaVersion string    `json:"schemaVersion"`
	Provider      string    `json:"provider"`
	NodeID        string    `json:"nodeId"`
	Name          string    `json:"name"`
	Ancestors     []string  `json:"ancestors"`
	Children      []NodeRef `json:"children"`
}

type Describable

type Describable interface {
	Describe() Descriptor
}

Describable backends expose a Descriptor.

type Descriptor

type Descriptor struct {
	Name         string   `json:"name"`
	Summary      string   `json:"summary"`
	Keyless      bool     `json:"keyless"`      // works with no credential?
	Auth         string   `json:"auth"`         // how you authenticate
	HostedSafe   bool     `json:"hostedSafe"`   // safe from cloud/datacenter IPs?
	Cost         string   `json:"cost"`         // rough cost (verify current pricing)
	Risk         string   `json:"risk"`         // headline risk
	ReviewsScope string   `json:"reviewsScope"` // full | sample | none
	Capabilities []string `json:"capabilities"` // search/item/offers/reviews/variations/browse
	Official     bool     `json:"official"`     // first-party Amazon API?
}

Descriptor is the published, machine-readable profile of a backend: what it can do, what it costs, and what it risks. It is the single source of truth behind `rivr provider list` AND the docs matrix, so capabilities/cost/risk can never drift between code and docs.

func Describe

func Describe(p Provider) Descriptor

Describe returns a backend's profile, falling back to a minimal one if it doesn't implement Describable.

type Item

type Item struct {
	SchemaVersion string   `json:"schemaVersion"`
	Provider      string   `json:"provider"`
	ASIN          string   `json:"asin"`
	Title         string   `json:"title"` // free text — fenced
	Brand         string   `json:"brand"`
	Price         float64  `json:"price"`
	Currency      string   `json:"currency"`
	Offers        []Offer  `json:"offers"`
	Features      []string `json:"features"`    // free text — fenced
	Description   string   `json:"description"` // free text — fenced
	Images        []string `json:"images"`
	Rating        float64  `json:"rating"`
	ReviewCount   int      `json:"reviewCount"`
	SalesRank     int      `json:"salesRank"`
	URL           string   `json:"url"`
}

type NodeRef

type NodeRef struct {
	NodeID string `json:"nodeId"`
	Name   string `json:"name"`
}

type Offer

type Offer struct {
	Price        float64 `json:"price"`
	Currency     string  `json:"currency"`
	Condition    string  `json:"condition"`
	Merchant     string  `json:"merchant"`
	Prime        bool    `json:"prime"`
	Availability string  `json:"availability"`
}

type OffersResult

type OffersResult struct {
	SchemaVersion string  `json:"schemaVersion"`
	Provider      string  `json:"provider"`
	ASIN          string  `json:"asin"`
	Offers        []Offer `json:"offers"`
	BuyboxPrice   float64 `json:"buyboxPrice"`
}

type Provider

type Provider interface {
	Name() string
	Capabilities() []string
	Configured() bool
	Search(ctx context.Context, query string, opts SearchOpts) (*SearchResult, error)
	GetItem(ctx context.Context, asin string, detailed bool) (*Item, error)
	GetOffers(ctx context.Context, asin string) (*OffersResult, error)
	GetReviews(ctx context.Context, asin, cursor string) (*ReviewsResult, error)
	GetVariations(ctx context.Context, asin string) (*VariationsResult, error)
	GetBrowseNode(ctx context.Context, nodeID string) (*BrowseNode, error)
}

Provider is the pluggable backend interface. cli-implement adds real implementations.

func All

func All() []Provider

All returns every registered provider (for `provider list`).

func Select

func Select(name string) (Provider, bool)

Select returns the named provider, or the default when name is empty.

type Refresher

type Refresher interface {
	Refresh(ctx context.Context) error
}

func RefresherFor

func RefresherFor(p Provider) (Refresher, bool)

type Review

type Review struct {
	Rating   int    `json:"rating"`
	Title    string `json:"title"` // free text — fenced
	Body     string `json:"body"`  // free text — fenced
	Author   string `json:"author"`
	Date     string `json:"date"`
	Verified bool   `json:"verified"`
}

type ReviewsResult

type ReviewsResult struct {
	SchemaVersion string `json:"schemaVersion"`
	Provider      string `json:"provider"`
	ASIN          string `json:"asin"`
	// Scope declares whether these are the full paginated reviews or an on-page sample,
	// so an agent never mistakes a partial set for the whole (contract: be honest about
	// partial results). "full" (e.g. Rainforest) or "sample" (e.g. SerpApi product page).
	Scope      string   `json:"scope,omitempty"`
	Reviews    []Review `json:"reviews"`
	NextCursor string   `json:"nextCursor,omitempty"`
	Truncated  bool     `json:"truncated,omitempty"`
}

type SearchItem

type SearchItem struct {
	ASIN        string  `json:"asin"`
	Title       string  `json:"title"` // free text — fenced in agent mode
	Price       float64 `json:"price"`
	Currency    string  `json:"currency"`
	Rating      float64 `json:"rating"`
	ReviewCount int     `json:"reviewCount"`
	Prime       bool    `json:"prime"`
	URL         string  `json:"url"`
	Image       string  `json:"image"`
	// Badges are trust/merchandising signals like "Amazon's Choice" or "Best Seller".
	// Population is provider-dependent (best-effort); absent means unknown, not "none".
	Badges []string `json:"badges,omitempty"`
}

type SearchOpts

type SearchOpts struct {
	Category  string
	MinRating float64
	Prime     bool
	MinPrice  float64
	MaxPrice  float64
	Sort      string
	Limit     int
	Cursor    string
}

SearchOpts carries the search filters (all optional).

type SearchResult

type SearchResult struct {
	SchemaVersion string       `json:"schemaVersion"`
	Provider      string       `json:"provider"`
	Query         string       `json:"query"`
	Items         []SearchItem `json:"items"`
	NextCursor    string       `json:"nextCursor,omitempty"`
	Count         int          `json:"count"`
	Limit         int          `json:"limit"`
	// Truncated is true when more results existed than --limit returned (the same signal as
	// the stderr note, but in-band so agents piping straight to jq don't miss it).
	Truncated bool `json:"truncated,omitempty"`
}

type TagAware

type TagAware interface {
	SetPartnerTag(tag string)
}

TagAware is implemented by backends that need the resolved Amazon Associates tag injected (the official Creators API requires partnerTag on every request). The CLI runtime calls SetPartnerTag before dispatching a command.

type Unconfigured

type Unconfigured interface {
	UnconfiguredErr() error
}

Unconfigured lets a backend supply its own "not configured" error instead of the generic AUTH_REQUIRED — e.g. the scrape backend is opt-in, not key-based, so it explains how to enable it rather than telling you to pipe a nonexistent API key.

type Validator

type Validator interface {
	Validate(ctx context.Context) error
}

Validator is implemented by backends that can actively test credentials/connectivity (used by `auth status` and `doctor`). Refresher re-mints a cached token.

func ValidatorFor

func ValidatorFor(p Provider) (Validator, bool)

ValidatorFor / RefresherFor are capability probes for the cli layer.

type Variation

type Variation struct {
	ASIN       string            `json:"asin"`
	Attributes map[string]string `json:"attributes"`
	Price      float64           `json:"price"`
	URL        string            `json:"url"`
}

type VariationsResult

type VariationsResult struct {
	SchemaVersion string      `json:"schemaVersion"`
	Provider      string      `json:"provider"`
	ParentASIN    string      `json:"parentAsin"`
	Variations    []Variation `json:"variations"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL