Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@badrap/valita

Package Overview
Dependencies
Maintainers
2
Versions
64
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@badrap/valita - npm Package Compare versions

Comparing version 0.3.5 to 0.3.6

76

dist/cjs/index.d.ts

@@ -135,2 +135,5 @@ /**

readonly ok: true;
/**
* The successfully parsed value.
*/
readonly value: T;

@@ -146,4 +149,13 @@ };

readonly ok: false;
/**
* A condensed overview of the parsing issues.
*/
readonly message: string;
/**
* A detailed list of the parsing issues.
*/
readonly issues: readonly Issue[];
readonly message: string;
/**
* Throw a new ValitaError representing the parsing issues.
*/
throw(): never;

@@ -206,7 +218,2 @@ };

type RawResult<T> = undefined | Ok<T> | IssueTree;
declare const enum FuncMode {
PASS = 0,
STRICT = 1,
STRIP = 2
}
/**

@@ -224,18 +231,18 @@ * Return the inferred output type of a validator.

export type Infer<T extends AbstractType> = T extends AbstractType<infer I> ? I : never;
type ParseOptions = {
mode?: "passthrough" | "strict" | "strip";
};
declare abstract class AbstractType<Output = unknown> {
abstract readonly name: string;
abstract toTerminals(func: (t: TerminalType) => void): void;
abstract func(v: unknown, mode: FuncMode): RawResult<Output>;
abstract func(v: unknown, flags: number): RawResult<Output>;
optional(): Optional<Output>;
default<T extends Literal>(defaultValue: T): Type<Exclude<Output, undefined> | T>;
default<T>(defaultValue: T): Type<Exclude<Output, undefined> | T>;
assert<T extends Output>(func: ((v: Output) => v is T) | ((v: Output) => boolean), error?: CustomError): Type<T>;
map<T extends Literal>(func: (v: Output) => T): Type<T>;
map<T>(func: (v: Output) => T): Type<T>;
chain<T extends Literal>(func: (v: Output) => ValitaResult<T>): Type<T>;
chain<T>(func: (v: Output) => ValitaResult<T>): Type<T>;
assert<T extends Output>(func: ((v: Output, options: ParseOptions) => v is T) | ((v: Output, options: ParseOptions) => boolean), error?: CustomError): Type<T>;
map<T extends Literal>(func: (v: Output, options: ParseOptions) => T): Type<T>;
map<T>(func: (v: Output, options: ParseOptions) => T): Type<T>;
chain<T extends Literal>(func: (v: Output, options: ParseOptions) => ValitaResult<T>): Type<T>;
chain<T>(func: (v: Output, options: ParseOptions) => ValitaResult<T>): Type<T>;
}
type ParseOptions = {
mode: "passthrough" | "strict" | "strip";
};
/**

@@ -245,6 +252,15 @@ * A base class for all concreate validators/parsers.

declare abstract class Type<Output = unknown> extends AbstractType<Output> {
/**
* Return new validator that accepts both the original type and `null`.
*/
nullable(): Type<null | Output>;
toTerminals(func: (t: TerminalType) => void): void;
try(v: unknown, options?: Partial<ParseOptions>): ValitaResult<Infer<this>>;
parse(v: unknown, options?: Partial<ParseOptions>): Infer<this>;
/**
* Parse a value without throwing.
*/
try(v: unknown, options?: ParseOptions): ValitaResult<Infer<this>>;
/**
* Parse a value. Throw a ValitaError on failure.
*/
parse(v: unknown, options?: ParseOptions): Infer<this>;
}

@@ -262,3 +278,3 @@ /**

constructor(type: AbstractType<Output>);
func(v: unknown, mode: FuncMode): RawResult<Output | undefined>;
func(v: unknown, flags: number): RawResult<Output | undefined>;
toTerminals(func: (t: TerminalType) => void): void;

@@ -288,3 +304,3 @@ optional(): Optional<Output>;

check(func: (v: ObjectOutput<Shape, Rest>) => boolean, error?: CustomError): ObjectType<Shape, Rest>;
func(v: unknown, mode: FuncMode): RawResult<ObjectOutput<Shape, Rest>>;
func(v: unknown, flags: number): RawResult<ObjectOutput<Shape, Rest>>;
rest<R extends Type>(restType: R): ObjectType<Shape, R>;

@@ -314,3 +330,3 @@ extend<S extends ObjectShape>(shape: S): ObjectType<Omit<Shape, keyof S> & S, Rest>;

constructor(head: Head, rest?: Rest);
func(arr: unknown, mode: FuncMode): RawResult<ArrayOutput<Head, Rest>>;
func(arr: unknown, flags: number): RawResult<ArrayOutput<Head, Rest>>;
}

@@ -323,3 +339,3 @@ declare class UnionType<T extends Type[] = Type[]> extends Type<Infer<T[number]>> {

toTerminals(func: (t: TerminalType) => void): void;
func(v: unknown, mode: FuncMode): RawResult<Infer<T[number]>>;
func(v: unknown, flags: number): RawResult<Infer<T[number]>>;
}

@@ -329,3 +345,3 @@ declare class NeverType extends Type<never> {

private readonly issue;
func(_: unknown, __: FuncMode): RawResult<never>;
func(_: unknown, __: number): RawResult<never>;
}

@@ -339,3 +355,3 @@ /**

readonly name = "unknown";
func(_: unknown, __: FuncMode): RawResult<unknown>;
func(_: unknown, __: number): RawResult<unknown>;
}

@@ -350,3 +366,3 @@ /**

private readonly issue;
func(v: unknown, _: FuncMode): RawResult<undefined>;
func(v: unknown, _: number): RawResult<undefined>;
}

@@ -360,3 +376,3 @@ /**

private readonly issue;
func(v: unknown, _: FuncMode): RawResult<null>;
func(v: unknown, _: number): RawResult<null>;
}

@@ -370,3 +386,3 @@ /**

private readonly issue;
func(v: unknown, _: FuncMode): RawResult<number>;
func(v: unknown, _: number): RawResult<number>;
}

@@ -380,3 +396,3 @@ /**

private readonly issue;
func(v: unknown, _: FuncMode): RawResult<bigint>;
func(v: unknown, _: number): RawResult<bigint>;
}

@@ -390,3 +406,3 @@ /**

private readonly issue;
func(v: unknown, _: FuncMode): RawResult<string>;
func(v: unknown, _: number): RawResult<string>;
}

@@ -400,3 +416,3 @@ /**

private readonly issue;
func(v: unknown, _: FuncMode): RawResult<boolean>;
func(v: unknown, _: number): RawResult<boolean>;
}

@@ -412,3 +428,3 @@ /**

constructor(value: Out);
func(v: unknown, _: FuncMode): RawResult<Out>;
func(v: unknown, _: number): RawResult<Out>;
}

@@ -415,0 +431,0 @@ /**

@@ -261,3 +261,5 @@ "use strict";

}
const Nothing = Symbol.for("valita.Nothing");
const FLAG_FORBID_EXTRA_KEYS = 0x1;
const FLAG_STRIP_EXTRA_KEYS = 0x2;
const FLAG_MISSING_VALUE = 0x4;
class AbstractType {

@@ -275,13 +277,13 @@ optional() {

const err = { ok: false, code: "custom_error", error };
return new TransformType(this, (v) => func(v) ? undefined : err);
return new TransformType(this, (v, options) => func(v, options) ? undefined : err);
}
map(func) {
return new TransformType(this, (v) => ({
return new TransformType(this, (v, options) => ({
ok: true,
value: func(v),
value: func(v, options),
}));
}
chain(func) {
return new TransformType(this, (v) => {
const r = func(v);
return new TransformType(this, (v, options) => {
const r = func(v, options);
return r.ok ? r : r.issueTree;

@@ -295,4 +297,7 @@ });

class Type extends AbstractType {
/**
* Return new validator that accepts both the original type and `null`.
*/
nullable() {
return union(nullSingleton, this);
return new Nullable(this);
}

