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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@locally-com/lcly-js-sdk

v3.0.0

Published

Locally Javascript Software Development Kit

Downloads

128

Readme

Locally Headless API SDK

Introduction

A Javascript SDK for the Locally.com Headless API. This library is built with Javascript developers in mind, but it also works with TypeScript.

Note: This SDK is in beta and is not ready for production

Features

  • Supports Node.js 14+.
  • Ships with CommonJS and ES Modules.
  • Works in server and browser environments.

Installing

npm install @locally-com/lcly-js-sdk

Client

To set up the client we will authenticate with a token as follows:

import LCLY from "@locally-com/lcly-js-sdk" // ESM
// const LCLY = require('@locally-com/lcly-js-sdk').default // CommonJS
const client = new LCLY("{{ MY_TOKEN }}")

Examples

To see the full list of API endpoints this SDK supports and their implementation, please review the dist/mjs/api/ directory: https://www.npmjs.com/package/@locally-com/lcly-js-sdk?activeTab=code

Initialize a shopper session

Initialize the shopper session and validate your product and UPC combination.

import LCLY from "@locally-com/lcly-js-sdk"

const client = new LCLY("{{ MY_TOKEN }}")

async function main() {
    const result = await client.conversion().get('start', {
        upc: "{{ UPC }}",
        product_id: {{ PRODUCT_ID }},
        company_id: {{ COMPANY_ID }}
    })

    console.log(result)
}

main()

The response contains a validated UPC and its geographical location.

{
  "success": true,
  "data": {
    "style": "999",
    "company_id": 999,
    "upc": "000000000000",
    "company_name": "ACME Outfitters Chicago",
    "initial_store_id": 999,
    "company_logo": "image.jpg",
    "user_geo": {
      "lat": "41.8756719",
      "lng": "-87.6243469",
      "city_label": "Chicago, IL",
      "country": "US",
      "distance_unit": "mi"
    }
  }
}

Locate a product at multiple stores

With the response from the initialization example, you can now use the validated UPC and geographic coordinates to return a list of stores that stock the item.

import LCLY from "@locally-com/lcly-js-sdk"

const client = new LCLY("{{ MY_TOKEN }}")

async function main() {
    const result = await client.conversion().get('store_data', {
        company_id: {{ COMPANY_ID }},
        upc: "{{ UPC }}",
        map_center_lat: "{{ LAT }}",
        map_center_lng: "{{ LNG }}",
        map_distance_unit: "{{ UNIT }}",
        map_distance_diag: "{{ DISTANCE }}"
    })

    console.log(result)
}

main()

This response contains a list of stores that have the validated UPC in stock nearest to the shopper's geographical location.

{
  "success": true,
  "data": {
    "all_upcs_carried": [
       000000000000,
       ...
    ],
    "markers": [
      {
        "id": 37175,
        "name": "ACME Outfitters Chicago",
        "lat": "41.91136867",
        "lng": "-87.67771437",
        "address": "15 ACME Ave",
        "city": "Chicago",
        "state": "IL",
        "zip": "60647",
        "phone": "(555) 697-7381",
        "country": "US",
        "company_id": 999,
        "image": "image.jpg",
        "vendor_id": "",
        "user_distance": 0,
        "stock_status": 3,
        "stocking_product": 1,
        "stocking_variant": 1,
        "acquisition_options": {
      		bopis: 1,
        	ropis: 1
        },
        "disclaimer": "Item is in Stock!",
        "dow": 0,
        "display_dow": [
          {
            "bil_hrs": "7am-8pm",
            "label": "Monday",
            "day_index": 0
          }
        ],
        "today_hours": "7am-8pm",
        "hours_known": 1,
        "is_open": 1,
        "next_open": "",
        "is_closing_soon": 0,
        "phone_link": "tel:+15556977381",
        "is_tmp_closed": 0,
        "status_class": "success",
        "status_label": "Open",
        "qoh": 10,
        "stock_status_constants": [
          {
            "key": "PRODUCT_YES_VARIANT_YES_BIL_YES",
            "value": "Item is in Stock!"
          }
        ],
        "feature_constants": [
          {
            "key": "DELIVERY_AVAILABLE",
            "value": "Same-day Local Delivery Available"
          },
          {
            "key": "IN_STORE_PICKUP_AVAILABLE",
            "value": "Store Pickup Available"
          }
        ],
        "web_address": "https:\/\/www.acmeco.com"
      },
      ...
    ],
    "total_marker_count": 100
  }
}

