0.12.2 • Published 1 year ago

@decs/typeschema v0.12.2

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

Many libraries rely on some sort of type validation. Their maintainers have the choice of either to:

  1. Implement their own validation logic: which leads to more code to maintain, and we already have many good solutions out there (e.g. zod, arktype, typia)
  2. Couple their code with a specific validation library: which limits adoption by developers who use another
  3. Support multiple validation libraries: which is a burden to keep up-to-date (e.g. tRPC)

There's no best validation library because there's always a tradeoff. Each developer chooses the library that makes the most sense to them. TypeSchema solves this problem by easily providing option 3: support multiple validation libraries out-of-the-box.

Features

  • 🚀 Decouple from schema validation libraries
  • 🍃 Tiny client footprint, tree-shakeable
  • 🛋️ Easy-to-use, minimal API

Usage

import type {Infer, InferIn, Schema} from '@decs/typeschema';
import {assert, validate, wrap} from '@decs/typeschema';

// Use your favorite validation library, e.g. `zod`, `arktype`, `typia`
const schema: Schema = z.string();
const schema: Schema = type('string');
const schema: Schema = typia.createAssert<string>();

// Extracts the schema type
type Output = Infer<typeof schema>; // `string`
type Input = InferIn<typeof schema>; // `string`

// Returns the wrapped schema with access to all its operations
const wrapped = wrap(schema);
await wrapped.validate('123'); // {success: true, data: '123'}
await wrapped.assert('123'); // '123'

// Returns the validated data or a list of `ValidationIssue`s
await validate(schema, '123'); // {success: true, data: '123'}
await validate(schema, 123); // {success: false, issues: [`ValidationIssue`]}

// Returns the validated data or throws an `AggregateError`
await assert(schema, '123'); // '123'
await assert(schema, 123); // throws `AggregateError`

tRPC

You can use any supported schema on tRPC through the wrap function:

import {wrap} from '@decs/typeschema';
import {initTRPC} from '@trpc/server';
import {object, string} from 'valibot';

// Use your favorite validation library, e.g. `valibot`
const schema = object({name: string()});

const t = initTRPC.create();
const appRouter = t.router({
  hello: t.procedure
    .input(wrap(schema)) // like this
    .query(({input}) => `Hello, ${input.name}!`),
});

Coverage

TypeSchema supports all major schema validation libraries:

ProjectPopularitywrapvalidateassertInferInferInExample schema
zodz.string()
yupstring()
joiJoi.string()
ajv{type: "string"}
superstructstring()
io-tst.string
valibotstring()
typeboxType.String()
typiatypia.createAssert<string>()
ow^1ow.string
effectS.string
arktypetype('string')
deepkittypeOf<string>()
runtypesString

^1: For ow, only v0.28.2 is supported (sindresorhus/ow#248)

Custom validations are also supported:

export function assertString(data: unknown): string {
  if (typeof data !== 'string') {
    throw new Error('Expected a string, got: ' + data);
  }
  return data;
}

await validate(assertString, '123'); // {success: true, data: '123'}
await validate(assertString, 123); // {success: false, issues: [`ValidationIssue`]}

await assert(assertString, '123'); // '123'
await assert(assertString, 123); // throws `AggregateError`

Setup

Install TypeSchema with your package manager of choice:

API

Types

  • Schema

    Generic interface for schemasAn union of the schema types of all supported libraries

  • TypeSchema<TOutput, TInput = TOutput>

    Interface for a wrapped schema, exposing all its operations

  • Infer<TSchema extends Schema>

    Extracts the output type of a schema

  • InferIn<TSchema extends Schema>

    Extracts the input type of a schema

  • ValidationIssue

    Generic interface for validation issuesIncludes a message and an optional path

Functions

  • wrap(schema)

    wrap<TSchema extends Schema>(
      schema: TSchema,
    ): TypeSchema<Infer<TSchema>, InferIn<TSchema>>

    Returns the wrapped schema with access to all its operations

  • validate(schema, data)

    validate<TSchema extends Schema>(
      schema: TSchema,
      data: unknown,
    ): Promise<ValidationResult<Infer<TSchema>>>

    Returns the validated data or a list of ValidationIssues

  • assert(schema, data)

    assert<TSchema extends Schema>(
      schema: TSchema,
      data: unknown,
    ): Promise<Infer<TSchema>>

    Returns the validated data or throws an AggregateError

Acknowledgements

0.12.2

1 year ago

0.12.1

2 years ago

0.12.0

2 years ago

0.11.7

2 years ago

0.11.5

2 years ago

0.11.3

2 years ago

0.11.2

2 years ago

0.11.0

2 years ago

0.10.2

2 years ago

0.10.1

2 years ago

0.10.0

2 years ago

0.9.3

2 years ago

0.9.1

2 years ago

0.9.0

2 years ago

0.8.3

2 years ago

0.8.2

2 years ago

0.8.1

2 years ago

0.8.0

2 years ago

0.7.4

2 years ago

0.7.3

2 years ago

0.7.2

2 years ago

0.7.1

2 years ago

0.7.0

2 years ago

0.6.4

2 years ago

0.6.3

2 years ago

0.6.2

2 years ago

0.6.1

2 years ago

0.6.0

2 years ago

0.5.2

2 years ago

0.5.1

2 years ago

0.5.0

2 years ago

0.4.0

2 years ago

0.3.3

2 years ago

0.3.2

2 years ago

0.3.1

2 years ago

0.3.0

2 years ago

0.2.1

2 years ago

0.2.0

2 years ago

0.1.3

2 years ago

0.1.2

2 years ago

0.1.1

2 years ago

0.1.0

2 years ago