@@ -302,13 +307,14 @@ toTerminals(func) {

}
/**
* Parse a value without throwing.
*/
try(v, options) {
let mode = 1 /* FuncMode.STRICT */;
if (options !== undefined) {
if (options.mode === "passthrough") {
mode = 0 /* FuncMode.PASS */;
}
else if (options.mode === "strip") {
mode = 2 /* FuncMode.STRIP */;
}
let flags = FLAG_FORBID_EXTRA_KEYS;
if ((options === null || options === void 0 ? void 0 : options.mode) === "passthrough") {
flags = 0;
}
const r = this.func(v, mode);
else if ((options === null || options === void 0 ? void 0 : options.mode) === "strip") {
flags = FLAG_STRIP_EXTRA_KEYS;
}
const r = this.func(v, flags);
if (r === undefined) {

@@ -324,13 +330,14 @@ return { ok: true, value: v };

}
/**
* Parse a value. Throw a ValitaError on failure.
*/
parse(v, options) {
let mode = 1 /* FuncMode.STRICT */;
if (options !== undefined) {
if (options.mode === "passthrough") {
mode = 0 /* FuncMode.PASS */;
}
else if (options.mode === "strip") {
mode = 2 /* FuncMode.STRIP */;
}
let flags = FLAG_FORBID_EXTRA_KEYS;
if ((options === null || options === void 0 ? void 0 : options.mode) === "passthrough") {
flags = 0;
}
const r = this.func(v, mode);
else if ((options === null || options === void 0 ? void 0 : options.mode) === "strip") {
flags = FLAG_STRIP_EXTRA_KEYS;
}
const r = this.func(v, flags);
if (r === undefined) {

@@ -347,2 +354,19 @@ return v;

}
class Nullable extends Type {
constructor(type) {
super();
this.type = type;
this.name = "nullable";
}
func(v, flags) {
return v === null ? undefined : this.type.func(v, flags);
}
toTerminals(func) {
func(nullSingleton);
this.type.toTerminals(func);
}
nullable() {
return this;
}
}
/**

@@ -361,6 +385,6 @@ * A validator/parser marked as "optional", signifying that their value can

}
func(v, mode) {
return v === undefined || v === Nothing
func(v, flags) {
return v === undefined || flags & FLAG_MISSING_VALUE
? undefined
: this.type.func(v, mode);
: this.type.func(v, flags);
}

@@ -422,3 +446,3 @@ toTerminals(func) {

}
func(v, mode) {
func(v, flags) {
let func = this._func;

@@ -429,3 +453,3 @@ if (func === undefined) {

}
return func(v, mode);
return func(v, flags);
}

@@ -523,3 +547,3 @@ rest(restType) {

}
return function (obj, mode) {
return function (obj, flags) {
if (!isObject(obj)) {

@@ -534,3 +558,5 @@ return invalidType;

let seenCount = 0;
if (mode !== 0 /* FuncMode.PASS */ || rest !== undefined) {
if (flags & FLAG_FORBID_EXTRA_KEYS ||
flags & FLAG_STRIP_EXTRA_KEYS ||
rest !== undefined) {
for (const key in obj) {

@@ -543,9 +569,9 @@ const value = obj[key];

seenBits = setBit(seenBits, index);
r = types[index].func(value, mode);
r = types[index].func(value, flags);
}
else if (rest !== undefined) {
r = rest.func(value, mode);
r = rest.func(value, flags);
}
else {
if (mode === 1 /* FuncMode.STRICT */) {
if (flags & FLAG_FORBID_EXTRA_KEYS) {
if (unrecognized === undefined) {

@@ -558,3 +584,3 @@ unrecognized = [key];

}
else if (mode === 2 /* FuncMode.STRIP */ &&
else if (flags & FLAG_STRIP_EXTRA_KEYS &&
issues === undefined &&

@@ -609,3 +635,4 @@ !copied) {

const key = keys[i];
let value = obj[key];
const value = obj[key];
let keyFlags = flags & ~FLAG_MISSING_VALUE;
if (value === undefined && !(key in obj)) {

@@ -616,7 +643,9 @@ if (i < requiredCount) {

}
value = Nothing;
keyFlags |= FLAG_MISSING_VALUE;
}
const r = types[i].func(value, mode);
const r = types[i].func(value, keyFlags);
if (r === undefined) {
if (copied && issues === undefined && value !== Nothing) {
if (copied &&
issues === undefined &&
!(keyFlags & FLAG_MISSING_VALUE)) {
set(output, key, value);

@@ -698,3 +727,3 @@ }

}
func(arr, mode) {
func(arr, flags) {
if (!Array.isArray(arr)) {

@@ -713,3 +742,3 @@ return this.invalidType;

const type = i < minLength ? this.head[i] : this.rest;
const r = type.func(arr[i], mode);
const r = type.func(arr[i], flags);
if (r !== undefined) {

@@ -863,3 +892,3 @@ if (r.ok) {

}
return function (_obj, mode) {
return function (_obj, flags) {
var _a;

@@ -869,6 +898,8 @@ const obj = _obj;

if (value === undefined && !(key in obj)) {
return optionals.length > 0 ? optionals[0].func(obj, mode) : missingValue;
return optionals.length > 0
? optionals[0].func(obj, flags)
: missingValue;
}
const option = (_a = byType === null || byType === void 0 ? void 0 : byType[toInputType(value)]) !== null && _a !== void 0 ? _a : litMap === null || litMap === void 0 ? void 0 : litMap.get(value);
return option ? option.func(obj, mode) : issue;
return option ? option.func(obj, flags) : issue;
};

@@ -913,6 +944,6 @@ }

}
return function (value, mode) {
return function (value, flags) {
var _a, _b;
let options;
if (value === Nothing) {
if (flags & FLAG_MISSING_VALUE) {
options = optionals;

@@ -929,3 +960,3 @@ }

for (let i = 0; i < options.length; i++) {
const r = options[i].func(value, mode);
const r = options[i].func(value, flags);
if (r === undefined || r.ok) {

@@ -952,3 +983,3 @@ return r;

}
func(v, mode) {
func(v, flags) {
let func = this._func;

@@ -966,7 +997,7 @@ if (func === undefined) {

else {
func = function (v, mode) {
func = function (v, f) {
if (isObject(v)) {
return object(v, mode);
return object(v, f);
}
return base(v, mode);
return base(v, f);
};

@@ -976,5 +1007,8 @@ }

}
return func(v, mode);
return func(v, flags);
}
}
const STRICT = Object.freeze({ mode: "strict" });
const STRIP = Object.freeze({ mode: "strip" });
const PASSTHROUGH = Object.freeze({ mode: "passthrough" });
class TransformType extends Type {

@@ -990,3 +1024,3 @@ constructor(transformed, transform) {

}
func(v, mode) {
func(v, flags) {
let chain = this.transformChain;

@@ -1006,3 +1040,3 @@ if (!chain) {

// eslint-disable-next-line
let result = this.transformRoot.func(v, mode);
let result = this.transformRoot.func(v, flags);
if (result !== undefined && !result.ok) {

@@ -1015,3 +1049,3 @@ return result;

}
else if (v === Nothing) {
else if (flags & FLAG_MISSING_VALUE) {
current = undefined;

@@ -1023,4 +1057,9 @@ result = this.undef;

}
const options = flags & FLAG_FORBID_EXTRA_KEYS
? STRICT
: flags & FLAG_STRIP_EXTRA_KEYS
? STRIP
: PASSTHROUGH;
for (let i = 0; i < chain.length; i++) {
const r = chain[i](current, mode);
const r = chain[i](current, options);
if (r !== undefined) {

@@ -1047,7 +1086,7 @@ if (!r.ok) {

}
func(v, mode) {
func(v, flags) {
if (!this.type) {
this.type = this.definer();
}
return this.type.func(v, mode);
return this.type.func(v, flags);
}

@@ -1054,0 +1093,0 @@ toTerminals(func) {

@@ -135,2 +135,5 @@ /**

readonly ok: true;
/**
* The successfully parsed value.
*/
readonly value: T;

@@ -146,4 +149,13 @@ };

readonly ok: false;
/**
* A condensed overview of the parsing issues.
*/
readonly message: string;
/**
* A detailed list of the parsing issues.
*/
readonly issues: readonly Issue[];
readonly message: string;
/**
* Throw a new ValitaError representing the parsing issues.
*/
throw(): never;

@@ -206,7 +218,2 @@ };

type RawResult<T> = undefined | Ok<T> | IssueTree;
declare const enum FuncMode {
PASS = 0,
STRICT = 1,
STRIP = 2
}
/**

@@ -224,18 +231,18 @@ * Return the inferred output type of a validator.

export type Infer<T extends AbstractType> = T extends AbstractType<infer I> ? I : never;
type ParseOptions = {
mode?: "passthrough" | "strict" | "strip";
};
declare abstract class AbstractType<Output = unknown> {
abstract readonly name: string;
abstract toTerminals(func: (t: TerminalType) => void): void;
abstract func(v: unknown, mode: FuncMode): RawResult<Output>;
abstract func(v: unknown, flags: number): RawResult<Output>;
optional(): Optional<Output>;
default<T extends Literal>(defaultValue: T): Type<Exclude<Output, undefined> | T>;
default<T>(defaultValue: T): Type<Exclude<Output, undefined> | T>;
assert<T extends Output>(func: ((v: Output) => v is T) | ((v: Output) => boolean), error?: CustomError): Type<T>;
map<T extends Literal>(func: (v: Output) => T): Type<T>;
map<T>(func: (v: Output) => T): Type<T>;
chain<T extends Literal>(func: (v: Output) => ValitaResult<T>): Type<T>;
chain<T>(func: (v: Output) => ValitaResult<T>): Type<T>;
assert<T extends Output>(func: ((v: Output, options: ParseOptions) => v is T) | ((v: Output, options: ParseOptions) => boolean), error?: CustomError): Type<T>;
map<T extends Literal>(func: (v: Output, options: ParseOptions) => T): Type<T>;
map<T>(func: (v: Output, options: ParseOptions) => T): Type<T>;
chain<T extends Literal>(func: (v: Output, options: ParseOptions) => ValitaResult<T>): Type<T>;
chain<T>(func: (v: Output, options: ParseOptions) => ValitaResult<T>): Type<T>;
}
type ParseOptions = {
mode: "passthrough" | "strict" | "strip";
};
/**

@@ -245,6 +252,15 @@ * A base class for all concreate validators/parsers.

declare abstract class Type<Output = unknown> extends AbstractType<Output> {
/**
* Return new validator that accepts both the original type and `null`.
*/
nullable(): Type<null | Output>;
toTerminals(func: (t: TerminalType) => void): void;
try(v: unknown, options?: Partial<ParseOptions>): ValitaResult<Infer<this>>;
parse(v: unknown, options?: Partial<ParseOptions>): Infer<this>;
/**
* Parse a value without throwing.
*/
try(v: unknown, options?: ParseOptions): ValitaResult<Infer<this>>;
/**
* Parse a value. Throw a ValitaError on failure.
*/
parse(v: unknown, options?: ParseOptions): Infer<this>;
}

@@ -262,3 +278,3 @@ /**

constructor(type: AbstractType<Output>);
func(v: unknown, mode: FuncMode): RawResult<Output | undefined>;
func(v: unknown, flags: number): RawResult<Output | undefined>;
toTerminals(func: (t: TerminalType) => void): void;

@@ -288,3 +304,3 @@ optional(): Optional<Output>;

check(func: (v: ObjectOutput<Shape, Rest>) => boolean, error?: CustomError): ObjectType<Shape, Rest>;
func(v: unknown, mode: FuncMode): RawResult<ObjectOutput<Shape, Rest>>;
func(v: unknown, flags: number): RawResult<ObjectOutput<Shape, Rest>>;
rest<R extends Type>(restType: R): ObjectType<Shape, R>;

@@ -314,3 +330,3 @@ extend<S extends ObjectShape>(shape: S): ObjectType<Omit<Shape, keyof S> & S, Rest>;

constructor(head: Head, rest?: Rest);
func(arr: unknown, mode: FuncMode): RawResult<ArrayOutput<Head, Rest>>;
func(arr: unknown, flags: number): RawResult<ArrayOutput<Head, Rest>>;
}

@@ -323,3 +339,3 @@ declare class UnionType<T extends Type[] = Type[]> extends Type<Infer<T[number]>> {

toTerminals(func: (t: TerminalType) => void): void;
func(v: unknown, mode: FuncMode): RawResult<Infer<T[number]>>;
func(v: unknown, flags: number): RawResult<Infer<T[number]>>;
}

@@ -329,3 +345,3 @@ declare class NeverType extends Type<never> {

private readonly issue;
func(_: unknown, __: FuncMode): RawResult<never>;
func(_: unknown, __: number): RawResult<never>;
}

@@ -339,3 +355,3 @@ /**

readonly name = "unknown";
func(_: unknown, __: FuncMode): RawResult<unknown>;
func(_: unknown, __: number): RawResult<unknown>;
}

@@ -350,3 +366,3 @@ /**

private readonly issue;
func(v: unknown, _: FuncMode): RawResult<undefined>;
func(v: unknown, _: number): RawResult<undefined>;
}

@@ -360,3 +376,3 @@ /**

private readonly issue;
func(v: unknown, _: FuncMode): RawResult<null>;
func(v: unknown, _: number): RawResult<null>;
}

@@ -370,3 +386,3 @@ /**

private readonly issue;
func(v: unknown, _: FuncMode): RawResult<number>;
func(v: unknown, _: number): RawResult<number>;
}

@@ -380,3 +396,3 @@ /**

private readonly issue;
func(v: unknown, _: FuncMode): RawResult<bigint>;
func(v: unknown, _: number): RawResult<bigint>;
}

@@ -390,3 +406,3 @@ /**

private readonly issue;
func(v: unknown, _: FuncMode): RawResult<string>;
func(v: unknown, _: number): RawResult<string>;
}

@@ -400,3 +416,3 @@ /**

private readonly issue;
func(v: unknown, _: FuncMode): RawResult<boolean>;
func(v: unknown, _: number): RawResult<boolean>;
}

@@ -412,3 +428,3 @@ /**

constructor(value: Out);
func(v: unknown, _: FuncMode): RawResult<Out>;
func(v: unknown, _: number): RawResult<Out>;
}

@@ -415,0 +431,0 @@ /**

@@ -261,3 +261,5 @@ "use strict";

}
const Nothing = Symbol.for("valita.Nothing");
const FLAG_FORBID_EXTRA_KEYS = 0x1;
const FLAG_STRIP_EXTRA_KEYS = 0x2;
const FLAG_MISSING_VALUE = 0x4;
class AbstractType {

@@ -275,13 +277,13 @@ optional() {

const err = { ok: false, code: "custom_error", error };
return new TransformType(this, (v) => func(v) ? undefined : err);
return new TransformType(this, (v, options) => func(v, options) ? undefined : err);
}
map(func) {
return new TransformType(this, (v) => ({
return new TransformType(this, (v, options) => ({
ok: true,
value: func(v),
value: func(v, options),
}));
}
chain(func) {
return new TransformType(this, (v) => {
const r = func(v);
return new TransformType(this, (v, options) => {
const r = func(v, options);
return r.ok ? r : r.issueTree;

@@ -295,4 +297,7 @@ });

class Type extends AbstractType {
/**
* Return new validator that accepts both the original type and `null`.
*/
nullable() {
return union(nullSingleton, this);
return new Nullable(this);
}

@@ -302,13 +307,14 @@ toTerminals(func) {

}
/**
* Parse a value without throwing.
*/
try(v, options) {
let mode = 1 /* FuncMode.STRICT */;
if (options !== undefined) {
if (options.mode === "passthrough") {
mode = 0 /* FuncMode.PASS */;
}
else if (options.mode === "strip") {
mode = 2 /* FuncMode.STRIP */;
}
let flags = FLAG_FORBID_EXTRA_KEYS;
if (options?.mode === "passthrough") {
flags = 0;
}
const r = this.func(v, mode);
else if (options?.mode === "strip") {
flags = FLAG_STRIP_EXTRA_KEYS;
}
const r = this.func(v, flags);
if (r === undefined) {

@@ -324,13 +330,14 @@ return { ok: true, value: v };

}
/**
* Parse a value. Throw a ValitaError on failure.
*/
parse(v, options) {
let mode = 1 /* FuncMode.STRICT */;
if (options !== undefined) {
if (options.mode === "passthrough") {
mode = 0 /* FuncMode.PASS */;
}
else if (options.mode === "strip") {
mode = 2 /* FuncMode.STRIP */;
}
let flags = FLAG_FORBID_EXTRA_KEYS;
if (options?.mode === "passthrough") {
flags = 0;
}
const r = this.func(v, mode);
else if (options?.mode === "strip") {
flags = FLAG_STRIP_EXTRA_KEYS;
}
const r = this.func(v, flags);
if (r === undefined) {

@@ -347,2 +354,19 @@ return v;

}
class Nullable extends Type {
constructor(type) {
super();
this.type = type;
this.name = "nullable";
}
func(v, flags) {
return v === null ? undefined : this.type.func(v, flags);
}
toTerminals(func) {
func(nullSingleton);
this.type.toTerminals(func);
}
nullable() {
return this;
}
}
/**

@@ -361,6 +385,6 @@ * A validator/parser marked as "optional", signifying that their value can

}
func(v, mode) {
return v === undefined || v === Nothing
func(v, flags) {
return v === undefined || flags & FLAG_MISSING_VALUE
? undefined
: this.type.func(v, mode);
: this.type.func(v, flags);
}

@@ -421,3 +445,3 @@ toTerminals(func) {

}
func(v, mode) {
func(v, flags) {
let func = this._func;

@@ -428,3 +452,3 @@ if (func === undefined) {

}
return func(v, mode);
return func(v, flags);
}

@@ -521,3 +545,3 @@ rest(restType) {

}
return function (obj, mode) {
return function (obj, flags) {
if (!isObject(obj)) {

@@ -532,3 +556,5 @@ return invalidType;

let seenCount = 0;
if (mode !== 0 /* FuncMode.PASS */ || rest !== undefined) {
if (flags & FLAG_FORBID_EXTRA_KEYS ||
flags & FLAG_STRIP_EXTRA_KEYS ||
rest !== undefined) {
for (const key in obj) {

@@ -541,9 +567,9 @@ const value = obj[key];

seenBits = setBit(seenBits, index);
r = types[index].func(value, mode);
r = types[index].func(value, flags);
}
else if (rest !== undefined) {
r = rest.func(value, mode);
r = rest.func(value, flags);
}
else {
if (mode === 1 /* FuncMode.STRICT */) {
if (flags & FLAG_FORBID_EXTRA_KEYS) {
if (unrecognized === undefined) {

@@ -556,3 +582,3 @@ unrecognized = [key];

}
else if (mode === 2 /* FuncMode.STRIP */ &&
else if (flags & FLAG_STRIP_EXTRA_KEYS &&
issues === undefined &&

@@ -607,3 +633,4 @@ !copied) {

const key = keys[i];
let value = obj[key];
const value = obj[key];
let keyFlags = flags & ~FLAG_MISSING_VALUE;
if (value === undefined && !(key in obj)) {

@@ -614,7 +641,9 @@ if (i < requiredCount) {

}
value = Nothing;
keyFlags |= FLAG_MISSING_VALUE;
}
const r = types[i].func(value, mode);
const r = types[i].func(value, keyFlags);
if (r === undefined) {
if (copied && issues === undefined && value !== Nothing) {
if (copied &&
issues === undefined &&
!(keyFlags & FLAG_MISSING_VALUE)) {
set(output, key, value);

@@ -696,3 +725,3 @@ }

}
func(arr, mode) {
func(arr, flags) {
if (!Array.isArray(arr)) {

@@ -711,3 +740,3 @@ return this.invalidType;

const type = i < minLength ? this.head[i] : this.rest;
const r = type.func(arr[i], mode);
const r = type.func(arr[i], flags);
if (r !== undefined) {

@@ -859,10 +888,12 @@ if (r.ok) {

}
return function (_obj, mode) {
return function (_obj, flags) {
const obj = _obj;
const value = obj[key];
if (value === undefined && !(key in obj)) {
return optionals.length > 0 ? optionals[0].func(obj, mode) : missingValue;
return optionals.length > 0
? optionals[0].func(obj, flags)
: missingValue;
}
const option = byType?.[toInputType(value)] ?? litMap?.get(value);
return option ? option.func(obj, mode) : issue;
return option ? option.func(obj, flags) : issue;
};

@@ -907,5 +938,5 @@ }

}
return function (value, mode) {
return function (value, flags) {
let options;
if (value === Nothing) {
if (flags & FLAG_MISSING_VALUE) {
options = optionals;

@@ -922,3 +953,3 @@ }

for (let i = 0; i < options.length; i++) {
const r = options[i].func(value, mode);
const r = options[i].func(value, flags);
if (r === undefined || r.ok) {

@@ -945,3 +976,3 @@ return r;

}
func(v, mode) {
func(v, flags) {
let func = this._func;

@@ -959,7 +990,7 @@ if (func === undefined) {

else {
func = function (v, mode) {
func = function (v, f) {
if (isObject(v)) {
return object(v, mode);
return object(v, f);
}
return base(v, mode);
return base(v, f);
};

@@ -969,5 +1000,8 @@ }

}
return func(v, mode);
return func(v, flags);
}
}
const STRICT = Object.freeze({ mode: "strict" });
const STRIP = Object.freeze({ mode: "strip" });
const PASSTHROUGH = Object.freeze({ mode: "passthrough" });
class TransformType extends Type {

@@ -983,3 +1017,3 @@ constructor(transformed, transform) {

}
func(v, mode) {
func(v, flags) {
let chain = this.transformChain;

@@ -999,3 +1033,3 @@ if (!chain) {

// eslint-disable-next-line
let result = this.transformRoot.func(v, mode);
let result = this.transformRoot.func(v, flags);
if (result !== undefined && !result.ok) {

@@ -1008,3 +1042,3 @@ return result;

}
else if (v === Nothing) {
else if (flags & FLAG_MISSING_VALUE) {
current = undefined;

@@ -1016,4 +1050,9 @@ result = this.undef;

}
const options = flags & FLAG_FORBID_EXTRA_KEYS
? STRICT
: flags & FLAG_STRIP_EXTRA_KEYS
? STRIP
: PASSTHROUGH;
for (let i = 0; i < chain.length; i++) {
const r = chain[i](current, mode);
const r = chain[i](current, options);
if (r !== undefined) {

@@ -1040,7 +1079,7 @@ if (!r.ok) {

}
func(v, mode) {
func(v, flags) {
if (!this.type) {
this.type = this.definer();
}
return this.type.func(v, mode);
return this.type.func(v, flags);
}

@@ -1047,0 +1086,0 @@ toTerminals(func) {

{
"name": "@badrap/valita",
"version": "0.3.5",
"version": "0.3.6",
"description": "A validation & parsing library for TypeScript",

@@ -5,0 +5,0 @@ "main": "./dist/cjs/index.js",

@@ -42,4 +42,4 @@ # @badrap/valita [![tests](https://github.com/badrap/valita/workflows/tests/badge.svg)](https://github.com/badrap/valita/actions?query=workflow%3Atests) [![npm](https://img.shields.io/npm/v/@badrap/valita.svg)](https://www.npmjs.com/package/@badrap/valita)

```ts
import * as v from "https://deno.land/x/valita/mod.ts";
```sh
deno add @badrap/valita
```

@@ -46,0 +46,0 @@

@@ -278,2 +278,6 @@ /**

readonly ok: true;
/**
* The successfully parsed value.
*/
readonly value: T;

@@ -290,4 +294,16 @@ };

readonly ok: false;
/**
* A condensed overview of the parsing issues.
*/
readonly message: string;
/**
* A detailed list of the parsing issues.
*/
readonly issues: readonly Issue[];
readonly message: string;
/**
* Throw a new ValitaError representing the parsing issues.
*/
throw(): never;

@@ -393,11 +409,7 @@ };

const Nothing = Symbol.for("valita.Nothing");
const FLAG_FORBID_EXTRA_KEYS = 0x1;
const FLAG_STRIP_EXTRA_KEYS = 0x2;
const FLAG_MISSING_VALUE = 0x4;
type Func<T> = (v: unknown, flags: number) => RawResult<T>;
const enum FuncMode {
PASS = 0,
STRICT = 1,
STRIP = 2,
}
type Func<T> = (v: unknown, mode: FuncMode) => RawResult<T>;
/**

@@ -417,6 +429,10 @@ * Return the inferred output type of a validator.

type ParseOptions = {
mode?: "passthrough" | "strict" | "strip";
};
abstract class AbstractType<Output = unknown> {
abstract readonly name: string;
abstract toTerminals(func: (t: TerminalType) => void): void;
abstract func(v: unknown, mode: FuncMode): RawResult<Output>;
abstract func(v: unknown, flags: number): RawResult<Output>;

@@ -439,25 +455,35 @@ optional(): Optional<Output> {

assert<T extends Output>(
func: ((v: Output) => v is T) | ((v: Output) => boolean),
func:
| ((v: Output, options: ParseOptions) => v is T)
| ((v: Output, options: ParseOptions) => boolean),
error?: CustomError,
): Type<T> {
const err: IssueLeaf = { ok: false, code: "custom_error", error };
return new TransformType(this, (v) =>
func(v as Output) ? undefined : err,
return new TransformType(this, (v, options) =>
func(v as Output, options) ? undefined : err,
);
}
map<T extends Literal>(func: (v: Output) => T): Type<T>;
map<T>(func: (v: Output) => T): Type<T>;
map<T>(func: (v: Output) => T): Type<T> {
return new TransformType(this, (v) => ({
map<T extends Literal>(
func: (v: Output, options: ParseOptions) => T,
): Type<T>;
map<T>(func: (v: Output, options: ParseOptions) => T): Type<T>;
map<T>(func: (v: Output, options: ParseOptions) => T): Type<T> {
return new TransformType(this, (v, options) => ({
ok: true,
value: func(v as Output),
value: func(v as Output, options),
}));
}
chain<T extends Literal>(func: (v: Output) => ValitaResult<T>): Type<T>;
chain<T>(func: (v: Output) => ValitaResult<T>): Type<T>;
chain<T>(func: (v: Output) => ValitaResult<T>): Type<T> {
return new TransformType(this, (v) => {
const r = func(v as Output);
chain<T extends Literal>(
func: (v: Output, options: ParseOptions) => ValitaResult<T>,
): Type<T>;
chain<T>(
func: (v: Output, options: ParseOptions) => ValitaResult<T>,
): Type<T>;
chain<T>(
func: (v: Output, options: ParseOptions) => ValitaResult<T>,
): Type<T> {
return new TransformType(this, (v, options) => {
const r = func(v as Output, options);
return r.ok ? r : (r as unknown as { issueTree: IssueTree }).issueTree;

@@ -468,6 +494,2 @@ });

type ParseOptions = {
mode: "passthrough" | "strict" | "strip";
};
/**

@@ -477,4 +499,7 @@ * A base class for all concreate validators/parsers.

abstract class Type<Output = unknown> extends AbstractType<Output> {
/**
* Return new validator that accepts both the original type and `null`.
*/
nullable(): Type<null | Output> {
return union(nullSingleton, this);
return new Nullable(this);
}

@@ -486,13 +511,14 @@

try(v: unknown, options?: Partial<ParseOptions>): ValitaResult<Infer<this>> {
let mode: FuncMode = FuncMode.STRICT;
if (options !== undefined) {
if (options.mode === "passthrough") {
mode = FuncMode.PASS;
} else if (options.mode === "strip") {
mode = FuncMode.STRIP;
}
/**
* Parse a value without throwing.
*/
try(v: unknown, options?: ParseOptions): ValitaResult<Infer<this>> {
let flags = FLAG_FORBID_EXTRA_KEYS;
if (options?.mode === "passthrough") {
flags = 0;
} else if (options?.mode === "strip") {
flags = FLAG_STRIP_EXTRA_KEYS;
}
const r = this.func(v, mode);
const r = this.func(v, flags);
if (r === undefined) {

@@ -507,13 +533,14 @@ return { ok: true, value: v as Infer<this> };

parse(v: unknown, options?: Partial<ParseOptions>): Infer<this> {
let mode: FuncMode = FuncMode.STRICT;
if (options !== undefined) {
if (options.mode === "passthrough") {
mode = FuncMode.PASS;
} else if (options.mode === "strip") {
mode = FuncMode.STRIP;
}
/**
* Parse a value. Throw a ValitaError on failure.
*/
parse(v: unknown, options?: ParseOptions): Infer<this> {
let flags = FLAG_FORBID_EXTRA_KEYS;
if (options?.mode === "passthrough") {
flags = 0;
} else if (options?.mode === "strip") {
flags = FLAG_STRIP_EXTRA_KEYS;
}
const r = this.func(v, mode);
const r = this.func(v, flags);
if (r === undefined) {

@@ -529,2 +556,23 @@ return v as Infer<this>;

class Nullable<Output = unknown> extends Type<Output | null> {
readonly name = "nullable";
constructor(private readonly type: Type<Output>) {
super();
}
func(v: unknown, flags: number): RawResult<Output | null> {
return v === null ? undefined : this.type.func(v, flags);
}
toTerminals(func: (t: TerminalType) => void): void {
func(nullSingleton);
this.type.toTerminals(func);
}
nullable(): Type<Output | null> {
return this;
}
}
/**

@@ -544,6 +592,6 @@ * A validator/parser marked as "optional", signifying that their value can

func(v: unknown, mode: FuncMode): RawResult<Output | undefined> {
return v === undefined || v === Nothing
func(v: unknown, flags: number): RawResult<Output | undefined> {
return v === undefined || flags & FLAG_MISSING_VALUE
? undefined
: this.type.func(v, mode);
: this.type.func(v, flags);
}

@@ -651,3 +699,3 @@

func(v: unknown, mode: FuncMode): RawResult<ObjectOutput<Shape, Rest>> {
func(v: unknown, flags: number): RawResult<ObjectOutput<Shape, Rest>> {
let func = this._func;

@@ -658,3 +706,3 @@ if (func === undefined) {

}
return func(v, mode) as RawResult<ObjectOutput<Shape, Rest>>;
return func(v, flags) as RawResult<ObjectOutput<Shape, Rest>>;
}

@@ -788,3 +836,3 @@

return function (obj, mode) {
return function (obj, flags) {
if (!isObject(obj)) {

@@ -801,3 +849,7 @@ return invalidType;

if (mode !== FuncMode.PASS || rest !== undefined) {
if (
flags & FLAG_FORBID_EXTRA_KEYS ||
flags & FLAG_STRIP_EXTRA_KEYS ||
rest !== undefined
) {
for (const key in obj) {

@@ -811,7 +863,7 @@ const value = obj[key];

seenBits = setBit(seenBits, index);
r = types[index].func(value, mode);
r = types[index].func(value, flags);
} else if (rest !== undefined) {
r = rest.func(value, mode);
r = rest.func(value, flags);
} else {
if (mode === FuncMode.STRICT) {
if (flags & FLAG_FORBID_EXTRA_KEYS) {
if (unrecognized === undefined) {

@@ -823,3 +875,3 @@ unrecognized = [key];

} else if (
mode === FuncMode.STRIP &&
flags & FLAG_STRIP_EXTRA_KEYS &&
issues === undefined &&

@@ -874,3 +926,5 @@ !copied

const key = keys[i];
let value = obj[key];
const value = obj[key];
let keyFlags = flags & ~FLAG_MISSING_VALUE;
if (value === undefined && !(key in obj)) {

@@ -881,7 +935,12 @@ if (i < requiredCount) {

}
value = Nothing;
keyFlags |= FLAG_MISSING_VALUE;
}
const r = types[i].func(value, mode);
const r = types[i].func(value, keyFlags);
if (r === undefined) {
if (copied && issues === undefined && value !== Nothing) {
if (
copied &&
issues === undefined &&
!(keyFlags & FLAG_MISSING_VALUE)
) {
set(output, key, value);

@@ -986,3 +1045,3 @@ }

func(arr: unknown, mode: FuncMode): RawResult<ArrayOutput<Head, Rest>> {
func(arr: unknown, flags: number): RawResult<ArrayOutput<Head, Rest>> {
if (!Array.isArray(arr)) {

@@ -1003,3 +1062,3 @@ return this.invalidType;

const type = i < minLength ? this.head[i] : this.rest;
const r = type.func(arr[i], mode);
const r = type.func(arr[i], flags);
if (r !== undefined) {

@@ -1174,10 +1233,12 @@ if (r.ok) {

return function (_obj: unknown, mode: FuncMode) {
return function (_obj: unknown, flags: number) {
const obj = _obj as Record<string, unknown>;
const value = obj[key];
if (value === undefined && !(key in obj)) {
return optionals.length > 0 ? optionals[0].func(obj, mode) : missingValue;
return optionals.length > 0
? optionals[0].func(obj, flags)
: missingValue;
}
const option = byType?.[toInputType(value)] ?? litMap?.get(value);
return option ? option.func(obj, mode) : issue;
return option ? option.func(obj, flags) : issue;
};

@@ -1238,5 +1299,5 @@ }

return function (value: unknown, mode: FuncMode) {
return function (value: unknown, flags: number) {
let options: undefined | AbstractType[];
if (value === Nothing) {
if (flags & FLAG_MISSING_VALUE) {
options = optionals;

@@ -1253,3 +1314,3 @@ } else {

for (let i = 0; i < options.length; i++) {
const r = options[i].func(value, mode);
const r = options[i].func(value, flags);
if (r === undefined || r.ok) {

@@ -1280,3 +1341,3 @@ return r;

func(v: unknown, mode: FuncMode): RawResult<Infer<T[number]>> {
func(v: unknown, flags: number): RawResult<Infer<T[number]>> {
let func = this._func;

@@ -1295,7 +1356,7 @@ if (func === undefined) {

} else {
func = function (v, mode) {
func = function (v, f) {
if (isObject(v)) {
return object(v, mode) as RawResult<Infer<T[number]>>;
return object(v, f) as RawResult<Infer<T[number]>>;
}
return base(v, mode) as RawResult<Infer<T[number]>>;
return base(v, f) as RawResult<Infer<T[number]>>;
};

@@ -1305,10 +1366,19 @@ }

}
return func(v, mode);
return func(v, flags);
}
}
type TransformFunc = (
value: unknown,
options: ParseOptions,
) => RawResult<unknown>;
const STRICT = Object.freeze({ mode: "strict" }) as ParseOptions;
const STRIP = Object.freeze({ mode: "strip" }) as ParseOptions;
const PASSTHROUGH = Object.freeze({ mode: "passthrough" }) as ParseOptions;
class TransformType<Output> extends Type<Output> {
readonly name = "transform";
private transformChain?: Func<unknown>[];
private transformChain?: TransformFunc[];
private transformRoot?: AbstractType;

@@ -1319,3 +1389,3 @@ private readonly undef = ok(undefined);

protected readonly transformed: AbstractType,
protected readonly transform: Func<unknown>,
protected readonly transform: TransformFunc,
) {

@@ -1327,3 +1397,3 @@ super();

func(v: unknown, mode: FuncMode): RawResult<Output> {
func(v: unknown, flags: number): RawResult<Output> {
let chain = this.transformChain;

@@ -1345,3 +1415,3 @@ if (!chain) {

// eslint-disable-next-line
let result = this.transformRoot!.func(v, mode);
let result = this.transformRoot!.func(v, flags);
if (result !== undefined && !result.ok) {

@@ -1354,3 +1424,3 @@ return result;

current = result.value;
} else if (v === Nothing) {
} else if (flags & FLAG_MISSING_VALUE) {
current = undefined;

@@ -1362,4 +1432,10 @@ result = this.undef;

const options =
flags & FLAG_FORBID_EXTRA_KEYS
? STRICT
: flags & FLAG_STRIP_EXTRA_KEYS
? STRIP
: PASSTHROUGH;
for (let i = 0; i < chain.length; i++) {
const r = chain[i](current, mode);
const r = chain[i](current, options);
if (r !== undefined) {

@@ -1390,7 +1466,7 @@ if (!r.ok) {

func(v: unknown, mode: FuncMode): RawResult<T> {
func(v: unknown, flags: number): RawResult<T> {
if (!this.type) {
this.type = this.definer();
}
return this.type.func(v, mode);
return this.type.func(v, flags);
}

@@ -1421,3 +1497,3 @@

};
func(_: unknown, __: FuncMode): RawResult<never> {
func(_: unknown, __: number): RawResult<never> {
return this.issue;

@@ -1438,3 +1514,3 @@ }

readonly name = "unknown";
func(_: unknown, __: FuncMode): RawResult<unknown> {
func(_: unknown, __: number): RawResult<unknown> {
return undefined;

@@ -1460,3 +1536,3 @@ }

};
func(v: unknown, _: FuncMode): RawResult<undefined> {
func(v: unknown, _: number): RawResult<undefined> {
return v === undefined ? undefined : this.issue;

@@ -1481,3 +1557,3 @@ }

};
func(v: unknown, _: FuncMode): RawResult<null> {
func(v: unknown, _: number): RawResult<null> {
return v === null ? undefined : this.issue;

@@ -1502,3 +1578,3 @@ }

};
func(v: unknown, _: FuncMode): RawResult<number> {
func(v: unknown, _: number): RawResult<number> {
return typeof v === "number" ? undefined : this.issue;

@@ -1523,3 +1599,3 @@ }

};
func(v: unknown, _: FuncMode): RawResult<bigint> {
func(v: unknown, _: number): RawResult<bigint> {
return typeof v === "bigint" ? undefined : this.issue;

@@ -1544,3 +1620,3 @@ }

};
func(v: unknown, _: FuncMode): RawResult<string> {
func(v: unknown, _: number): RawResult<string> {
return typeof v === "string" ? undefined : this.issue;

@@ -1565,3 +1641,3 @@ }

};
func(v: unknown, _: FuncMode): RawResult<boolean> {
func(v: unknown, _: number): RawResult<boolean> {
return typeof v === "boolean" ? undefined : this.issue;

@@ -1590,3 +1666,3 @@ }

}
func(v: unknown, _: FuncMode): RawResult<Out> {
func(v: unknown, _: number): RawResult<Out> {
return v === this.value ? undefined : this.issue;

@@ -1593,0 +1669,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc