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

@vatvaghool/ipl-fantasy-dashboard

v0.1.1

Published

Safe, reusable IPL fantasy dashboard transformation utilities.

Readme

@vatvaghool/ipl-fantasy-dashboard

TypeScript utilities extracted from the IPL fantasy dashboard project for normalizing fantasy leaderboard payloads, building dashboard-friendly data, and syncing raw match history forward from live snapshots.

This package is safe to publish publicly on npm because it does not include the private Next.js web app, MongoDB connection code, live snapshots, browser auth files, or bookmarklet secrets.

What This Package Is

This package contains the reusable data layer from the dashboard project:

  • payload normalization
  • leaderboard metric calculation
  • raw-user normalization
  • manual dashboard shaping
  • live snapshot merge helpers
  • raw-user sync helpers
  • TypeScript data types

It is useful if you want to:

  • normalize fantasy leaderboard payloads in your own app
  • build charts or analytics from raw team/match history
  • merge live standings into a historical dashboard model
  • keep your own storage layer while reusing the IPL-specific transforms

What This Package Does Not Include

This npm package does not publish:

  • the Next.js web app UI
  • MongoDB connection logic
  • .env values
  • ipl-auth.json
  • live snapshot seed files
  • bookmarklet endpoint code
  • local or deployed secrets

If you want the full dashboard web app with MongoDB setup and bookmarklet ingestion flow, use the source repository, not this package alone.

Install

npm install @vatvaghool/ipl-fantasy-dashboard

Exported API

Functions

  • toFiniteNumber
  • normalizePayload
  • normalizeRawApiUsers
  • addLeaderboardMetrics
  • buildManualDashboard
  • buildDashboardFromSnapshot
  • syncRawUsersWithSnapshot
  • serializeRawApiUsersModule

Types

  • DailyChartRow
  • DashboardData
  • OverallChartItem
  • RawApiUser
  • RawUsersSyncResult
  • ScrapedDashboardPayload
  • ScrapedLeaderboardItem
  • ScrapedSquadPlayer
  • TransformOptions

Basic Usage

import {
  buildDashboardFromSnapshot,
  buildManualDashboard,
  normalizePayload,
  normalizeRawApiUsers,
  syncRawUsersWithSnapshot,
} from "@vatvaghool/ipl-fantasy-dashboard";

const rawUsers = normalizeRawApiUsers([
  {
    rno: 1,
    temname: "Deccan Dominators",
    matches: [
      { matchId: 1, points: 120 },
      { matchId: 2, points: 88 },
    ],
  },
]);

const snapshot = normalizePayload({
  updatedAt: "2026-04-28T09:15:00.000Z",
  completedMatches: 41,
  leaders: [
    {
      rank: 1,
      name: "Deccan Dominators",
      points: 240,
      lastMatchPoints: 32,
      transfersLeft: 101,
    },
  ],
});

if (rawUsers && snapshot) {
  const manualDashboard = buildManualDashboard(rawUsers);
  const liveDashboard = buildDashboardFromSnapshot(snapshot, manualDashboard);
  const syncResult = syncRawUsersWithSnapshot(rawUsers, snapshot);

  console.log(liveDashboard.overall[0]);
  console.log(syncResult.status);
}

Using Team Aliases

Some fantasy exports may use one team name in raw match history and another team name in scraped live snapshots. Use teamAliases to map those names together.

import { normalizePayload, syncRawUsersWithSnapshot } from "@vatvaghool/ipl-fantasy-dashboard";

const snapshot = normalizePayload(incomingPayload, {
  teamAliases: {
    "Team RJ": "Raviteja Jakkani",
    "WATAPI11": "Rishikesh Shinde",
  },
});

const result = syncRawUsersWithSnapshot(rawUsers, snapshot!, {
  teamAliases: {
    "Team RJ": "Raviteja Jakkani",
    "WATAPI11": "Rishikesh Shinde",
  },
});

Main Functions In Detail

normalizePayload(payload, options?)

Accepts a scraped, partial, or mixed-format fantasy payload and converts it into a consistent ScrapedDashboardPayload.

It supports shapes such as:

  • { leaders: [...] }
  • raw leaderboard arrays
  • nested Data.Value payloads
  • bookmarklet-style payload fields like time, match, last, c, and v

Returns:

  • normalized payload object when valid
  • null when the input cannot be normalized

normalizeRawApiUsers(payload)

Normalizes raw match-history users into the RawApiUser[] shape:

  • trims names
  • parses numeric values
  • sorts matches by matchId
  • recalculates total points

Returns:

  • normalized array when valid
  • null when the input is invalid

buildManualDashboard(users, options?)

Builds a full historical dashboard structure from raw match history alone.

Returns a DashboardData object with:

  • overall
  • daily
  • source: "database"

buildDashboardFromSnapshot(snapshot, manualDashboard, options?)

Merges a live snapshot into the historical dashboard data.

If latest match points exist in the snapshot, a Live Update row is appended to the daily data.

addLeaderboardMetrics(leaders, options?)

Enriches leaderboard rows with:

  • previous rank
  • previous points
  • gap to next
  • gap percent
  • movement
  • transfer efficiency
  • last-match leader flag

syncRawUsersWithSnapshot(users, snapshot, options?)

Compares live leaderboard totals against stored raw match history and tries to move the raw data forward safely.

It returns:

  • status
  • updated users
  • matchId
  • mode
  • completedMatches
  • unmatchedNames

Possible statuses:

  • updated
  • unchanged
  • skipped

Transform Options

Most helpers accept an optional TransformOptions object:

type TransformOptions = {
  teamAliases?: Record<string, string>;
  totalTransfers?: number;
};

teamAliases

Use this when scraped and stored team names differ.

totalTransfers

Defaults to 210. Override this if your fantasy rules use a different total transfer count.

Example Input Payload

{
  "updatedAt": "2026-04-28T09:15:00.000Z",
  "completedMatches": 41,
  "leaders": [
    {
      "rank": 1,
      "name": "Deccan Dominators",
      "points": 7125,
      "lastMatchPoints": 52.5,
      "transfersLeft": 101,
      "boostersUsed": "1"
    }
  ]
}

Example Workflow

If you are building your own service around this package, a common flow looks like this:

  1. Read your stored raw match-history users from your database.
  2. Normalize any incoming live payload with normalizePayload.
  3. Build historical dashboard data using buildManualDashboard.
  4. Merge the live snapshot with buildDashboardFromSnapshot.
  5. Sync raw users forward with syncRawUsersWithSnapshot.
  6. Store the updated raw users and latest snapshot in your own database.

Relationship To The Full Web App

This npm package comes from a larger private dashboard project. The full web app includes:

  • a Next.js dashboard UI
  • MongoDB-backed API routes
  • a bookmarklet endpoint at /api/ipl/bookmarklet
  • local fallback seed files
  • optional Playwright automation

That full app is not published in this package.

If you cloned the source repo and want to run the full dashboard locally, the web app setup is documented in the root project README and includes:

  • MONGODB_URI setup
  • IPL_POST_SECRET usage
  • npm run dev:simple
  • npm run seed:mongodb
  • bookmarklet generation from /api/ipl/bookmarklet

Publish Notes

This package is already structured so that npm publishes only:

  • dist/
  • this package README
  • this package package.json

That keeps app-private files out of the public tarball.

Local Publish Checklist

From the source repo root:

npm run build:utils-package
npm run pack:utils-package

Then publish from the package directory:

cd packages/ipl-dashboard-utils
npm login
npm publish --access public

License

UNLICENSED