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

@ceptesoft/geo-link-parser

v0.2.0

Published

Turns messy real-world location shares (WhatsApp, Google Maps links, short links) into a routable "lat,lng" or address string. Injectable fetch, zero dependencies.

Readme

@ceptesoft/geo-link-parser

Turns messy real-world location shares into a routable destination string: "lat,lng", an address text, or null. Handles Google Maps, Yandex Maps, Apple Maps, OpenStreetMap links and bare coordinate text. Zero dependencies; short-link resolution uses an injectable fetch (defaults to globalThis.fetch), so it runs in Node, browsers, workers, and tests without network access.

Extracted from production route-planning code (CepteCari), where customers paste whatever their phone gives them: WhatsApp shares, maps.app.goo.gl short links, ?q= links, or plain coordinates.

Why not write this yourself? The formats hide traps. The best known: Yandex Maps ll=/pt= parameters are lon,lat — the reverse of every other provider. Parse them naively and every Yandex share lands ~kilometers away at a mirrored coordinate. This package carries those traps as tests.

Scope boundary: parsing/resolution only — no geocoding of address text (pass the returned string to your geocoding or Distance Matrix API).

Install

npm install @ceptesoft/geo-link-parser

Quickstart

import { normalizeLocation, parseLocationLink } from "@ceptesoft/geo-link-parser";

// Sync parse of one link/text (no HTTP)
parseLocationLink("https://www.google.com/maps/place/X/@39.75,30.49,13z"); // "39.75,30.49"
parseLocationLink("https://www.google.com/maps?q=Eskisehir+Merkez");       // "Eskisehir Merkez"
parseLocationLink("konum: 39.75,30.49");                                    // "39.75,30.49"

// Full pipeline: stored coords win → short links resolved → parsed
const destination = await normalizeLocation({
  link: "https://maps.app.goo.gl/abc123",
  latitude: null,
  longitude: null,
});
// e.g. "39.75,30.49"

Inject a custom fetch (tests, proxies, non-standard runtimes):

const destination = await normalizeLocation(
  { link: "https://goo.gl/xyz" },
  { fetch: async (url, init) => myHttpClient.follow(url, init) }
);

API

normalizeLocation(input, options?): Promise<string | null>

input: { link, latitude?, longitude? }. Precedence: valid stored coordinates → link (short links resolved by following redirects, retrying with a mobile User-Agent when the first result is unparseable) → parse.

options: fetch (FetchLike, default globalThis.fetch), shortLinkHosts (default goo.gl domains), userAgents (tried in order).

parseLocationLink(urlString): string | null

Synchronous single-string parse. Precedence: Yandex whatshere[point]/pt/ ll (lon,lat — swapped) → path @lat,lngdata=!3d!4d → path lat,lngll=/coordinate= (lat,lng) → mlat/mlon and lat/lon|lng pairs → #map=zoom/lat/lon (OSM) → q/query/address (coords, else returned as address text) → hash → whole decoded text.

Covered provider formats:

| Provider | Formats | |---|---| | Google Maps | @lat,lng path, data=!3d!4d, ll=, q=/query=, short links (via normalizeLocation) | | Yandex Maps | ll=, pt=, whatshere[point]= — all lon,lat, swapped automatically | | Apple Maps | ll=, coordinate= (/place links), address= text fallback | | OpenStreetMap | mlat/mlon markers, #map=zoom/lat/lon, generic lat/lon pairs |

isValidLatLng(lat, lng): boolean

WGS84 bounds + finiteness check.