Skip to content

Repository files navigation

featurable

Node.js and TypeScript SDK for the Featurable API.

Fetch your Featurable widgets and their Google reviews from any Node.js or TypeScript application. Written in TypeScript with full type definitions, zero runtime dependencies, and both ESM and CommonJS builds.

Requirements

  • Node.js 18 or newer (uses the built-in fetch)

Installation

pnpm add featurable
# or
npm install featurable
# or
yarn add featurable

Authentication

Create an API key in your Featurable developer settings and provide it to the client, either directly or via the FEATURABLE_API_KEY environment variable.

Quick start

import { Featurable } from 'featurable';

const client = new Featurable({
  apiKey: process.env.FEATURABLE_API_KEY,
});

const widget = await client.widgets.retrieve('your-widget-uuid');

console.log(
  `${widget.gbpLocationSummary.rating}★ from ${widget.gbpLocationSummary.reviewsCount} reviews`,
);

for (const review of widget.reviews) {
  console.log(`${review.author.name}: ${review.rating.value}/${review.rating.max}`);
  console.log(review.text);
}

CommonJS is supported too:

const { Featurable } = require('featurable');

Configuration

const client = new Featurable({
  apiKey: '...', // defaults to process.env.FEATURABLE_API_KEY
  baseURL: 'https://featurable.com/api/v2', // override the API base URL
  timeout: 60_000, // per-request timeout in ms (0 disables)
  maxRetries: 2, // retries for transient failures
  defaultHeaders: {}, // headers added to every request
  fetch: globalThis.fetch, // custom fetch implementation
});

Per-request options

Every resource method accepts optional overrides:

const controller = new AbortController();

const widget = await client.widgets.retrieve('your-widget-uuid', {
  timeout: 10_000,
  maxRetries: 0,
  signal: controller.signal,
  headers: { 'X-Trace-Id': 'abc123' },
});

Error handling

All errors extend FeaturableError. HTTP errors are APIError instances with a status code, and are further specialized so you can branch on the failure:

import {
  Featurable,
  APIError,
  NotFoundError,
  RateLimitError,
  AuthenticationError,
} from 'featurable';

try {
  await client.widgets.retrieve('missing');
} catch (error) {
  if (error instanceof NotFoundError) {
    // 404 — the widget does not exist
  } else if (error instanceof RateLimitError) {
    // 429 — retry later
  } else if (error instanceof AuthenticationError) {
    // 401 — check your API key
  } else if (error instanceof APIError) {
    console.error(error.status, error.requestId, error.body);
  } else {
    throw error;
  }
}
Error When
BadRequestError HTTP 400
AuthenticationError HTTP 401
PermissionDeniedError HTTP 403
NotFoundError HTTP 404
ConflictError HTTP 409
RateLimitError HTTP 429
InternalServerError HTTP 5xx
APITimeoutError Request exceeded the timeout
APIConnectionError Network failure / request aborted

Retries

By default the client retries up to maxRetries (2) times on network errors and 408, 409, 429, and 5xx responses, using exponential backoff with jitter. When the API returns a Retry-After header, it is honored.

API

client.widgets.retrieve(uuid, options?)

Retrieve a widget and its reviews by UUID. Returns a Widget.

Development

See CONTRIBUTING.md.

License

MIT

About

Node.js and TypeScript SDK for the Featurable API

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages