Skip to content

Developer-friendly & type-safe Typescript SDK specifically catered to leverage CoCart API

Notifications You must be signed in to change notification settings

cocart-headless/cocart-sdk-js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@cocart/sdk

Developer-friendly & type-safe Typescript SDK specifically catered to leverage CoCart API.

Summary

Warning

⚠️ This SDK is a work in progress and should not be used for production at this time. Please star the repository if interested and keep a lookout for an official release.

CoCart API

Read the docs at https://docs.cocartapi.com/api-reference

SDK Installation

The SDK can be installed with either npm, pnpm, bun or yarn package managers.

NPM

npm install @cocart/sdk

Yarn

yarn add @cocart/sdk

PNPM

pnpm add @cocart/sdk

BUN

bun add @cocart/sdk

Note

This package is published with CommonJS and ES Modules (ESM) support.

Supported JavaScript Runtimes

This SDK supports JavaScript runtimes that support ECMAScript 2020 or newer:

  • Browsers: Chrome, Safari, Edge, Firefox (evergreen browsers)
  • Node.js: v18 and v20 (active and maintenance LTS releases)
  • Bun: v1 and above
  • Deno: v1.39 and above

Recommended TypeScript Compiler Options

For the best experience with this SDK, use the following TypeScript compiler options:

{
  "compilerOptions": {
    "target": "es2020", // or higher
    "lib": ["es2020", "dom", "dom.iterable"],
  }
}

Basic Usage

import { CoCart } from '@cocart/sdk';

// Initialize client
const cocart = new CoCart({
  siteUrl: 'https://example.com',
  // Optional configurations
  apiVersion: 'v2',
  apiPrefix: 'wp-json', // Use this only if you have changed the REST API prefix on your WordPress setup.
  timeout: 30000,
});

// Example: Get cart contents
async function getCart() {
  try {
    const cart = await cocart.cart.get();
    console.log(cart);
  } catch (error) {
    console.error('Error fetching cart:', error);
  }
}

// Example: Add item to cart
async function addToCart() {
  try {
    const result = await cocart.cart.addItem({
      id: 123,
      quantity: 1,
    });
    console.log('Item added:', result);
  } catch (error) {
    console.error('Error adding item to cart:', error);
  }
}

SDK Architecture & Design

The CoCart SDK follows a modular, layered architecture designed for a type-safe and developer-friendly experience. The SDK architecture includes:

  • Promise-based API for all endpoints
  • Comprehensive TypeScript integration
  • Consistent endpoint architecture
  • Structured error handling system
  • Event-based extension system
  • Built-in utilities for currency and timezone handling

For a detailed overview of the SDK architecture and design principles, see the Architecture Documentation.

Authentication

The SDK supports multiple authentication methods:

Basic Authentication

const cocart = new CoCart({
  siteUrl: 'https://example.com',
  auth: {
    type: 'basic',
    username: 'username', // email address, billing phone number and consumer key (for admin)
    password: 'password', // consumer_secret (for admin)
  },
});

JWT Authentication

const cocart = new CoCart({
  siteUrl: 'https://example.com',
  auth: {
    type: 'jwt',
    token: 'your_jwt_token',
  },
});

Custom HTTP Client

The TypeScript SDK makes API calls using an HTTPClient that wraps the native Fetch API. This client is a thin wrapper around fetch and provides the ability to attach hooks around the request lifecycle that can be used to modify the request or handle errors and response.

The HTTPClient constructor takes an optional fetcher argument that can be used to integrate a third-party HTTP client or when writing tests to mock out the HTTP client and feed in fixtures.

The following example shows how to use the "beforeRequest" hook to add a custom header and a timeout to requests and how to use the "requestError" hook to log errors:

import { CoCart } from '@cocart/sdk';

// Create a client with interceptors
const cocart = new CoCart({
  siteUrl: 'https://example.com',
});

