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

@flyyer/variables

v2.1.3

Published

Helper module to create a `schema` that enables Flyyer to display template's variables on https://flyyer.io for decks and templates.

Downloads

21

Readme

@flyyer/variables

Helper module to create a schema that enables Flyyer to display template's variables on https://flyyer.io for decks and templates.

npm install --save @flyyer/variables

# if you prefer yarn:
yarn add @flyyer/variables

Some of our official free templates are using @flyyer/variables:

  • 🌠 flyyer.io/@/flyyer/simple-products
    • Source-code: github.com/useflyyer/flyyer-marketplace-simpleproducts
  • 🌠 flyyer.io/@/flyyer/nice-typography
    • Source-code: github.com/useflyyer/flyyer-marketplace-nicetypography
  • 🌠 flyyer.io/@/flyyer/branded
    • Source-code: github.com/useflyyer/flyyer-marketplace-brand

Here is what a template with an exported schema looks like:

Final result on flyyer.io dashboard

Note: Not every JSON-Schema is supported on Flyyer UI, try to use a plain object and avoid complex types such as Union, Object, Array, etc.

Usage

import { Variable as V, Static, Validator } from "@flyyer/variables";

/**
 * Export `const schema = V.Object({})` to make variables visible on https://flyyer.io/
 */
export const schema = V.Object({
  title: V.String({ description: "Displayed on https://flyyer.io" }),
  price: V.Nullable(V.Number()),
  image: V.Optional(V.Image({
    description: "Image URL",
    examples: ["https://flyyer.io/logo.png"],
  })),
  font: V.Optional(V.Font({
    default: "Inter", // https://github.com/useflyyer/use-googlefonts
  })),
});
const validator = new Validator(schema);

// Remove line and TemplateProps<Variables> if using plain Javascript
type Variables = Static<typeof schema>;

export default function Template({ variables }: TemplateProps<Variables>) {
  if (validator.validate(variables)) {
    const title = variables["title"]; // type is `string`
    const price = variables["price"]; // type is `number | null`
    const image = variables["image"]; // type is `string | undefined` and has URL format.
    const font = variables["font"]; // type is `string | undefined`, use with @flyyer/use-googlefonts
    // ...
  }
}

Optimistic usage

Using the same schema from the previous example, if you prefer a more optimistic validation you can use:

const {
  data: { title, price, image }
} = validator.parse(variables);

// Optimistic path but variables might not be compliant with the schema.

Instead of (strict validation):

if (validator.validate(variables)) {
  // Happy path with compliant variables
} else {
  // Show empty or error to the user.
}

Useful types

Most common types with full flyyer.io UI support are:

  • V.String()
  • V.Integer()
  • V.Number() for floats
  • V.Boolean()
  • V.DateTime(), V.Date(), and V.Time() (V.DateTime() has the best compatibility)
  • V.URL()
  • V.Image()
  • V.Font()
  • V.ColorHex()
  • V.Enum()
  • V.EnumKeys()

Modifiers:

  • V.Optional()
  • V.Null()
  • V.Optional(V.Null())

You should be able to cover most cases with these types.

Provide default value

Default values are used when incoming variable is undefined.

export const schema = V.Object({
  title: V.String({ default: "Hello world" }),
});

Provide example values

On flyyer.io many template previews are rendered using the first provided examples value of each property with fallback to default.

🚨 The examples property must be an array

export const schema = V.Object({
  image: V.Image({ examples: ["https://flyyer.io/logo.png"] }),
});

E-commerce

For E-commerce templates you probably want to display the price and currency of a product. Currently we haven't defined a proper V.Price and V.Currency methods yet. We recommended sticking with price: V.Number and currency: V.String until we have enough information to create those methods.

Production example: https://github.com/useflyyer/flyyer-marketplace-simpleproducts

Example:

import { Variable as V, Validator } from '@flyyer/variables';

export const schema = V.Object({
  currency: V.Optional(
    V.String({ default: 'USD', examples: ['USD', 'EUR'] }),
  ),
  price: V.Optional(
    V.Number({ examples: ['59.99'] }),
  ),
});
const validator = new Validator(schema);

// props are provided by our systems
export default function Template({ variables, locale }) {
  const {
    data: {
      currency, // type is `string | undefined`
      price, // type is `number | undefined`
    }
  } = validator.parse(variables);

  const formatter = new Intl.NumberFormat(locale, {
    style: 'currency',
    currency: currency,
    currencyDisplay: 'symbol'
  });

  if (Number.isFinite(price) && price === 0) {
    return <p>Free</p>;
  } else (Number.isFinite(price)) {
    return <p>{formatter.format(price)}</p>
  } else {
    return null; // Do not display price if user sets input to null or blank,
  }
}

Enums

TypeScript has the enum type. This library can create a schema for these enums based on their keys or their values.

  • Create enum schema with keys: V.EnumKeys
  • Create enum schema with values: V.Enum
enum Alignment {
  Y = "flex flex-col justify-center",
  X = "flex flex-row justify-center",
}
const schema = V.Object({
  keys: V.EnumKeys(Alignment, { default: "X" }),
  values: V.Enum(Alignment, { default: Alignment.X }),
});

What is the difference? If you want to display the enum's key on the UI at flyyer.io you should use V.EnumKeys which is more clear to the user.

// Let the user pick between "X" or "Y" on flyyer.io UI.
const schema = V.Object({
  alignment: V.EnumKeys(Alignment, { default: "X" }),
});

Recommendations

JSON Schemas can be super complex and allow a lot of custom settings. At Flyyer.io we recommend sticking to a simple 1-level object for the better final user experience.

// ⚠️ Works via @flyyer/flyyer and API but not handled by Flyyer.io UI (dashboard)
export const schema = V.Object({
  title: V.Object({
    text: V.String(),
    color: V.ColorHex({ default: "#FFFFFF" }),
    font: V.Font({ default: "Inter" }),
  })
});
/* https://cdn.flyyer.io/render/v2/tenant/deck/template?title[text]=Hello&title[font]=Roboto */
/* https://cdn.flyyer.io/v2/project/_/title[text]=Hello&title[font]=Roboto/path */

// ✅ Recommended! works via @flyyer/flyyer, API, and Flyyer.io UI (dashboard)
export const schema = V.Object({
  title: V.String(),
  titleColor: V.ColorHex({ default: "#FFFFFF" }),
  titleFont: V.Font({ default: "Inter" }),
});
/* https://cdn.flyyer.io/render/v2/tenant/deck/template?title=Hello&titleFont=Roboto */
/* https://cdn.flyyer.io/v2/project/_/title=Hello&titleFont=Roboto/path */
// It also produces shorter URLs to generate images which is good.

Credits to https://github.com/sinclairzx81/typebox to enable creating a JSON Schema with an amazing developer experience.