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

schemata-ts

v2.2.3

Published

An all-inclusive schema engine featuring schemata inspired by io-ts and validators.js. Written for TypeScript with fp-ts

Downloads

1,541

Readme

Welcome

Schemata-ts is an unofficial continuation of io-ts v2 built from the ground up using the highly extensible Schemable/Schema API. Schemata also comes with a suite of string validation schemas and branded types — powered by Kuvio — all inspired by io-ts-types and validators.js.

| | Features | | --- | -------------------------------------------------------------------------------------- | | ✅ | Validation, Parsing, and Serialization | | ✅ | Type Guards | | ✅ | Json-Schema Draft 07, 2019-09, and 2020-12 | | ✅ | Fast-Check Arbitraries | | ✅ | and more |

Installation

Yarn

yarn add schemata-ts

NPM

npm install schemata-ts

PNPM

pnpm add schemata-ts

A note on fast-check: Schemata lists fast-check as a peer dependency. As a result, it doesn't need to be installed for schemata to work. It is recommended to install fast-check as a dev dependency which will satisfy the peer dependency requirement. To avoid fast-check being bundled in a front-end application, only import from the Arbitrary module in test files.

Schema

A Schema is a simple function that's architected using service-oriented principles. It's a function that takes a Schemable which is an interface of capabilities that produce a particular data-type. Schemas aren't intended to be constructed by users of the library but instead are pre-constructed and exported from the root directory.

The following import will give you access to all of the pre-constructed schemas.

import * as S from 'schemata-ts'

In addition to "primitive" schemas like S.String(params?), S.Int(params?), S.Boolean, schemata-ts also exports schema combinators from the root directory. 'Combinator' is a fancy word for a function that takes one or more schemas and returns a new schema. For example, S.Array(S.String()) is a schema over an array of strings, and S.Struct({ foo: S.String() }) is a schema over an object with a single property foo which is a string.

Schema Example

import * as S from 'schemata-ts'

export const PersonSchema = S.Struct({
  name: S.String(),
  age: S.Int({ min: 0, max: 120 }),
  isCool: S.Boolean,
  favoriteColors: S.Array(S.String()),
})

Schema Transformations

There are three ways to transform a schema in schemata-ts: 'combinators' which are functions that take schemas as parameters and return new schemas, 'transformers' which are specific to particular schemata, and Imap which applies an invariant transformation to the underlying data-type.

Invariant Transformations

Aside from Guard, all data-types derivable from schemas are invariant functors. This means that supplying mapping functions to and from to Imap adjusts the Output of that particular data type. Because Guard is not invariant, you must supply the resulting Guard to the invariant map. The combinator version of this is Imap. In version 3.0 (coming late 2023/early 2024) it will be possible to .imap() any schema.

Schema Transformers

Schema transformers are classes which extend SchemaImplementation, and allow adjustment to the underlying schema parameters after it has been declared in an immutable fashion. This is useful for type-specific methods like pick or omit for Struct.

Here are the current transformers and available methods,

  • Struct: pick, omit, partial, partialOption, readonly, strict, addIndexSignature, extend, intersect
  • Array: minLength, maxLength, nonEmpty
  • String: brand, minLength, maxLength, errorName
  • Int: brand, min, max, errorName
  • Float: brand, min, max, errorName
  • Tuple: append, prepend

... with more to come!

Transformation Example

const SoftwareDeveloperSchema = PersonSchema.omit('isCool')
  .extend({
    favoriteLanguages: S.Array(S.String()),
    favoriteFrameworks: S.Array(S.String()),
  })
  .strict()

TypeScript Types

Schemas can be used to extract the underlying TypeScript type to avoid writing the same definition twice and different parts of code getting out of sync.

Schemas have reference to both the input and output type. The input type is more often for usage outside of JavaScript land (such as over the wire in an API request), and the output type is more often for usage within JavaScript land.

export type Person = S.OutputOf<typeof PersonSchema>

export type PersonInput = S.InputOf<typeof PersonSchema>

Validation, Parsing, and Serialization

Schemata-ts's type-class for validation and parsing is called "Transcoder." Transcoders can be derived from schemas using deriveTranscoder:

import { deriveTranscoder, type Transcoder } from 'schemata-ts/Transcoder'

const personTranscoder: Transcoder<PersonInput, Person> = deriveTranscoder(PersonSchema)

Transcoders are intended to succeed Decoder, Encoder, and Codec from io-ts v2. They contain two methods: decode and encode. The decode method takes an unknown value to an fp-ts Either type where the failure type is a schemata-ts error tree called TranscodeError, and the success type is the output type of the schema.

Transcoder Transformations (Advanced)

In addition to parsing an unknown value, Transcoder can transform input types. One example is MapFromEntries which takes an array of key-value pairs and transforms it into a JavaScript Map type.

import * as Str from 'fp-ts/string'

const PeopleSchema = S.MapFromEntries(Str.Ord, S.String(), PersonSchema)

const peopleTranscoder: Transcoder<
  ReadonlyArray<readonly [string, PersonInput]>,
  ReadonlyMap<string, Person>
> = deriveTranscoder(PeopleSchema)

Transcoder Serialization (Advanced)

Schemas can be turned into printer-parsers using various Parser schemas, such as:

(De)Serialization from Json String:

const parsePersonTranscoder: Transcoder<S.JsonString, Person> = deriveTranscoder(
  S.ParseJsonString(PersonSchema),
)

or, (De)Serialization from a Base-64 encoded Json String:

const parsePersonTranscoder: Transcoder<S.Base64, Person> = deriveTranscoder(
  S.ParseBase64Json(PersonSchema),
)

Transcoder Parallelized Validation (Advanced)

Transcoders can be parallelized using TranscoderPar which is a typeclass similar to Transcoder but returns TaskEithers instead of Eithers. This allows for parallelized validation for schemas of multiple values like structs and arrays.

import { deriveTranscoderPar, type TranscoderPar } from 'schemata-ts/TranscoderPar'

const personTranscoderPar: TranscoderPar<PersonInput, Person> =
  deriveTranscoderPar(PersonSchema)

Transcoder Documentation

Type Guards

Type guards are used by TypeScript to narrow the type of a value to something concrete. Guards can be derived from schemas using deriveGuard:

import { deriveGuard, type Guard } from 'schemata-ts/Guard'

const guardPerson: Guard<Person> = deriveGuard(PersonSchema)

Type Guard Documentation

JSON Schema (Draft 7, 2019-09, and 2020-12)

Json-Schema is a standard for describing JSON data. Schemata-ts can derive Json-Schema from schemas using deriveJsonSchema for versions Draft-07, 2019-09, and 2020-12.

import { deriveJsonSchema } from 'schemata-ts/JsonSchema'

const personJsonSchemaDraft07 = deriveJsonSchema(PersonSchema, 'Draft-07')
const personJsonSchema2019 = deriveJsonSchema(PersonSchema)
const personJsonSchema2020 = deriveJsonSchema(PersonSchema, '2020-12')

JSON Schema Documentation

Fast-Check Arbitraries

Fast-Check is a property-based testing library for JavaScript. Schemata-ts can derive fast-check arbitraries from schemas using deriveArbitrary:

import * as fc from 'fast-check'
import { deriveArbitrary } from 'schemata-ts/Arbitrary'

const personArbitrary = deriveArbitrary(PersonSchema).arbitrary(fc)

Arbitrary Documentation

And more

Schemata has other derivations besides the ones above, below are links to those places in the documentation.

Contributors ✨

All Contributors

Thanks goes to these wonderful people (emoji key):

This project follows the all-contributors specification. Contributions of any kind welcome!