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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@ksf-media/vetrina

v4.1.1

Published

Vetrina, frontend for purchasing KSF Media products

Downloads

30

Readme

ksf-media/vetrina

For javascript use

Install it from npm yarn add @ksf-media/vetrina and just import it into your project:

import ReactDOM from 'react-dom';
import { Vetrina } from '@ksf-media/vetrina';
var renderVetrina = function() {
  ReactDOM.render(
    <Vetrina products={[
      {
        id: "HBL",
        description: <div>HBL is amazing!</div>,
        descriptionPurchaseCompleted: <div>You can now read premium content of HBL.fi</div>,
        priceCents: 990
      }
    ]}/>
    , document.getElementById('vetrina'));
};

Props

The props/callbacks for Vetrina are

  • onClose
    • this is called when the purchase is done and should be probably used for closing Vetrina
    • if missing, the "completed" view is shown with out a button, as sometimes there is no need for a final action
    • () => { console.log("Purchase done!") }
  • onLogin
    • used for invoking whatever functionality the embedding part has for logging in users
    • () => { openLoginModal() }
  • products
    • an array of Products we want to be subscribeable, see type of Product below
    • products={[id: "HBL", description: <div>HBL is amazing!</div>, priceCents: 990, name: "HBL Premium" }]}
    • if multiple products are given, a dropdown is shown listing the products (if minimalLayout=true, it will be shown even with one product)
  • unexpectedError
    • a view to be rendered when an unexpected error occurs (for example, if vetrina fails to initialize entirely)
    • <div>Error!</div>
  • accessEntitlements
    • a list of entitlement names required to do the action the parent wants
    • if at least one of the entitlements given matches with the user entitlements, vetrina will not proceed with the purchase
    • [ "hbl-web", "hbl-epaper" ]
  • headline
    • headline to show above Vetrina (JSX)
    • headline={<div className="vetrina--headline">Läs HBL digitalt för <span className="vetrina--price-headline">endast 1€</span></div>}
  • paper
    • name of the paper (brand) in question
    • paper should belong to ("HBL", "VN", "ON", "ÖN", "ÖNY", "KSF")
    • if paper is missing or invalid, the brand neutral "KSF" is used
  • paymentMethods
    • list of payment methods to choose from, supported methods currently are "creditcard" and "paperinvoice"
    • [ "creditcard", "paperinvoice" ]
    • if missing, "creditcard" is used by default
  • minimalLayout
    • a boolean to switch minimal layout on or off
    • this will leave most of the copy and product descriptions out

Product

type Product =
  { id                           :: String -- The package id of the product
  , name                         :: String -- Name of the product, e.g. "Hufvudstadsbladet Premium"
  , priceCents                   :: Int -- The product price in cents
  , description                  :: JSX -- Description is JSX and it's shown when selecting a product (optional)
  , descriptionPurchaseCompleted :: JSX -- A description/guide to show when the purchase is completed (optional)
  , campaign                     :: Maybe Campaign -- The campaign used for this product (optional). Note however that if the campaign is somehow defined, but faulty, error will be thrown
  , contents                     :: Array ProductContent -- For describing the product in more detail (optional)
  }

type Campaign =
  { no         :: Int
  , id         :: String
  , name       :: String
  , length     :: Int
  , lengthUnit :: String -- Should belong to `("day", "month", "week", "year")`
  , priceEur   :: Number
  }

type ProductContent =
  { description :: String
  , title       :: String
  }

Getting it up and running

Depending on the production environment we're in (dev, prod), the configuration settings for these features might differ.

Vetrina expects the following configuration variables to be present:

  • PERSONA_URL
  • BOTTEGA_URL

dotenv is used for setting the variables in place.

Publishing

Run npm publish - this will run the end-to-end tests, which you should fix before publishing.