Skip to content

Getting started ​

Install ​

juniper is a peer dependency, so install both:

sh
npm i juniper juniper-validator
sh
pnpm add juniper juniper-validator
sh
yarn add juniper juniper-validator

TIP

juniper-validator is ESM only, and requires Node.js 24 or later. From CommonJS, load it with a dynamic import: const { makeValidator } = await import('juniper-validator');

Make a validator ​

Pass a schema to makeValidator. The schema is compiled once, so make the validator once and reuse it:

ts
import { 
mergeSchema
,
numberSchema
,
stringSchema
} from 'juniper';
import {
makeValidator
} from 'juniper-validator';
const
schema
=
mergeSchema
().
anyOf
([
numberSchema
().
exclusiveMinimum
(2).
maximum
(13),
stringSchema
().
contains
('foo').
endsWith
('bar'),
]); const
validator
=
makeValidator
(
schema
);
const validator: JuniperValidator<number | (`${string}bar` & `${string}foo${string}`)>

A validator checks data three ways.

is(): type guard ​

Returns whether the value matches, and narrows it when it does:

ts
if (
validator
.
is
(
input
)) {
console
.
log
(
input
);
const input: number | (`${string}bar` & `${string}foo${string}`)
}

validate(): issues ​

Returns the value, or the reasons it doesn't match:

ts
const 
result
=
validator
.
validate
(true);
if (
result
.
issues
) {
console
.
error
(
result
.
issues
.
map
(
issue
=>
issue
.
message
));
// ['must be number', 'must be string', 'must match a schema in anyOf'] } else {
console
.
log
(
result
.
value
);
StandardSchemaV1<Input = unknown, Output = Input>.SuccessResult<number | (`${string}bar` & `${string}foo${string}`)>.value: number | (`${string}bar` & `${string}foo${string}`)

The typed output value.

}

assert(): throw ​

Throws when the value doesn't match, and narrows it after the call when it does. TypeScript only narrows with an assertion function whose type is written out, so annotate the validator, or the function, with a type:

ts
const 
validator
:
JuniperValidator
<string> =
makeValidator
(
schema
);
validator
.
assert
(
input
);
console
.
log
(
input
);
const input: string
const
assertBar
:
AssertionType
<typeof
validator
> =
validator
.
assert
;
assertBar
(
other
);
console
.
log
(
other
);
const other: string

Without one, TypeScript rejects the call:

ts
const { 
assert
} =
makeValidator
(
stringSchema
());
assert(
input
);
Assertions require every name in the call target to be declared with an explicit type annotation.

The thrown Error has the message Value does not match schema, and Ajv's error objects as its cause.

Plain JSON Schemas ​

makeValidator also takes a rendered JSON Schema object, such as one loaded from a file. Its type is whatever the JsonSchema is typed as, so an untyped object validates to unknown:

ts
import { 
stringSchema
} from 'juniper';
import {
makeValidator
} from 'juniper-validator';
const
json
=
stringSchema
().
toJSON
();
const json: JsonSchema<string>
const
fromJuniper
=
makeValidator
(
json
);
const fromJuniper: JuniperValidator<string>
const
fromFile
=
makeValidator
(
JSON
.
parse
('{ "type": "string" }'));
const fromFile: JuniperValidator<unknown>

Next steps ​