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

@gucciogucci/contented

v5.2.0

Published

A library to coerce values at run-time.

Downloads

365

Readme

Table of Contents

Introduction

Contented is a TypeScript library for performing type coercion at run-time. To this end, Contented introduces run-time representations of primitive types, such as string, which can be then mixed and matched to describe compound types.

import { string, number, object } from '@gucciogucci/contented';

const Image = object({
  url: string,
  size: number
});

Contented may be useful every time there are expectations — but no real guarantees, on the shape of data acquired at run-time. Common use cases include processing data coming over the wire, from files, or any other external source.

Reference

Coercing

isValid(T, input)

A type-guard that returns true if input is evaluated to be a T, and false otherwise.

import { number, object, isValid } from '@gucciogucci/contented';

const Point = object({
  x: number,
  y: number
});

if (isValid(Point, input)) {
  // here input: { x: number, y: number }
}

explain(T, input)

Explains why input cannot be coerced to T. It returns undefined if no explanation is needed, that is, if input is in fact a T.

import { number, object, explain } from '@gucciogucci/contented';

const Point = object({
  x: number,
  y: number
});

explain(Point, { x: 10 });
/* {
     value: { x: 10 },
     isNot: { object: { x: 'number', y: 'number' } },
     since: [ { missingKey: 'y' } ]
   }
*/

explain(Point, { x: 'hello', y: 'there' })
/* {
     value: { x: 'hello', y: 'there' },
     isNot: { object: { x: 'number', y: 'number' } },
     since: [
       { atKey: 'x', value: 'hello', isNot: 'number' },
       { atKey: 'y', value: 'there', isNot: 'number' }
     ]
   }
*/

explain(Point, { x: 10, y : 20 });
// undefined

Primitive types

string

A run-time representation of the string type.

import { string, isValid, explain } from '@gucciogucci/contented';

isValid(string, 'hello');
// true

explain(string, 42);
// { value: 42, isNot: 'string' }

number

A run-time representation of the number type.

import { number, isValid, explain } from '@gucciogucci/contented';

isValid(number, 42);
// true

explain(number, 'hello');
// { value: 'hello', isNot: 'number' }

bigint

A run-time representation of the bigint type.

import { bigint, isValid, explain } from '@gucciogucci/contented';

isValid(bigint, 1024n);
// true

explain(bigint, 'hello');
// { value: 'hello', isNot: 'bigint' }

boolean

A run-time representation of the boolean type.

import { boolean, isValid, explain } from '@gucciogucci/contented';

isValid(boolean, false);
// true

explain(boolean, 'hello');
// { value: 'hello', isNot: 'boolean' }

null_

A run-time representation of the null type. The trailing underscore is to avoid shadowing the built-in null value.

import { null_, isValid, explain } from '@gucciogucci/contented';

isValid(null_, null);
// true

explain(null_, 'hello');
// { value: 'hello', isNot: 'null' }

Literal types

literal

A run-time representation of the narrowest type that can be constructed from value. Hence, coercions to literal(value) succeed only when value is provided as an input.

import { literal, isValid, explain } from '@gucciogucci/contented';

isValid(literal('hello'), 'hello');
// true

explain(literal('hello'), 'foo');
// { value: 'foo', isNot: { literal: 'hello' }  }

Compound types

object

A run-time representation of an object.

import { number, object, isValid, explain } from '@gucciogucci/contented';

const Point = object({ x: number, y: number });

isValid(Point, { x: 10, y : 20 });
// true

explain(Point, { x: 10 });
/* {
     value: { x: 10 },
     isNot: { object: { x: 'number', y: 'number' } },
     since: [ { missingKey: 'y' } ]
   }
*/

As with compile-time types, optional properties are marked by adding a ? at the end of their names:

import { number, object, isValid } from '@gucciogucci/contented';

const Point = object({ x: number, y: number, 'z?': number })

isValid(Point, { x: 10, y: 20 });
// true

isValid(Point, { x: 10, y: 20, z: 30 });
// true

isValid(Point, { x: 10, y: 20, z: undefined });
// true

arrayOf(T)

A run-time representation of an array of Ts, where T denotes the run-time representation of its element type.

import { number, arrayOf, isValid, explain } from '@gucciogucci/contented';

isValid(arrayOf(number), [ 3, 4, 5 ]);
// true

explain(arrayOf(number), 'hello');
// { value: 'hello', isNot: { arrayOf: 'number' } }

explain(arrayOf(number), [ 3, 'a', 5 ]);
/* {
     value: [ 3, 'a', 5 ],
     isNot: { arrayOf: 'number' },
     since: [ { atKey: 1, value: 'a', isNot: 'number' } ]
   }
*/

oneOf(T1, T2, ...Ts)

A run-time representation of the union type T1 | T2 | ...Ts.

import { oneOf, literal, isValid, explain } from '@gucciogucci/contented';

const abc = oneOf(literal('a'), literal('b'), literal('c'));

isValid(abc, 'a');
// true

explain(abc, 'd');
/* {
     value: 'd',
     isNot: { oneOf: [ { literal: 'a' }, { literal: 'b' }, { literal: 'c' } ] },
     since: [
       { value: 'd', isNot: { literal: 'a' } },
       { value: 'd', isNot: { literal: 'b' } },
       { value: 'd', isNot: { literal: 'c' } }
     ]
   }
*/

allOf(T1, T2, ...Ts)

A run-time representation of the intersection type T1 & T2 & ...Ts.

import { allOf, object, number, isValid, explain } from '@gucciogucci/contented';

const abObject = allOf(object({ a: number }), object({ b: number }));

isValid(abObject, { a: 10, b: 20 });
// true

explain(abObject, { a: 10 });
/* {
     value: { a: 10 },
     isNot: { allOf: [ { object: { a: 'number' } }, { object: { b: 'number' } } ] },
     since: [{
       value: { a: 10 },
       isNot: { object: { b: 'number' } },
       since: [ { missingKey: 'b' } ]
     }]
   }
*/

Utility types

Infer

Infer comes in handy every time it is necessary to infer the compile-time type corresponding to some run-time representation T.

import { Infer, string, object } from '@gucciogucci/contented';

const User = object({
  name: string,
  surname: string,
  contacts: object({ phone: string })
});

function fn(user: Infer<typeof User>) {
  // here, user: { name: string; surname: string; contacts: { phone: string } }
}

License

Copyright 2024 Gucci.

Licensed under the GNU Lesser General Public License, Version 3.0