ChemPare Documentation - v0.0.0
    Preparing search index...

    Implementation of the Carolina Biological Supply Company supplier. Provides product search and data extraction functionality for Carolina.com.

    Carolina.com uses Oracle ATG Commerce as their ecommerce platform which has a predictable output format, though very bulky. But very parseable.

    Product search uses the following endpoints:

    • Product Search: /browse/product-search-results?tab=p&q=acid
    • Product Search JSON: /browse/product-search-results?tab=p&format=json&ajax=true&q=acid
    • Product Details: /:category/:productName/:productId.pr
    • Product Details JSON: /:category/:productName/:productId.pr?format=json&ajax=true

    API Documentation:

    • Swagger UI: https://www.carolina.com/swagger-ui/
    • OpenAPI Spec: https://www.carolina.com/api/rest/openapi.json
    • WADL: https://www.carolina.com/api/rest/application.wadl

    Common API Endpoints:

    • Product Quick View: /api/rest/cb/product/product-quick-view/:id
    • Product Details: /api/rest/cb/product/product-details/:id
    • Search Suggestions: /api/rest/cb/static/fetch-suggestions-for-global-search/:term

    JSON Format: Append &format=json&ajax=true to any URL to get JSON response

    Hierarchy (View Summary)

    Implements

    Index

    Constructors

    • Creates a new instance of the supplier base class. Initializes the supplier with query parameters, request limits, and abort controller. Sets up logging and default product values.

      Parameters

      • query: string

        The search term to query products for

      • limit: number = 5

        The maximum number of results to return (default: 5)

      • Optionalcontroller: AbortController

        AbortController instance for managing request cancellation

      Returns SupplierCarolina

      // Create a supplier with default limit
      const supplier = new MySupplier("sodium chloride", undefined, new AbortController());

      // Create a supplier with custom limit
      const supplier = new MySupplier("acetone", 10, new AbortController());

      // Create a supplier and handle cancellation
      const controller = new AbortController();
      const supplier = new MySupplier("ethanol", 5, controller);

      // Later, to cancel all pending requests:
      controller.abort();

    Methods

    • Initializes the cache for the supplier. This is called after construction to ensure supplierName is set.

      Returns void

      The cache is initialized with the supplier's name and is used to store both query results and product data. This method should be called after the supplier's name is set to ensure proper cache key generation.

      class MySupplier extends SupplierBase<Product> {
      constructor() {
      super("acetone", 5);
      // supplierName is set here
      this.initCache(); // Initialize cache after supplierName is set
      }
      }
    • Placeholder for any setup that needs to be done before the query is made. Override this in subclasses if you need to perform setup (e.g., authentication, token fetching).

      Returns Promise<void>

      A promise that resolves when the setup is complete.

      await supplier.setup();
      
    • Retrieves HTTP headers from a URL using a HEAD request. Useful for checking content types, caching headers, and other metadata without downloading the full response.

      Parameters

      • url: string | URL

        The URL to fetch headers from

      Returns Promise<Maybe<HeadersInit>>

      Promise resolving to the response headers or void if request fails

      // Basic usage
      const headers = await supplier.httpGetHeaders('https://example.com/product/123');
      if (headers) {
      console.log('Content-Type:', headers['content-type']);
      }
      // With error handling
      try {
      const headers = await supplier.httpGetHeaders('https://example.com/product/123');
      if (headers) {
      console.log('Headers:', headers);
      }
      } catch (err) {
      console.error('Failed to fetch headers:', err);
      }
    • Sends a POST request to the given URL with the given body and headers. Handles request setup, error handling, and response caching.

      Parameters

      Returns Promise<Maybe<Response>>

      Promise resolving to the Response object or void if request fails

      // Basic POST request
      const response = await supplier.httpPost({
      path: '/api/v1/products',
      body: { name: 'Test Chemical' }
      });
      // POST with custom headers
      const response = await supplier.httpPost({
      path: '/api/v1/products',
      body: { name: 'Test Chemical' },
      headers: {
      'Authorization': 'Bearer token123',
      'Content-Type': 'application/json'
      }
      });
      // POST with custom host and params
      const response = await supplier.httpPost({
      path: '/api/v1/products',
      host: 'api.example.com',
      body: { name: 'Test Chemical' },
      params: { version: '2' }
      });
      // Error handling
      try {
      const response = await supplier.httpPost({ path: '/api/v1/products', body: { name: 'Test' } });
      if (response && response.ok) {
      const data = await response.json();
      console.log('Created:', data);
      }
      } catch (err) {
      console.error('POST failed:', err);
      }
    • Sends a POST request and returns the response as a JSON object.

      Parameters

      Returns Promise<Maybe<JsonValue>>

      The response from the POST request as a JSON object.

      // Basic usage
      const data = await supplier.httpPostJson({
      path: '/api/v1/products',
      body: { name: 'John' }
      });
      // With custom headers and error handling
      try {
      const data = await supplier.httpPostJson({
      path: '/api/v1/products',
      body: { name: 'John' },
      headers: { 'Authorization': 'Bearer token123' }
      });
      if (data) {
      console.log('Created:', data);
      }
      } catch (err) {
      console.error('POST JSON failed:', err);
      }
    • Sends a POST request and returns the response as a HTML string.

      Parameters

      Returns Promise<Maybe<string>>

      Promise resolving to the HTML response as a string or void if request fails

      TypeError - If the response is not valid HTML content

      // Basic usage
      const html = await supplier.httpPostHtml({
      path: '/api/v1/products',
      body: { name: 'John' }
      });
    • Sends a GET request to the given URL with the specified options. Handles request setup, error handling, and response caching.

      Parameters

      Returns Promise<Maybe<Response>>

      Promise resolving to the Response object or void if request fails

      // Basic GET request
      const response = await supplier.httpGet({
      path: '/products/search',
      params: { query: 'sodium chloride' }
      });
      // GET with custom headers
      const response = await supplier.httpGet({
      path: '/products/search',
      headers: { 'Accept': 'application/json' }
      });
      // GET with custom host
      const response = await supplier.httpGet({
      path: '/products/search',
      host: 'api.example.com',
      params: { category: 'chemicals' }
      });
      // Error handling
      try {
      const response = await supplier.httpGet({ path: '/products/search' });
      if (response && response.ok) {
      const data = await response.json();
      console.log('Products:', data);
      }
      } catch (err) {
      console.error('GET failed:', err);
      }
    • Filters an array of data using fuzzy string matching to find items that closely match a query string. Uses the WRatio algorithm from fuzzball for string similarity comparison.

      Type Parameters

      • X

      Parameters

      • query: string

        The search string to match against

      • data: X[]

        Array of data objects to search through

      • cutoff: number = 40

        Minimum similarity score (0-100) for a match to be included (default: 40)

      Returns X[]

      Array of matching data objects with added fuzzy match metadata

      // Example with simple string array
      const products = [
      { title: "Sodium Chloride", price: 29.99 },
      { title: "Sodium Hydroxide", price: 39.99 },
      { title: "Potassium Chloride", price: 19.99 }
      ];

      const matches = this.fuzzyFilter("sodium chloride", products);
      // Returns: [
      // {
      // title: "Sodium Chloride",
      // price: 29.99,
      // ___fuzz: { score: 100, idx: 0 }
      // },
      // {
      // title: "Sodium Hydroxide",
      // price: 39.99,
      // ___fuzz: { score: 85, idx: 1 }
      // }
      // ]

      // Example with custom cutoff
      const strictMatches = this.fuzzyFilter("sodium chloride", products, 90);
      // Returns only exact matches with score >= 90

      // Example with different data structure
      const chemicals = [
      { name: "NaCl", formula: "Sodium Chloride" },
      { name: "NaOH", formula: "Sodium Hydroxide" }
      ];

      // Override titleSelector to use formula field
      this.titleSelector = (data) => data.formula;
      const formulaMatches = this.fuzzyFilter("sodium chloride", chemicals);
    • Makes an HTTP GET request and returns the response as a string. Handles request configuration, error handling, and HTML parsing.

      Parameters

      Returns Promise<Maybe<string>>

      Promise resolving to the HTML response as a string or void if request fails

      TypeError - If the response is not valid HTML content

      // Basic GET request
      const html = await this.httpGetHtml({
      path: "/api/products",
      params: { search: "sodium" }
      });

      // GET request with custom headers
      const html = await this.httpGetHtml({
      path: "/api/products",
      headers: {
      "Authorization": "Bearer token123",
      "Accept": "text/html"
      }
      });

      // GET request with custom host
      const html = await this.httpGetHtml({
      path: "/products",
      host: "api.supplier.com",
      params: { limit: 10 }
      });
    • Makes an HTTP GET request and returns the response as parsed JSON. Handles request configuration, error handling, and JSON parsing.

      Parameters

      Returns Promise<Maybe<JsonValue>>

      Promise resolving to the parsed JSON response or void if request fails

      TypeError - If the response is not valid JSON content

      // Basic GET request
      const data = await supplier.httpGetJson({ path: '/api/products', params: { search: 'sodium' } });
      // GET request with custom headers
      const data = await supplier.httpGetJson({
      path: '/api/products',
      headers: {
      'Authorization': 'Bearer token123',
      'Accept': 'application/json'
      }
      });
      // GET request with custom host
      const data = await supplier.httpGetJson({
      path: '/products',
      host: 'api.supplier.com',
      params: { limit: 10 }
      });
      // Error handling
      try {
      const data = await supplier.httpGetJson({ path: '/api/products' });
      if (data) {
      console.log('Products:', data);
      }
      } catch (error) {
      console.error('Failed to fetch products:', error);
      }
    • Executes a product search query with caching support. First checks the cache for existing results, then falls back to the actual query if needed. The limit parameter is only used for the actual query and doesn't affect caching.

      Parameters

      • query: string

        The search term to query products for

      • limit: number = ...

        The maximum number of results to return (defaults to instance limit)

      Returns Promise<void | ProductBuilder<Product>[]>

      Promise resolving to array of product builders or void if search fails

      // Basic usage with default limit
      const results = await supplier.queryProductsWithCache("acetone");
      if (results) {
      console.log(`Found ${results.length} products`);
      }
      // With custom limit
      const results = await supplier.queryProductsWithCache("acetone", 10);
      if (results) {
      for (const builder of results) {
      const product = await builder.build();
      console.log(product.title, product.price);
      }
      }
    • Executes the supplier's search query and returns the results. This method will execute all results concurrently (to the limits set in the supplier class), and resolve to an array of product objects.

      Returns AsyncGenerator<Product, void, undefined>

      Promise resolving to an array of products

      This method is used to execute the supplier's search query and return the results.

    • Finalizes a partial product by adding computed properties and validating the result. This method:

      1. Validates the product has minimal required properties
      2. Computes USD price if product is in different currency
      3. Calculates base quantity using the unit of measure
      4. Ensures the product URL is absolute

      Parameters

      Returns Promise<Maybe<Product>>

      Promise resolving to a complete Product object or void if validation fails

      // Example with a valid partial product
      const builder = new ProductBuilder<Product>(this.baseURL);
      builder
      .setBasicInfo("Sodium Chloride", "/products/nacl", "ChemSupplier")
      .setPricing(29.99, "USD", "$")
      .setQuantity(500, "g");

      const finishedProduct = await this.finishProduct(builder);
      if (finishedProduct) {
      console.log("Finalized product:", {
      title: finishedProduct.title,
      price: finishedProduct.price,
      quantity: finishedProduct.quantity,
      uom: finishedProduct.uom,
      usdPrice: finishedProduct.usdPrice,
      baseQuantity: finishedProduct.baseQuantity
      });
      }

      // Example with an invalid partial product
      const invalidBuilder = new ProductBuilder<Product>(this.baseURL);
      invalidBuilder.setBasicInfo("Sodium Chloride", "/products/nacl", "ChemSupplier");
      // Missing required fields

      const invalidProduct = await this.finishProduct(invalidBuilder);
      if (!invalidProduct) {
      console.log("Failed to finalize product - missing required fields");
      }
    • Takes in either a relative or absolute URL and returns an absolute URL. This is useful for when you aren't sure if the link (retrieved from parsed text, a setting, an element, an anchor value, etc) is absolute or not. Using relative links will result in http://chrome-extension://... being added to the link.

      Parameters

      • path: string | URL

        URL object or string

      • Optionalparams: Maybe<RequestParams>

        The parameters to add to the URL.

      • Optionalhost: string

        The host to use for overrides (eg: needing to call a different host for an API)

      Returns string

      absolute URL

      this.href('/some/path')
      // https://supplier_base_url.com/some/path

      this.href('https://supplier_base_url.com/some/path', null, 'another_host.com')
      // https://another_host.com/some/path

      this.href('/some/path', { a: 'b', c: 'd' }, 'another_host.com')
      // http://another_host.com/some/path?a=b&c=d

      this.href('https://supplier_base_url.com/some/path')
      // https://supplier_base_url.com/some/path

      this.href(new URL('https://supplier_base_url.com/some/path'))
      // https://supplier_base_url.com/some/path

      this.href('/some/path', { a: 'b', c: 'd' })
      // https://supplier_base_url.com/some/path?a=b&c=d

      this.href('https://supplier_base_url.com/some/path', new URLSearchParams({ a: 'b', c: 'd' }))
      // https://supplier_base_url.com/some/path?a=b&c=d
    • Retrieves product data with caching support. Similar to getProductData but allows for additional parameters to be included in the cache key.

      Parameters

      Returns Promise<void | ProductBuilder<Product>>

      Promise resolving to the updated ProductBuilder or void if fetch fails

      const builder = new ProductBuilder<Product>(this.baseURL);
      builder.setBasicInfo("Acetone", "/products/acetone", "ChemSupplier");

      // Use custom fetcher with additional params
      const updatedBuilder = await supplier.getProductDataWithCache(
      builder,
      async (b) => {
      // Custom fetching logic
      return b;
      },
      { version: "2.0" }
      );
    • Groups variants of a product by their title

      Type Parameters

      • R

      Parameters

      • data: R[]

        Array of product listings from search results

      Returns R[]

      Array of product listings with grouped variants

      Create a generic method for this, the same method is used in Synthetika and could be of use with LoudWolf.

      const results = await this.queryProducts("sodium chloride");
      const grouped = this.groupVariants(results);
      // grouped is an array of product listings with grouped variants
    • Internal fetch method with request counting and decorator. Tracks request count and enforces hard limits on HTTP requests.

      Parameters

      • ...args: [input: URL | RequestInfo, init?: RequestInit]

        Arguments to pass to fetchDecorator (usually a Request or URL and options)

      Returns Promise<any>

      The response from the fetchDecorator

      Error if request count exceeds hard limit

      // Example usage inside a subclass:
      const response = await this.fetch(new Request('https://example.com'));
      if (response.ok) {
      const data = await response.json();
      console.log(data);
      }
      // With custom request options
      const response = await this.fetch(
      new Request('https://example.com', {
      headers: { 'Accept': 'application/json' }
      })
      );
    • Constructs the query parameters for a product search request

      Parameters

      • query: string

        Search term to look for

      Returns CarolinaSearchParams

      Object containing all required search parameters

    • Executes a product search query and stores results Fetches products matching the current search query and updates internal results cache

      Parameters

      • query: string
      • limit: number = ...

      Returns Promise<void | ProductBuilder<Product>[]>

    • Initialize product builders from Carolina search response data. Transforms product listings into ProductBuilder instances, handling:

      • Basic product information (title, URL, supplier)
      • Product descriptions and specifications
      • Product IDs and SKUs
      • Pricing information with currency details
      • CAS number extraction from product text
      • Quantity parsing from product names and descriptions
      • Grade/purity level extraction
      • Product categories and classifications

      Parameters

      Returns ProductBuilder<Product>[]

      Array of ProductBuilder instances initialized with product data

      const results = await this.queryProducts("sodium chloride");
      if (results) {
      const builders = this.initProductBuilders(results);
      // Each builder contains parsed product data
      for (const builder of builders) {
      const product = await builder.build();
      console.log(product.title, product.price, product.grade);
      }
      }
    • Extracts product search results from a response object Navigates through nested response structure to find product listings

      Parameters

      • response: unknown

        Raw response object from search request

      Returns CarolinaSearchResult[]

      Array of validated search result items

    • Extracts the relevant product data from an ATG response object Navigates through the nested response structure to find product information

      Parameters

      • productResponse: unknown

        Raw ATG response object

      Returns
          | null
          | {
              breadCrumbSchemaJson: {
                  breadCrumbSchemaJson: string;
                  dataLayer_obj: Record<string, string>;
              };
              standardResult: {
                  productName: string;
                  productId: string;
                  pdpOrderResult: Record<string, unknown>;
                  tabsResult: {
                      pdpspecifications: { specificationList: SpecificationItem[] };
                  };
              };
              longDescription: string;
              product: string;
              dataLayer: {
                  productDetail: {
                      productImageUrl: string;
                      productId: string;
                      productUrl: string;
                      page_type: string;
                      productName: string;
                  };
                  productPrice: string[];
                  dataLayerObject: { dataLayerJson: Record<string, string> };
              };
              canonicalUrl: string;
              isDLProduct: boolean;
              displayName: string;
              isDiscontinuedItem: boolean;
              isproductGrouping: boolean;
              shortDescription: string;
              prodType: string;
              familyVariyantProductDetails: {
                  productId: string;
                  variantUrl: string;
                  schemaJson: {
                      schemaJson: {
                          offers: {
                              image?: string;
                              priceCurrency?: string;
                              price: number;
                              name: string;
                              description?: string;
                              availability: string;
                              sku: string;
                              url: string;
                              itemCondition?: string;
                          }[];
                      };
                  };
              };
              familyVariyantDisplayName: string;
              organizationDetails: Record<string, unknown>;
          }

      Product data from response or null if invalid/not found

      • null
      • {
            breadCrumbSchemaJson: {
                breadCrumbSchemaJson: string;
                dataLayer_obj: Record<string, string>;
            };
            standardResult: {
                productName: string;
                productId: string;
                pdpOrderResult: Record<string, unknown>;
                tabsResult: {
                    pdpspecifications: { specificationList: SpecificationItem[] };
                };
            };
            longDescription: string;
            product: string;
            dataLayer: {
                productDetail: {
                    productImageUrl: string;
                    productId: string;
                    productUrl: string;
                    page_type: string;
                    productName: string;
                };
                productPrice: string[];
                dataLayerObject: { dataLayerJson: Record<string, string> };
            };
            canonicalUrl: string;
            isDLProduct: boolean;
            displayName: string;
            isDiscontinuedItem: boolean;
            isproductGrouping: boolean;
            shortDescription: string;
            prodType: string;
            familyVariyantProductDetails: {
                productId: string;
                variantUrl: string;
                schemaJson: {
                    schemaJson: {
                        offers: {
                            image?: string;
                            priceCurrency?: string;
                            price: number;
                            name: string;
                            description?: string;
                            availability: string;
                            sku: string;
                            url: string;
                            itemCondition?: string;
                        }[];
                    };
                };
            };
            familyVariyantDisplayName: string;
            organizationDetails: Record<string, unknown>;
        }
        • breadCrumbSchemaJson: { breadCrumbSchemaJson: string; dataLayer_obj: Record<string, string> }

          Schema data for breadcrumb navigation including JSON structure and data layer information

          • breadCrumbSchemaJson: string

            JSON string containing the structured breadcrumb schema data

          • dataLayer_obj: Record<string, string>

            Analytics data layer object specific to breadcrumb navigation

        • standardResult: {
              productName: string;
              productId: string;
              pdpOrderResult: Record<string, unknown>;
              tabsResult: {
                  pdpspecifications: { specificationList: SpecificationItem[] };
              };
          }

          Standard result object containing core product information

          • productName: string

            Name of the product

          • productId: string

            Unique identifier for the product

          • pdpOrderResult: Record<string, unknown>

            Order-related data for the product display page

          • tabsResult: { pdpspecifications: { specificationList: SpecificationItem[] } }

            Specifications for the product

        • longDescription: string

          Detailed description of the product

        • product: string

          Product data in string format

        • dataLayer: {
              productDetail: {
                  productImageUrl: string;
                  productId: string;
                  productUrl: string;
                  page_type: string;
                  productName: string;
              };
              productPrice: string[];
              dataLayerObject: { dataLayerJson: Record<string, string> };
          }

          Analytics and tracking data container

          • productDetail: {
                productImageUrl: string;
                productId: string;
                productUrl: string;
                page_type: string;
                productName: string;
            }

            Detailed product information for analytics

            • productImageUrl: string

              URL of the product's primary image

            • productId: string

              Unique identifier for the product

            • productUrl: string

              URL to the product's detail page

            • page_type: string

              Type of page being displayed

            • productName: string

              Name of the product

          • productPrice: string[]

            Array of product price information

          • dataLayerObject: { dataLayerJson: Record<string, string> }

            Container for data layer information

            • dataLayerJson: Record<string, string>

              JSON object containing analytics data layer information

        • canonicalUrl: string

          Canonical URL for the product page

        • isDLProduct: boolean

          Indicates if the product is a digital learning product

        • displayName: string

          Display name shown for the product

        • isDiscontinuedItem: boolean

          Indicates if the product has been discontinued

        • isproductGrouping: boolean

          Indicates if this is a product grouping

        • shortDescription: string

          Brief description of the product

        • prodType: string

          Type or category of the product

        • familyVariyantProductDetails: {
              productId: string;
              variantUrl: string;
              schemaJson: {
                  schemaJson: {
                      offers: {
                          image?: string;
                          priceCurrency?: string;
                          price: number;
                          name: string;
                          description?: string;
                          availability: string;
                          sku: string;
                          url: string;
                          itemCondition?: string;
                      }[];
                  };
              };
          }

          Details about product variants within the same family

        • familyVariyantDisplayName: string

          Display name for the product family variant

        • organizationDetails: Record<string, unknown>

          Details about the organization

      const response = await this.httpGetJson({
      path: `/api/rest/cb/product/product-quick-view/${productId}`
      });
      const productData = this.extractATGResponse(response);
      if (productData) {
      console.log(productData.products[0]);
      }
    • Transforms a Carolina search result into the common Product type Makes additional API calls if needed to get complete product details

      Parameters

      Returns Promise<void | ProductBuilder<Product>>

      Promise resolving to a partial Product object or void if invalid

      Look to see if the response header is 302 and if its sending us to https://www.carolina.com/CB_500, if so, stop sending requests to them for this search.

      const searchResults = await this.queryProducts("acid");
      if (searchResults) {
      const product = await this.getProductData(searchResults[0]);
      if (product) {
      console.log(product.title, product.price);
      }
      }

    Properties

    query: string

    String to query for (Product name, CAS, etc). This is the search term that will be used to find products. Set during construction and used throughout the supplier's lifecycle.

    const supplier = new MySupplier("sodium chloride", 10);
    console.log(supplier.query); // "sodium chloride"
    baseSearchParams: Record<string, string | number> = {}

    The base search parameters that are always included in search requests. These parameters are merged with any additional search parameters when making requests to the supplier's API.

    class MySupplier extends SupplierBase<Product> {
    constructor() {
    super();
    this.baseSearchParams = {
    format: "json",
    version: "2.0"
    };
    }
    }
    controller: AbortController

    The AbortController instance used to manage and cancel ongoing requests. This allows for cancellation of in-flight requests when needed, such as when a new search is started or the supplier is disposed.

    const controller = new AbortController();
    const supplier = new MySupplier("acetone", 5, controller);

    // Later, to cancel all pending requests:
    controller.abort();
    limit: number

    The maximum number of results to return for a search query. This is not a limit on HTTP requests, but rather the number of products that will be returned to the caller.

    const supplier = new MySupplier("acetone", 5); // Limit to 5 results
    for await (const product of supplier) {
    // Will yield at most 5 products
    }
    products: ProductBuilder<Product>[] = []

    The products that are currently being built by the supplier. This array holds ProductBuilder instances that are in the process of being transformed into complete Product objects.

    await supplier.queryProducts("acetone");
    console.log(`Building ${supplier.products.length} products`);
    for (const builder of supplier.products) {
    const product = await builder.build();
    console.log("Built product:", product.title);
    }
    requestCount: number = 0

    Counter for HTTP requests made during the current query execution. This is used to track the number of requests and ensure we don't exceed the httpRequestHardLimit.

    0

    await supplier.queryProducts("acetone");
    console.log(`Made ${supplier.requestCount} requests`);
    if (supplier.requestCount >= supplier.httpRequestHardLimit) {
    console.log("Reached request limit");
    }
    minConcurrentCycle: number = 100

    Minimum number of milliseconds between two consecutive tasks

    logger: Logger
    productDefaults: {
        uom: string;
        quantity: number;
        currencyCode: string;
        currencySymbol: string;
    } = ...
    productDataCacheKey: "supplier_product_data_cache"
    supplierName: string = "Carolina"

    Display name of the supplier

    baseURL: string = "https://www.carolina.com"

    Base URL for all API requests

    shipping: ShippingRange = "domestic"

    The shipping scope of the supplier. This is used to determine the shipping scope of the supplier.

    country: string = "US"

    The country code of the supplier. This is used to determine the currency and other country-specific information.

    paymentMethods: PaymentMethod[] = ...

    The payment methods accepted by the supplier. This is used to determine the payment methods accepted by the supplier.

    queryResults: CarolinaSearchResult[] = []

    Cached search results from the last query

    httpRequestHardLimit: number = 50

    Maximum number of HTTP requests allowed per query

    httpRequstCount: number = 0

    Counter for HTTP requests made during current query

    maxConcurrentRequests: number = 5

    Number of requests to process in parallel

    headers: HeadersInit = ...

    Default headers sent with every request