jsvrx
v2.0.0
Published
An interface for RxJS operators creation to validate/discriminate data objects using JSON Schema(s).
Downloads
16
Maintainers
Readme
jsvrx
RxJS operators to validate/discriminate data objects using JSON Schema(s).
Features
- Basic
DataValidator
interface to validate/discriminate data objects- validate a data object using single JSON Schema
- discriminate a data object using set of JSON Schemas
- Data validation and JSON Schema processing can be provided by third-party libraries
- Compatible with standard RxJS data processing
- ECMAScript module, typings available
Usage
The package declares an abstract DataValidator
interface. Use existing implementations or create your own.
Known implementations:
- jsvrx-ajv -
DataValidator
implementation using Ajv - jsvrx-djv -
DataValidator
implementation using Djv
Examples
Parse a string and validate objects array
const data: string = ...; // JSON encoded array of objects T
const schema: JSONSchema = { $id: 'SCHEMA', ... }; // JSON Schema of type T
const dv: DataValidator = new someDataValidator(...);
dv.addSchemas([schema]);
of(data).pipe(
map((s) => JSON.Parse(s)),
mergeMap((arr) => from(arr)),
dv.validate(schema.$id)
); // <-- Observable<T>
Parse a string and discriminate object array
const data: string = ...; // JSON encoded array of objects
const schemas: JSONSchema[] = [...]; // JSON Schemas of types in data
const dv: DataValidator = new someDataValidator(...);
dv.addSchemas(schemas);
of(data).pipe(
map((s) => JSON.Parse(s)),
switchMap((arr) => from(arr)),
dv.discriminate(schemas.map((s) => s.$id), 'invalid'),
mergeMap((group) =>
group.pipe(
// Processing specific to object validated by JSON Schema group.key
toArray(),
map((arr) => ({ [group.key]: arr }))
)
)
reduce((acc, g) => ({ ...acc, ...g }), {} as Record<string, unknown[]>)
); // <-- Observable<{ ID1: [...], ID2: [...], ... , invalid: [...] }>
DataValidator
interface constructs validators and discriminators to use in RxJS data stream processing to validate unknown data object or produce new data streams based on validation results using a set of JSON Schemas.
DataValidator interface
DataValidator
interface provides methods to add JSON Schemas and to construct validate and dicriminate RxJS operators for a set of Schema ids. To start processing data is RxJS stream one can take the following steps:
- Instantiate an implementation of
DataValidator
interface; - Add required JSON Schema using
addSchemas()
method or by other means provided. Every schema should have a unique identifier that is used to reference the schema invalidate()
anddiscriminate()
methods. - Get required RxJS operator for a set of JSON Schema identifiers using
validate()
ordiscriminate()
methods. - Use the operator in RxJS data processing
pipe()
.
Validator
A validate operator uses a single JSON Schema to validate data objects and throw an error if failed. Consider discriminate operator if multiple JSON Schemas validation or custom error handling is required.
validate(id: JSONSchemaID)
constructs RxJS operator to validate data objects using JSON Schema selected by id
. If validation fails a ValidationError()
error is thrown.
The operator returns Observable.
Discriminator
A discriminate operator uses a set of JSON Schemas to validate data objects and creates new RxJS output data streams. Every input object is validated and placed in the output data stream according to the object's validated type. Invalid objects are placed in a dedicated output data stream.
discriminate(ids: JSONSchemaID[], unk?: JSONSchemaID)
constructs RxJS operator to discriminate data objects using a set of JSON Schemas defined by ids
array. Validated objects are grouped by JSON Schema and are marked with the schema's id, invalid objects are reported in a group marked with unk
value. If validation fails and unk
is not set a ValidationError()
error is thrown.
The operator returns GroupedObservable for every unique schema id.
| Validation result | unk
parameter | GroupedObservable.key
|
| ---: | :--- | :--- |
| Validated by a schema id
| - | id
|
| Invalid | present | inv
|
| Invalid | absent | ValidationError
is thrown |
Typing
DataValidator
interface provides typing information for validate
and discriminate
methods using generics.
validate<T>(...): OperatorFunction<unknown, T>
T is unknown by default.
It's possible to create a JSON Schema -> Type mapping type to control discriminate operator typing.
// IDx - JSON schema ids, Tx - corresponding typescript types
type M = { ID1: T1, ID2: T2 };
discriminate<M>(...): OperatorFunction<
unknown,
GroupedObservable<ID1, T1> | GroupedObservable<ID2, T2>>
>
M is { [JSONSchemaID]: unknown } by default.
discriminate(...): OperatorFunction<
unknown,
GroupedObservable<string, unknown>
>
A custom implementation
The package declares two functions to help implementing custom provider DataValidator
interface:
validate<T>(v: (obj: unknown) => T)): ValidatorOperator<T>
discriminate<M>(d: (obj: unknown) => keyof M)) DiscriminatorOperator<M>
Both functions with a projector provided as a parameter return correct RxJS operator to implement DataValidator
interface requirements.
To design a custom provider:
- Declare a class that implements the
DataValidator
interface. - Desing a custom constructor method.
- Implement
addSchemas(schemas: JSONSchema[])
method. - In
validate(id: JSONSchemaID)
method implementation define a functions that validates unknown object with JSONSchema. Return helpervalidate()
with the function as the parameter. - In
discriminate(ids: JSONSchemaID[], unk?: JSONSchemaID)
method implementation define a functions that validates unknown object with set of JSONSchemas and choose the schema id orunk
value. Return helperdiscriminate()
with the function as the parameter.