npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@biobarica/seller-resolution

v1.0.2

Published

Resolves a seller from Firestore by phone number or country using Pipedrive

Downloads

140

Readme

@biobarica/seller-resolution

Resolves a Pipedrive seller for a given phone number or country code using Firestore as the seller registry.

How it works

  1. By phone — searches Pipedrive for an existing contact with that number. If one is found and already has an owner, that owner is returned. Otherwise the phone's country is extracted and the flow continues as below.
  2. By country — fetches all sellers from the user_details Firestore collection that are assigned to that country (or to the "ROW" catch-all), then picks one at random weighted by their configured country weights.

Installation

npm install @biobarica/seller-resolution

Usage

With a Firestore instance

Use this when you already have firebase-admin initialised in your app.

import { SellersService, BusinessUnit } from "@biobarica/seller-resolution";
import { getFirestore } from "firebase-admin/firestore";

const service = new SellersService({
  pipedriveApiKey: process.env.PIPEDRIVE_API_KEY,
  businessUnit: BusinessUnit.OXY,
  defaultSellerId: 42,
  defaultUserId: "fallback-uid",
  db: getFirestore(),
});

With a service account

Use this when you don't have firebase-admin set up yet. The package initialises it internally.

import { SellersService, BusinessUnit } from "@biobarica/seller-resolution";
import serviceAccount from "./service-account.json";

const service = new SellersService({
  pipedriveApiKey: process.env.PIPEDRIVE_API_KEY,
  businessUnit: BusinessUnit.OXY,
  defaultSellerId: 42,
  defaultUserId: "fallback-uid",
  serviceAccount,
});

db and serviceAccount are mutually exclusive — TypeScript will report an error if you pass both.

API

new SellersService(options, logger?)

| Option | Type | Required | Description | |---|---|---|---| | pipedriveApiKey | string | Yes | Pipedrive API key | | businessUnit | string | Yes | Business unit key used to scope seller selection (e.g. "oxy") | | db | Firestore | One of | An existing Firestore instance | | serviceAccount | ServiceAccountCredentials | One of | Firebase service account credentials object | | defaultSellerId | number | No | Fallback Pipedrive seller id when no seller can be resolved | | defaultUserId | string | No | Fallback Firestore user id when no seller can be resolved |

An optional second argument accepts a custom Logger ({ info, warn, error }). Defaults to console.

getSeller(phoneNumber)

Resolves a seller for a phone number. Accepts E.164 format (+5491123456789) or without the leading +.

const result = await service.getSeller("+5491123456789");
// result.sellerId                   — Pipedrive seller id (number | undefined)
// result.userId                     — Firestore user document id (string | undefined)
// result.displayName                — seller display name (string | undefined)
// result.calendarLink               — booking calendar URL (string | undefined)
// result.discoveryCallCalendarLink  — discovery call calendar URL (string | undefined)
// result.whatsappNumber             — WhatsApp contact number (string | undefined)

getSellerByCountry(countryCode)

Resolves a seller directly from a country code, skipping the Pipedrive lookup.

const { sellerId, userId, displayName, calendarLink } = await service.getSellerByCountry("AR");

Firestore data model

The service reads from the user_details collection. Each seller document must have at least:

{
  "id": "firestore-doc-id",
  "roles": ["seller"],
  "sellerInfo": {
    "pipedriveSellerId": 42,
    "assignedCountries": ["AR", "CL"],   // ISO 3166-1 alpha-2 or "ROW" as catch-all
    "countryWeights": { "AR": 0.7, "CL": 0.3 },
    "businessUnits": ["oxy"]             // omit to make available to all business units
  }
}

Per-business-unit overrides

A seller can override assignedCountries and countryWeights for a specific business unit by nesting them under the business unit key:

{
  "sellerInfo": {
    "pipedriveSellerId": 42,
    "assignedCountries": ["ROW"],
    "oxy": {
      "assignedCountries": ["AR", "BR"],
      "countryWeights": { "AR": 0.6, "BR": 0.4 }
    }
  }
}

Country weights

Weights do not need to sum to 1 — the selection is proportional. A seller with weight 2 is twice as likely to be picked as one with weight 1. If no weight is configured for a country, all eligible sellers share equal probability.

Custom logger

import { SellersService, Logger } from "@biobarica/seller-resolution";

const logger: Logger = {
  info: (msg) => myLogger.info(msg),
  warn: (msg) => myLogger.warn(msg),
  error: (msg) => myLogger.error(msg),
};

const service = new SellersService({ ... }, logger);