Tracking a product at a specific store

If you are interested in ongoing product availability for a specific store, you can query the conversion/store_data endpoint in single store mode.

Start by recording the specific data.markers[].id of a multi-store result (please review the prior example if needed). We can target a particular store by setting the store ID as value for the only_store_id query parameter.

import LCLY from "@locally-com/lcly-js-sdk"

const client = new LCLY("{{MY_TOKEN}}")

async function main() {
    const result = await client.conversion().get('store_data', {
        only_store_id: {{ STORE_ID }},
        company_id: {{ COMPANY_ID }},
        upc: "{{ UPC }}",
        map_distance_unit: "{{ UNIT }}",
        map_distance_diag: "1"
    })

    console.log(result)
}

main()

The response is nearly identical to the multi-store request example, except that only one marker is returned.

Manually handling location and persisting a session

All of the Locally Headless API endpoints will automatically attempt to geolocate the shopper based on their location on the first request. However, it is possible to set an alternative location prior to initialization and persist it for subsequent requests by utilizing sessions.

In this example we are asking the API for suggestions of locations matching the term "chicago".

import LCLY from "@locally-com/lcly-js-sdk"

const client = new LCLY("{{MY_TOKEN}}")

async function main() {
    const result = await client.location().get('suggest', {
        query: "Chicago"
    })

    console.log(result)
}

main()

The response includes coordinates for locations that match the term "chicago".

{
  "success": true,
  "data": {
    "query": "chicago",
    "suggestions": [
      {
        "value": "Chicago, Illinois, United States",
        "postcode": "",
        "data": {
          "lat": 41.875562,
          "lng": -87.624421,
          "relevance": 1
        }
      },
      {
        "value": "Chicagon, Michigan, United States",
        "postcode": "",
        "data": {
          "lat": 46.095231,
          "lng": -88.507357,
          "relevance": 0.96
        }
      }
    ],
    "from": [
      "40.0292888",
      "-105.3100174"
    ],
    "session": {
      "id": "abc999"
     }
  }
}

We can utilize the session ID, coordinates and URL-encoded location name returned in the location/suggest payload to switch the shopper's location for the duration of their session.

import LCLY from "@locally-com/lcly-js-sdk"

const client = new LCLY("{{MY_TOKEN}}")

async function main() {
    const result = await client.location().get('switch', {
        lat: "41.875562",
        lng: "-87.624421",
        location_change_to_string: "Chicago,+Illinois,+United+States"
    }, {
      'Locally-Api-Session-Id': "abc999",
    })

    console.log(result)
}

main()

Response:

{
  "success": true,
  "data": {
    "city_label": "Chicago, IL",
    "country": "US",
    "zip_label": "60604",
    "postal_code": "60604",
    "lat": "41.87758900",
    "lng": "-87.62818000",
    "source": "region",
    "base_url": "/in/chicago-il",
    "distance_unit": "mi",
    "session": {
      "id": "abc999"
     }
  }
}

The response confirms a successful location change has been applied to this shopper's location. To persist the location in subsequent requests, we can now go through the normal initialization workflow, being mindful to pass the session ID:

import LCLY from "@locally-com/lcly-js-sdk"

const client = new LCLY("{{ MY_TOKEN }}")

async function main() {
    const result = await client.conversion().get('start', {
        upc: "{{ UPC }}",
        product_id: {{ PRODUCT_ID }},
        company_id: {{ COMPANY_ID }}
    },{
        'Locally-Api-Session-Id': "abc999",
    })

    console.log(result)
}

main()