The Switchboard SDK validates the Order object when created by use of the toOrder
method. If the order has any invalid property or sub-property (e.g. an Address property is invalid), an exception will be logged and thrown with the specific failures as defined by the Protect Order model definition.
Protect API uses the class-validator
, which works by allowing decorators prefixed with @
to designate runtime validation that can be invoked by calling the validation methods. For example:
export class Post {
@Length(10, 20)
title: string;
@Contains("hello")
text: string;
@IsInt()
@Min(0)
@Max(10)
rating: number;
@IsEmail()
email: string;
@IsFQDN()
site: string;
@IsDate()
createDate: Date;
}
...
const x = new Post();
x.email = 'foo@bar.com';
const xValid = await x.isValid(); //true
const y = new Post();
y.email = 'foobarcom';
const yValid = await x.isValid(); //false
The Switchboard SDK consumes the luddites-protect-models
project, which is simply an export of the protect-api models folder. This allows the SDK to convert the loosely typed {name}Data
classes into the strongly typed model classes that Protect expects. Since luddites-protect-models
is an exported (and therefore transpiled to JavaScript) project, the decorators and attributes defined in the original source code are not transferred to the compiled code, which means that class-validator
cannot independently and by itself be used to validate a Protect model.
Further, the use of multiple instances of class-validator
(one from luddites-protect-models
and the other from protect-sdk-switchboard
) is not currently supported. For these reasons, the validation is entirely delegated to luddites-protect-api
and exposed to downstream consumers via two key methods: isValid
and getValidationErrors
(see IValidatable
). ValidationErrors
include the full validation context as provided by class-validator
.
With the exception of the Order
class, all protect models that together comprise an instance of an Order implement this interface and these methods. As the Order
class implements a separate interface, this class exposes these two methods directly (and not by the direction of its implemented interface). On Order
, the isValid
and getValidationErrors
methods validate the entire Order object, its properties, its related classes and all related classes properties and sub-properties.
From within the Switchboard SDK, the underlying implementation of the validation logic is applied only to the toOrder
method at the conclusion of all data conversions. This allows all nested objects to be fully populated in order that on validation failure, the reported errors will include every failure for every property on the entire object. Therefore, it is strongly recommended to either convert raw data objects using toOrder
or to manually validate the order using validateOrder
.
The validation methods provided by class-validator
are asynchronous; therefore significant refactoring was required in order to change the converter logic to also be asynchronous. As validation only occurs automatically via toOrder
or manually via validateOrder
, within the SDK these are the only consumer facing methods which are async. The converters for Address, LineItem, etc. remain sync.
Unit tests in the Switchboard SDK are implemented using the test runner utilities from protect-tools-js
. As the testing suite was originally written to operate synchronously, the suite had to be refactored to run async and all implementations of the test runner in downstream projects required similar refactoring. As a result of this work, the test suite now fully supports both synchronous and asynchronous tests out of the box.