Skip to content

Releases: badrap/valita

v0.1.7

10 Nov 15:46
Compare
Choose a tag to compare
  • Fix cases where a lazy(...) call references const variables that are defined later.

v0.1.6

04 Aug 13:48
Compare
Choose a tag to compare
  • Optimize code by doing less defineProperty shenanigans.
  • Add tests for basic primitives (null(), undefined(), ...).

v0.1.5

02 Jun 10:46
Compare
Choose a tag to compare
  • Fix: Allow type checking to work with native Node16 Typescript ESM (#27, thanks @rslabbert!)

v0.1.4

30 May 21:42
Compare
Choose a tag to compare
  • Rewrite parts of the internal bookkeeping for v.object(...), hopefully clarifying it a bit. For details take a look at the relevant code.

v0.1.3

06 May 19:17
Compare
Choose a tag to compare

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

v0.1.2

06 May 14:57
8c44190
Compare
Choose a tag to compare

v0.1.1

26 Jan 19:03
Compare
Choose a tag to compare
  • 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.

v0.1.0

30 Nov 00:59
Compare
Choose a tag to compare
v0.1.0

v0.0.26

26 Nov 04:28
Compare
Choose a tag to compare
  • v.record() is equal to v.record(v.unknown())

v0.0.25

11 Nov 15:32
Compare
Choose a tag to compare
v0.0.25