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

@noidme/cmp-migrate

v0.1.0-beta.0

Published

Migrate from another CMP. Convert an incumbent consent-management config (OneTrust, Cookiebot, …) into a noidme.js PolicyConfig so a prospect can switch without re-mapping everything, plus a diff/summary report of what mapped and what didn't. Zero-depende

Readme

@noidme/cmp-migrate

Zero-dependency CMP migration importers. Convert an incumbent consent-management config (OneTrust, Cookiebot, Ketch, …) into a noidme.js PolicyConfig so a prospect can switch without re-mapping everything by hand — plus a diff/summary report of what mapped and what didn't.

Extracted from noidme.js; usable standalone.

A competitor export is untrusted input, and the output is a suggested PolicyConfig that a human must review before enforcing. The input shapes are representative of each vendor's export; real exports vary by account and version, so every importer returns a report of what mapped, what didn't, what was rejected, and — critically — which hosts would become never-blocked (report.essentialCandidates).

Install

npm i @noidme/cmp-migrate

Usage

import { importOneTrust, importCookiebot, importKetch } from '@noidme/cmp-migrate';

const { config, report } = importOneTrust(oneTrustExport);
// config → a noidme.js PolicyConfig (hosts, essentialSuffixes, …)
// report → { source, entries, processed, byPurpose, unmapped, rejected, essentialCandidates, conflicts }

if (report.essentialCandidates.length) {
  // These hosts would be NEVER blocked — the highest-trust decision. Review before enforcing.
  console.warn('Review — becomes never-blocked:', report.essentialCandidates);
}
if (report.unmapped.length) console.warn('Category could not be mapped:', report.unmapped);
if (report.rejected.length) console.warn('Dropped as unsafe:', report.rejected);

Report fields

| field | meaning | | --------------------- | ----------------------------------------------------------------------------- | | entries | total input rows (entries === processed + unmapped.length + rejected.length)| | processed | rows that mapped to a purpose (summed in byPurpose) | | byPurpose | count per purpose | | unmapped | host (category) — category couldn't be mapped | | rejected | host (reason) — dropped by a safety guard (empty / dangerous / public suffix)| | essentialCandidates | hosts whose winning purpose is essential → never-blocked; review these | | conflicts | hosts seen in multiple groups (most-restrictive purpose kept) |

Import stored consent values

import { importConsentValues } from '@noidme/cmp-migrate';

// Turn a competitor's category→granted map into a purpose-keyed ConsentMap.
const consent = importConsentValues({ Analytics: true, Advertising: false });
// { analytics: true, advertising: false }

Deny-wins: if several source keys map to the same purpose and any is not granted, the purpose is denied. In a migration, over-blocking is the privacy-safe failure — a sticky grant would silently under-block.

Category mapping

mapCategory(name) maps a vendor category label to a noidme purpose by whole-token keyword match (advertising, analytics, functional, social, essential), returning null when nothing matches so the caller can flag it rather than guess. essential is last-resort: a real tracking category always wins over an incidental security/essential token.

Security

Competitor exports are untrusted input, so the importers actively defend the enforcement boundary:

  • No prototype pollution. __proto__, constructor, and prototype are dropped from host and consent maps.
  • No essential-laundering. essential maps last, and a host's most-restrictive purpose across all groups wins — so a tracker tagged Advertising in one group and Security in another resolves to advertising (blocked), never to the never-blocked allowlist. Every host that does become essential is surfaced in report.essentialCandidates for review.
  • No public-suffix bypass. A bare TLD or public-suffix host (com, co.uk) is rejected before it can enter essentialSuffixes, where it would otherwise match every subdomain.

API

  • importOneTrust(cfg): ImportResult
  • importCookiebot(cfg): ImportResult
  • importKetch(cfg): ImportResult
  • importConsentValues(values, categoryMap?): ConsentMap
  • mapCategory(name): string | null

ImportResult = { config: PolicyConfig; report: ImportReport } (see the report-fields table above).

License

MIT