// Add a request interceptor that modifies requests before they're sent
cocart.interceptors.request.use(config => {
  // Add a custom header
  config.headers = {
    ...config.headers,
    'X-Custom-Header': 'CustomValue',
    'X-App-Version': '1.0.0',
  };
  
  // Add tracking information to query parameters
  if (config.params) {
    config.params = {
      ...config.params,
      'tracking_id': 'my-app-session-123',
    };
  }
  
  // Apply request timeout
  config.timeout = 20000; // 20 seconds timeout
  
  console.log(`Making request to ${config.endpoint}`);
  return config;
});

// Add a response interceptor
cocart.interceptors.response.use(
  // For successful responses
  response => {
    console.log(`Request to ${response.config.endpoint} succeeded`);
    
    // You can transform the response data if needed
    if (response.data && response.data.items) {
      console.log(`Received ${response.data.items.length} items`);
    }
    
    return response;
  },
  // For errors
  error => {
    console.error(`Request failed: ${error.message}`);
    
    // Log errors to your monitoring service
    if (typeof window !== 'undefined') {
      window.myAnalytics.logError({
        type: 'api_error',
        endpoint: error.config?.endpoint,
        status: error.status,
        message: error.message
      });
    }
    
    // You could implement retry logic for network errors
    if (error.name === 'NetworkError') {
      // Perhaps retry the request
      return Promise.reject(error); // but for now, just pass it through
    }
    
    // Rethrow the error for the caller to handle
    return Promise.reject(error);
  }
);

// Use the client with the interceptors
async function fetchCart() {
  try {
    const cart = await cocart.cart.get();
    return cart;
  } catch (error) {
    // Error handling at call site
    console.error('Error fetching cart:', error);
    throw error;
  }
}

Pagination

Some of the endpoints in this SDK support pagination. To use pagination, you make your SDK calls as usual, but the returned response object will also be an async iterable that can be consumed using the for await...of syntax.

Here's an example of one such pagination call:

import { CoCart } from '@cocart/sdk';

const cocart = new CoCart({
  siteUrl: 'https://example.com',
});

// Example 1: Using async iteration to process all pages of products
async function getAllProducts() {
  try {
    const productsResponse = await cocart.products.getAll({
      per_page: 20, // items per page
    });
    
    const allProducts = [];
    
    // Iterate through all pages automatically
    for await (const pageProducts of productsResponse) {
      console.log(`Processing page with ${pageProducts.length} products`);
      allProducts.push(...pageProducts);
    }
    
    console.log(`Retrieved ${allProducts.length} products in total`);
    return allProducts;
  } catch (error) {
    console.error('Error fetching products:', error);
    throw error;
  }
}

// Example 2: Manual pagination control
async function getProductsWithManualPagination() {
  try {
    let page = 1;
    const allProducts = [];
    let hasMorePages = true;
    
    while (hasMorePages) {
      const productsResponse = await cocart.products.getAll({
        per_page: 20,
        page: page,
      });
      
      allProducts.push(...productsResponse.data);
      
      // Check if we've reached the last page
      hasMorePages = productsResponse.hasNextPage();
      page++;
      
      console.log(`Retrieved page ${page - 1}`);
    }
    
    console.log(`Retrieved ${allProducts.length} products in total`);
    return allProducts;
  } catch (error) {
    console.error('Error fetching products:', error);
    throw error;
  }
}

// Example 3: Using pagination metadata
async function getProductsWithPaginationInfo() {
  try {
    const productsResponse = await cocart.products.getAll({
      per_page: 20,
    });
    
    // Access pagination metadata
    console.log(`Total products: ${productsResponse.pagination.total}`);
    console.log(`Total pages: ${productsResponse.pagination.totalPages}`);
    console.log(`Current page: ${productsResponse.pagination.currentPage}`);
    
    return productsResponse.data;
  } catch (error) {
    console.error('Error fetching products:', error);
    throw error;
  }
}

Development

Maturity

This SDK is in beta, and there may be breaking changes between versions without a major version update. Therefore, we recommend pinning usage to a specific package version. This way, you can install the same version each time without breaking changes unless you are intentionally looking for the latest version.

Contributions

We look forward to hearing your feedback. Feel free to open a PR or an issue with a proof of concept and we'll do our best to include it in a future release.

About

Developer-friendly & type-safe Typescript SDK specifically catered to leverage CoCart API

Resources

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published