valita

A typesafe validation & parsing library for TypeScript.

MIT License

Downloads
52.4K
Stars
349
Committers
8

Bot releases are visible (Hide)

valita -

Published by jviide almost 2 years ago

  • Restore exported types that were accidentally omitted from v0.1.8
valita -

Published by jviide almost 2 years ago

  • Fix type errors when the importer's tsconfig.json has "declaration": true.
valita -

Published by jviide almost 2 years ago

  • Fix cases where a lazy(...) call references const variables that are defined later.
valita - v0.1.6

Published by jviide about 2 years ago

  • Optimize code by doing less defineProperty shenanigans.
  • Add tests for basic primitives (null(), undefined(), ...).
valita -

Published by jviide over 2 years ago

  • Fix: Allow type checking to work with native Node16 Typescript ESM (#27, thanks @rslabbert!)
valita -

Published by jviide over 2 years ago

  • Rewrite parts of the internal bookkeeping for v.object(...), hopefully clarifying it a bit. For details take a look at the relevant code.
valita - v0.1.3

Published by jviide over 2 years ago

This release modifies how object() and record() handle input that contains a property called __proto__.

As it happens, __proto__ is a bit special in JavaScript, as it allows the [[Prototype]] of an object to be mutated:

let obj = {}
obj.__proto__ = { a: 1 }
obj.a === 1 // true

Interestingly, JSON.parse doesn't set the prototype based on __proto__:

let input = JSON.parse('{ "__proto__": { "a": 1 } }')
input.a === 1 // false
input.__proto__.a === 1 // true

// cloning with e.g. Object.assign sets the prototype, though
Object.assign({}, input).a === 1 // true

JSON.parse is often used to parse input in HTTP servers. So, as Valita was built for validating & parsing arbitrary input data, it may encounter data that contains the __proto__ property. Some weird effects could be observed when Valita versions v0.1.2 and earlier encountered such input and needed to clone the input object:

import * as v from "@badrap/valita"
let t = v.object({ a: v.string().optional() }).rest(v.unknown().map((x) => x))
let o = t.parse(JSON.parse('{ "__proto__": { "a": 1 } }'))

// __proto__ is defined in the output...
o.__proto__.a === 1 // true

// ...but o.a shouldn't be, yet it is
o.a === 1 // true

This is now mitigated in Valita v0.1.3:

import * as v from "@badrap/valita"
let t = v.object({ a: v.string().optional() }).rest(v.unknown().map((x) => x))
let o = t.parse(JSON.parse('{ "__proto__": { "a": 1 } }'))

// __proto__ is still defined in the output...
o.__proto__.a === 1 // true

// ...and o.a isn't
o.a === undefined // true

Notes

valita - v0.1.2

Published by jviide over 2 years ago

valita - v0.1.1

Published by jviide over 2 years ago

  • Fast path v.record(v.unknown()) and v.object({ ... }).rest(v.unknown()).
  • Fix schemas like v.object({ a: v.string().optional() }).parse({}) failing when it shouldn't.
valita -

Published by jviide almost 3 years ago

valita -

Published by jviide almost 3 years ago

  • v.record() is equal to v.record(v.unknown())
valita -

Published by jviide almost 3 years ago

valita -

Published by jviide almost 3 years ago

  • Missing value errors from objects are now all collected:

    const t = v.object({ a: v.string(), b: v.string() });
    t.parse({});
    // ValitaError: missing_value at .b (missing value) (+ 1 other issue)
    
  • When in strict mode (which is the default) all unrecognized keys in an object are collected into one error:

    const t = v.object({});
    t.parse({ x: 1, y: 2 });
    // ValitaError: unrecognized_keys at . (unrecognized keys "x" and "y")
    
valita -

Published by jviide almost 3 years ago

valita -

Published by jviide almost 3 years ago

  • Fix lazy() throwing "Maximum call stack size exceeded" errors (#22)
valita - v0.0.21: Strictly Come Dancing

Published by jviide almost 3 years ago

  • Breaking change: The default parsing mode is now "strict". This means that extra keys for parsed objects cause the parsing to fail by default. For example this now fails:

    import * as v from "@badrap/valita";
    
    const t = v.object({ a: v.number() });
    
    t.parse({ "a": 1, "b": 2 });
    // Uncaught ValitaError: unrecognized_key at . (unrecognized key "b")
    

    You can go back to the default parsing mode ("passthrough") by giving the mode to .parse(...) (or .try(...)). This will not fail, even with the extra key "b" present:

    t.parse({ "a": 1, "b": 2 }, { mode: "passthrough" });
    

    You can also opt-in to allowing extra keys case-by-case basis by using .rest(...):

    const t = v.object({ a: v.number() }).rest(v.unknown());
    
    t.parse({ "a": 1, "b": 2 });
    // Succeeds, and the output type is { [x: string]: unknown; a: number; }
    
  • Docs galore: Huge thanks to @marvinhagemeister for documenting most of the API 🎉 (#20)

valita -

Published by jviide about 3 years ago

Up transpilation target to es2015 (#18, thanks @marvinhagemeister!)

valita -

Published by jviide about 3 years ago

valita -

Published by jviide about 3 years ago

valita -

Published by jviide over 3 years ago

  • Add v.object(...).pick("a", "b").
  • Add v.object(...).omit("a", "b").
  • Add v.object(...).partial().