0.12.2 • Published 4 months ago

@decs/typeschema v0.12.2

Weekly downloads
-
License
MIT
Repository
github
Last release
4 months 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

4 months ago

0.12.1

7 months ago

0.12.0

8 months ago

0.11.7

8 months ago

0.11.5

8 months ago

0.11.3

8 months ago

0.11.2

8 months ago

0.11.0

8 months ago

0.10.2

9 months ago

0.10.1

9 months ago

0.10.0

9 months ago

0.9.3

9 months ago

0.9.1

9 months ago

0.9.0

9 months ago

0.8.3

9 months ago

0.8.2

10 months ago

0.8.1

10 months ago

0.8.0

10 months ago

0.7.4

10 months ago

0.7.3

10 months ago

0.7.2

10 months ago

0.7.1

10 months ago

0.7.0

10 months ago

0.6.4

10 months ago

0.6.3

10 months ago

0.6.2

10 months ago

0.6.1

10 months ago

0.6.0

10 months ago

0.5.2

10 months ago

0.5.1

10 months ago

0.5.0

10 months ago

0.4.0

10 months ago

0.3.3

10 months ago

0.3.2

10 months ago

0.3.1

10 months ago

0.3.0

10 months ago

0.2.1

11 months ago

0.2.0

11 months ago

0.1.3

11 months ago

0.1.2

11 months ago

0.1.1

11 months ago

0.1.0

11 months ago