added all files

This commit is contained in:
DJj123dj
2021-11-14 09:12:55 +01:00
commit 918f5f4243
2793 changed files with 298038 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
import { BasePredicate, testSymbol } from './base-predicate';
import { PredicateOptions } from './predicate';
import { Main } from '..';
/**
@hidden
*/
export declare class AnyPredicate<T = unknown> implements BasePredicate<T> {
private readonly predicates;
private readonly options;
constructor(predicates: BasePredicate[], options?: PredicateOptions);
[testSymbol](value: T, main: Main, label: string | Function, idLabel: boolean): asserts value;
}
+55
View File
@@ -0,0 +1,55 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AnyPredicate = void 0;
const argument_error_1 = require("../argument-error");
const base_predicate_1 = require("./base-predicate");
const generate_argument_error_message_1 = require("../utils/generate-argument-error-message");
/**
@hidden
*/
class AnyPredicate {
constructor(predicates, options = {}) {
Object.defineProperty(this, "predicates", {
enumerable: true,
configurable: true,
writable: true,
value: predicates
});
Object.defineProperty(this, "options", {
enumerable: true,
configurable: true,
writable: true,
value: options
});
}
[base_predicate_1.testSymbol](value, main, label, idLabel) {
const errors = new Map();
for (const predicate of this.predicates) {
try {
main(value, label, predicate, idLabel);
return;
}
catch (error) {
if (value === undefined && this.options.optional === true) {
return;
}
// If we received an ArgumentError, then..
if (error instanceof argument_error_1.ArgumentError) {
// Iterate through every error reported.
for (const [key, value] of error.validationErrors.entries()) {
// Get the current errors set, if any.
const alreadyPresent = errors.get(key);
// Add all errors under the same key
errors.set(key, new Set([...alreadyPresent !== null && alreadyPresent !== void 0 ? alreadyPresent : [], ...value]));
}
}
}
}
if (errors.size > 0) {
// Generate the `error.message` property.
const message = generate_argument_error_message_1.generateArgumentErrorMessage(errors, true);
throw new argument_error_1.ArgumentError(`Any predicate failed with the following errors:\n${message}`, main, errors);
}
}
}
exports.AnyPredicate = AnyPredicate;
+21
View File
@@ -0,0 +1,21 @@
import { Predicate } from './predicate';
export declare class ArrayBufferPredicate<T extends ArrayBufferLike> extends Predicate<T> {
/**
Test an array buffer to have a specific byte length.
@param byteLength - The byte length of the array buffer.
*/
byteLength(byteLength: number): this;
/**
Test an array buffer to have a minimum byte length.
@param byteLength - The minimum byte length of the array buffer.
*/
minByteLength(byteLength: number): this;
/**
Test an array buffer to have a minimum byte length.
@param length - The minimum byte length of the array buffer.
*/
maxByteLength(byteLength: number): this;
}
+42
View File
@@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ArrayBufferPredicate = void 0;
const predicate_1 = require("./predicate");
class ArrayBufferPredicate extends predicate_1.Predicate {
/**
Test an array buffer to have a specific byte length.
@param byteLength - The byte length of the array buffer.
*/
byteLength(byteLength) {
return this.addValidator({
message: (value, label) => `Expected ${label} to have byte length of \`${byteLength}\`, got \`${value.byteLength}\``,
validator: value => value.byteLength === byteLength
});
}
/**
Test an array buffer to have a minimum byte length.
@param byteLength - The minimum byte length of the array buffer.
*/
minByteLength(byteLength) {
return this.addValidator({
message: (value, label) => `Expected ${label} to have a minimum byte length of \`${byteLength}\`, got \`${value.byteLength}\``,
validator: value => value.byteLength >= byteLength,
negatedMessage: (value, label) => `Expected ${label} to have a maximum byte length of \`${byteLength - 1}\`, got \`${value.byteLength}\``
});
}
/**
Test an array buffer to have a minimum byte length.
@param length - The minimum byte length of the array buffer.
*/
maxByteLength(byteLength) {
return this.addValidator({
message: (value, label) => `Expected ${label} to have a maximum byte length of \`${byteLength}\`, got \`${value.byteLength}\``,
validator: value => value.byteLength <= byteLength,
negatedMessage: (value, label) => `Expected ${label} to have a minimum byte length of \`${byteLength + 1}\`, got \`${value.byteLength}\``
});
}
}
exports.ArrayBufferPredicate = ArrayBufferPredicate;
+86
View File
@@ -0,0 +1,86 @@
import { BasePredicate } from './base-predicate';
import { Predicate, PredicateOptions } from './predicate';
export declare class ArrayPredicate<T = unknown> extends Predicate<T[]> {
/**
@hidden
*/
constructor(options?: PredicateOptions);
/**
Test an array to have a specific length.
@param length - The length of the array.
*/
length(length: number): this;
/**
Test an array to have a minimum length.
@param length - The minimum length of the array.
*/
minLength(length: number): this;
/**
Test an array to have a maximum length.
@param length - The maximum length of the array.
*/
maxLength(length: number): this;
/**
Test an array to start with a specific value. The value is tested by identity, not structure.
@param searchElement - The value that should be the start of the array.
*/
startsWith(searchElement: T): this;
/**
Test an array to end with a specific value. The value is tested by identity, not structure.
@param searchElement - The value that should be the end of the array.
*/
endsWith(searchElement: T): this;
/**
Test an array to include all the provided elements. The values are tested by identity, not structure.
@param searchElements - The values that should be included in the array.
*/
includes(...searchElements: readonly T[]): this;
/**
Test an array to include any of the provided elements. The values are tested by identity, not structure.
@param searchElements - The values that should be included in the array.
*/
includesAny(...searchElements: readonly T[]): this;
/**
Test an array to be empty.
*/
get empty(): this;
/**
Test an array to be not empty.
*/
get nonEmpty(): this;
/**
Test an array to be deeply equal to the provided array.
@param expected - Expected value to match.
*/
deepEqual(expected: readonly T[]): this;
/**
Test all elements in the array to match to provided predicate.
@param predicate - The predicate that should be applied against every individual item.
@example
```
ow(['a', 1], ow.array.ofType(ow.any(ow.string, ow.number)));
```
*/
ofType<U extends T>(predicate: BasePredicate<U>): ArrayPredicate<U>;
/**
Test if the elements in the array exactly matches the elements placed at the same indices in the predicates array.
@param predicates - Predicates to test the array against. Describes what the tested array should look like.
@example
```
ow(['1', 2], ow.array.exactShape([ow.string, ow.number]));
```
*/
exactShape(predicates: Predicate[]): this;
}
+158
View File
@@ -0,0 +1,158 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ArrayPredicate = void 0;
const isEqual = require("lodash.isequal");
const predicate_1 = require("./predicate");
const match_shape_1 = require("../utils/match-shape");
const of_type_1 = require("../utils/of-type");
class ArrayPredicate extends predicate_1.Predicate {
/**
@hidden
*/
constructor(options) {
super('array', options);
}
/**
Test an array to have a specific length.
@param length - The length of the array.
*/
length(length) {
return this.addValidator({
message: (value, label) => `Expected ${label} to have length \`${length}\`, got \`${value.length}\``,
validator: value => value.length === length
});
}
/**
Test an array to have a minimum length.
@param length - The minimum length of the array.
*/
minLength(length) {
return this.addValidator({
message: (value, label) => `Expected ${label} to have a minimum length of \`${length}\`, got \`${value.length}\``,
validator: value => value.length >= length,
negatedMessage: (value, label) => `Expected ${label} to have a maximum length of \`${length - 1}\`, got \`${value.length}\``
});
}
/**
Test an array to have a maximum length.
@param length - The maximum length of the array.
*/
maxLength(length) {
return this.addValidator({
message: (value, label) => `Expected ${label} to have a maximum length of \`${length}\`, got \`${value.length}\``,
validator: value => value.length <= length,
negatedMessage: (value, label) => `Expected ${label} to have a minimum length of \`${length + 1}\`, got \`${value.length}\``
});
}
/**
Test an array to start with a specific value. The value is tested by identity, not structure.
@param searchElement - The value that should be the start of the array.
*/
startsWith(searchElement) {
return this.addValidator({
message: (value, label) => `Expected ${label} to start with \`${searchElement}\`, got \`${value[0]}\``,
validator: value => value[0] === searchElement
});
}
/**
Test an array to end with a specific value. The value is tested by identity, not structure.
@param searchElement - The value that should be the end of the array.
*/
endsWith(searchElement) {
return this.addValidator({
message: (value, label) => `Expected ${label} to end with \`${searchElement}\`, got \`${value[value.length - 1]}\``,
validator: value => value[value.length - 1] === searchElement
});
}
/**
Test an array to include all the provided elements. The values are tested by identity, not structure.
@param searchElements - The values that should be included in the array.
*/
includes(...searchElements) {
return this.addValidator({
message: (value, label) => `Expected ${label} to include all elements of \`${JSON.stringify(searchElements)}\`, got \`${JSON.stringify(value)}\``,
validator: value => searchElements.every(element => value.includes(element))
});
}
/**
Test an array to include any of the provided elements. The values are tested by identity, not structure.
@param searchElements - The values that should be included in the array.
*/
includesAny(...searchElements) {
return this.addValidator({
message: (value, label) => `Expected ${label} to include any element of \`${JSON.stringify(searchElements)}\`, got \`${JSON.stringify(value)}\``,
validator: value => searchElements.some(element => value.includes(element))
});
}
/**
Test an array to be empty.
*/
get empty() {
return this.addValidator({
message: (value, label) => `Expected ${label} to be empty, got \`${JSON.stringify(value)}\``,
validator: value => value.length === 0
});
}
/**
Test an array to be not empty.
*/
get nonEmpty() {
return this.addValidator({
message: (_, label) => `Expected ${label} to not be empty`,
validator: value => value.length > 0
});
}
/**
Test an array to be deeply equal to the provided array.
@param expected - Expected value to match.
*/
deepEqual(expected) {
return this.addValidator({
message: (value, label) => `Expected ${label} to be deeply equal to \`${JSON.stringify(expected)}\`, got \`${JSON.stringify(value)}\``,
validator: value => isEqual(value, expected)
});
}
/**
Test all elements in the array to match to provided predicate.
@param predicate - The predicate that should be applied against every individual item.
@example
```
ow(['a', 1], ow.array.ofType(ow.any(ow.string, ow.number)));
```
*/
ofType(predicate) {
// TODO [typescript@>=5] If higher-kinded types are supported natively by typescript, refactor `addValidator` to use them to avoid the usage of `any`. Otherwise, bump or remove this TODO.
return this.addValidator({
message: (_, label, error) => `(${label}) ${error}`,
validator: value => of_type_1.default(value, 'values', predicate)
});
}
/**
Test if the elements in the array exactly matches the elements placed at the same indices in the predicates array.
@param predicates - Predicates to test the array against. Describes what the tested array should look like.
@example
```
ow(['1', 2], ow.array.exactShape([ow.string, ow.number]));
```
*/
exactShape(predicates) {
const shape = predicates;
return this.addValidator({
message: (_, label, message) => `${message.replace('Expected', 'Expected element')} in ${label}`,
validator: object => match_shape_1.exact(object, shape, undefined, true)
});
}
}
exports.ArrayPredicate = ArrayPredicate;
+15
View File
@@ -0,0 +1,15 @@
import { Main } from '..';
/**
@hidden
*/
export declare const testSymbol: unique symbol;
/**
@hidden
*/
export declare const isPredicate: (value: unknown) => value is BasePredicate<unknown>;
/**
@hidden
*/
export interface BasePredicate<T = unknown> {
[testSymbol](value: T, main: Main, label: string | Function, idLabel?: boolean): void;
}
+12
View File
@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isPredicate = exports.testSymbol = void 0;
/**
@hidden
*/
exports.testSymbol = Symbol('test');
/**
@hidden
*/
const isPredicate = (value) => Boolean(value[exports.testSymbol]);
exports.isPredicate = isPredicate;
+7
View File
@@ -0,0 +1,7 @@
import { Predicate, PredicateOptions } from './predicate';
export declare class BigIntPredicate extends Predicate<bigint> {
/**
@hidden
*/
constructor(options?: PredicateOptions);
}
+13
View File
@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BigIntPredicate = void 0;
const predicate_1 = require("./predicate");
class BigIntPredicate extends predicate_1.Predicate {
/**
@hidden
*/
constructor(options) {
super('bigint', options);
}
}
exports.BigIntPredicate = BigIntPredicate;
+15
View File
@@ -0,0 +1,15 @@
import { Predicate, PredicateOptions } from './predicate';
export declare class BooleanPredicate extends Predicate<boolean> {
/**
@hidden
*/
constructor(options?: PredicateOptions);
/**
Test a boolean to be true.
*/
get true(): this;
/**
Test a boolean to be false.
*/
get false(): this;
}
+31
View File
@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BooleanPredicate = void 0;
const predicate_1 = require("./predicate");
class BooleanPredicate extends predicate_1.Predicate {
/**
@hidden
*/
constructor(options) {
super('boolean', options);
}
/**
Test a boolean to be true.
*/
get true() {
return this.addValidator({
message: (value, label) => `Expected ${label} to be true, got ${value}`,
validator: value => value
});
}
/**
Test a boolean to be false.
*/
get false() {
return this.addValidator({
message: (value, label) => `Expected ${label} to be false, got ${value}`,
validator: value => !value
});
}
}
exports.BooleanPredicate = BooleanPredicate;
+25
View File
@@ -0,0 +1,25 @@
import { Predicate, PredicateOptions } from './predicate';
export declare class DataViewPredicate extends Predicate<DataView> {
/**
@hidden
*/
constructor(options?: PredicateOptions);
/**
Test a DataView to have a specific byte length.
@param byteLength - The byte length of the DataView.
*/
byteLength(byteLength: number): this;
/**
Test a DataView to have a minimum byte length.
@param byteLength - The minimum byte length of the DataView.
*/
minByteLength(byteLength: number): this;
/**
Test a DataView to have a minimum byte length.
@param length - The minimum byte length of the DataView.
*/
maxByteLength(byteLength: number): this;
}
+48
View File
@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DataViewPredicate = void 0;
const predicate_1 = require("./predicate");
class DataViewPredicate extends predicate_1.Predicate {
/**
@hidden
*/
constructor(options) {
super('DataView', options);
}
/**
Test a DataView to have a specific byte length.
@param byteLength - The byte length of the DataView.
*/
byteLength(byteLength) {
return this.addValidator({
message: (value, label) => `Expected ${label} to have byte length of \`${byteLength}\`, got \`${value.byteLength}\``,
validator: value => value.byteLength === byteLength
});
}
/**
Test a DataView to have a minimum byte length.
@param byteLength - The minimum byte length of the DataView.
*/
minByteLength(byteLength) {
return this.addValidator({
message: (value, label) => `Expected ${label} to have a minimum byte length of \`${byteLength}\`, got \`${value.byteLength}\``,
validator: value => value.byteLength >= byteLength,
negatedMessage: (value, label) => `Expected ${label} to have a maximum byte length of \`${byteLength - 1}\`, got \`${value.byteLength}\``
});
}
/**
Test a DataView to have a minimum byte length.
@param length - The minimum byte length of the DataView.
*/
maxByteLength(byteLength) {
return this.addValidator({
message: (value, label) => `Expected ${label} to have a maximum byte length of \`${byteLength}\`, got \`${value.byteLength}\``,
validator: value => value.byteLength <= byteLength,
negatedMessage: (value, label) => `Expected ${label} to have a minimum byte length of \`${byteLength + 1}\`, got \`${value.byteLength}\``
});
}
}
exports.DataViewPredicate = DataViewPredicate;
+19
View File
@@ -0,0 +1,19 @@
import { Predicate, PredicateOptions } from './predicate';
export declare class DatePredicate extends Predicate<Date> {
/**
@hidden
*/
constructor(options?: PredicateOptions);
/**
Test a date to be before another date.
@param date - Maximum value.
*/
before(date: Date): this;
/**
Test a date to be before another date.
@param date - Minimum value.
*/
after(date: Date): this;
}
+35
View File
@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DatePredicate = void 0;
const predicate_1 = require("./predicate");
class DatePredicate extends predicate_1.Predicate {
/**
@hidden
*/
constructor(options) {
super('date', options);
}
/**
Test a date to be before another date.
@param date - Maximum value.
*/
before(date) {
return this.addValidator({
message: (value, label) => `Expected ${label} ${value.toISOString()} to be before ${date.toISOString()}`,
validator: value => value.getTime() < date.getTime()
});
}
/**
Test a date to be before another date.
@param date - Minimum value.
*/
after(date) {
return this.addValidator({
message: (value, label) => `Expected ${label} ${value.toISOString()} to be after ${date.toISOString()}`,
validator: value => value.getTime() > date.getTime()
});
}
}
exports.DatePredicate = DatePredicate;
+61
View File
@@ -0,0 +1,61 @@
import { Predicate, PredicateOptions } from './predicate';
export declare class ErrorPredicate extends Predicate<Error> {
/**
@hidden
*/
constructor(options?: PredicateOptions);
/**
Test an error to have a specific name.
@param expected - Expected name of the Error.
*/
name(expected: string): this;
/**
Test an error to have a specific message.
@param expected - Expected message of the Error.
*/
message(expected: string): this;
/**
Test the error message to include a specific message.
@param message - Message that should be included in the error.
*/
messageIncludes(message: string): this;
/**
Test the error object to have specific keys.
@param keys - One or more keys which should be part of the error object.
*/
hasKeys(...keys: readonly string[]): this;
/**
Test an error to be of a specific instance type.
@param instance - The expected instance type of the error.
*/
instanceOf(instance: Function): this;
/**
Test an Error to be a TypeError.
*/
get typeError(): this;
/**
Test an Error to be an EvalError.
*/
get evalError(): this;
/**
Test an Error to be a RangeError.
*/
get rangeError(): this;
/**
Test an Error to be a ReferenceError.
*/
get referenceError(): this;
/**
Test an Error to be a SyntaxError.
*/
get syntaxError(): this;
/**
Test an Error to be a URIError.
*/
get uriError(): this;
}
+104
View File
@@ -0,0 +1,104 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ErrorPredicate = void 0;
const predicate_1 = require("./predicate");
class ErrorPredicate extends predicate_1.Predicate {
/**
@hidden
*/
constructor(options) {
super('error', options);
}
/**
Test an error to have a specific name.
@param expected - Expected name of the Error.
*/
name(expected) {
return this.addValidator({
message: (error, label) => `Expected ${label} to have name \`${expected}\`, got \`${error.name}\``,
validator: error => error.name === expected
});
}
/**
Test an error to have a specific message.
@param expected - Expected message of the Error.
*/
message(expected) {
return this.addValidator({
message: (error, label) => `Expected ${label} message to be \`${expected}\`, got \`${error.message}\``,
validator: error => error.message === expected
});
}
/**
Test the error message to include a specific message.
@param message - Message that should be included in the error.
*/
messageIncludes(message) {
return this.addValidator({
message: (error, label) => `Expected ${label} message to include \`${message}\`, got \`${error.message}\``,
validator: error => error.message.includes(message)
});
}
/**
Test the error object to have specific keys.
@param keys - One or more keys which should be part of the error object.
*/
hasKeys(...keys) {
return this.addValidator({
message: (_, label) => `Expected ${label} message to have keys \`${keys.join('`, `')}\``,
validator: error => keys.every(key => Object.prototype.hasOwnProperty.call(error, key))
});
}
/**
Test an error to be of a specific instance type.
@param instance - The expected instance type of the error.
*/
instanceOf(instance) {
return this.addValidator({
message: (error, label) => `Expected ${label} \`${error.name}\` to be of type \`${instance.name}\``,
validator: error => error instanceof instance
});
}
/**
Test an Error to be a TypeError.
*/
get typeError() {
return this.instanceOf(TypeError);
}
/**
Test an Error to be an EvalError.
*/
get evalError() {
return this.instanceOf(EvalError);
}
/**
Test an Error to be a RangeError.
*/
get rangeError() {
return this.instanceOf(RangeError);
}
/**
Test an Error to be a ReferenceError.
*/
get referenceError() {
return this.instanceOf(ReferenceError);
}
/**
Test an Error to be a SyntaxError.
*/
get syntaxError() {
return this.instanceOf(SyntaxError);
}
/**
Test an Error to be a URIError.
*/
get uriError() {
return this.instanceOf(URIError);
}
}
exports.ErrorPredicate = ErrorPredicate;
+75
View File
@@ -0,0 +1,75 @@
import { Predicate, PredicateOptions } from './predicate';
export declare class MapPredicate<T1 = unknown, T2 = unknown> extends Predicate<Map<T1, T2>> {
/**
@hidden
*/
constructor(options?: PredicateOptions);
/**
Test a Map to have a specific size.
@param size - The size of the Map.
*/
size(size: number): this;
/**
Test an Map to have a minimum size.
@param size - The minimum size of the Map.
*/
minSize(size: number): this;
/**
Test an Map to have a maximum size.
@param size - The maximum size of the Map.
*/
maxSize(size: number): this;
/**
Test a Map to include all the provided keys. The keys are tested by identity, not structure.
@param keys - The keys that should be a key in the Map.
*/
hasKeys(...keys: readonly T1[]): this;
/**
Test a Map to include any of the provided keys. The keys are tested by identity, not structure.
@param keys - The keys that could be a key in the Map.
*/
hasAnyKeys(...keys: readonly T1[]): this;
/**
Test a Map to include all the provided values. The values are tested by identity, not structure.
@param values - The values that should be a value in the Map.
*/
hasValues(...values: readonly T2[]): this;
/**
Test a Map to include any of the provided values. The values are tested by identity, not structure.
@param values - The values that could be a value in the Map.
*/
hasAnyValues(...values: readonly T2[]): this;
/**
Test all the keys in the Map to match the provided predicate.
@param predicate - The predicate that should be applied against every key in the Map.
*/
keysOfType(predicate: Predicate<T1>): this;
/**
Test all the values in the Map to match the provided predicate.
@param predicate - The predicate that should be applied against every value in the Map.
*/
valuesOfType(predicate: Predicate<T2>): this;
/**
Test a Map to be empty.
*/
get empty(): this;
/**
Test a Map to be not empty.
*/
get nonEmpty(): this;
/**
Test a Map to be deeply equal to the provided Map.
@param expected - Expected Map to match.
*/
deepEqual(expected: Map<T1, T2>): this;
}
+149
View File
@@ -0,0 +1,149 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MapPredicate = void 0;
const isEqual = require("lodash.isequal");
const has_items_1 = require("../utils/has-items");
const of_type_1 = require("../utils/of-type");
const predicate_1 = require("./predicate");
class MapPredicate extends predicate_1.Predicate {
/**
@hidden
*/
constructor(options) {
super('Map', options);
}
/**
Test a Map to have a specific size.
@param size - The size of the Map.
*/
size(size) {
return this.addValidator({
message: (map, label) => `Expected ${label} to have size \`${size}\`, got \`${map.size}\``,
validator: map => map.size === size
});
}
/**
Test an Map to have a minimum size.
@param size - The minimum size of the Map.
*/
minSize(size) {
return this.addValidator({
message: (map, label) => `Expected ${label} to have a minimum size of \`${size}\`, got \`${map.size}\``,
validator: map => map.size >= size,
negatedMessage: (map, label) => `Expected ${label} to have a maximum size of \`${size - 1}\`, got \`${map.size}\``
});
}
/**
Test an Map to have a maximum size.
@param size - The maximum size of the Map.
*/
maxSize(size) {
return this.addValidator({
message: (map, label) => `Expected ${label} to have a maximum size of \`${size}\`, got \`${map.size}\``,
validator: map => map.size <= size,
negatedMessage: (map, label) => `Expected ${label} to have a minimum size of \`${size + 1}\`, got \`${map.size}\``
});
}
/**
Test a Map to include all the provided keys. The keys are tested by identity, not structure.
@param keys - The keys that should be a key in the Map.
*/
hasKeys(...keys) {
return this.addValidator({
message: (_, label, missingKeys) => `Expected ${label} to have keys \`${JSON.stringify(missingKeys)}\``,
validator: map => has_items_1.default(map, keys)
});
}
/**
Test a Map to include any of the provided keys. The keys are tested by identity, not structure.
@param keys - The keys that could be a key in the Map.
*/
hasAnyKeys(...keys) {
return this.addValidator({
message: (_, label) => `Expected ${label} to have any key of \`${JSON.stringify(keys)}\``,
validator: map => keys.some(key => map.has(key))
});
}
/**
Test a Map to include all the provided values. The values are tested by identity, not structure.
@param values - The values that should be a value in the Map.
*/
hasValues(...values) {
return this.addValidator({
message: (_, label, missingValues) => `Expected ${label} to have values \`${JSON.stringify(missingValues)}\``,
validator: map => has_items_1.default(new Set(map.values()), values)
});
}
/**
Test a Map to include any of the provided values. The values are tested by identity, not structure.
@param values - The values that could be a value in the Map.
*/
hasAnyValues(...values) {
return this.addValidator({
message: (_, label) => `Expected ${label} to have any value of \`${JSON.stringify(values)}\``,
validator: map => {
const valueSet = new Set(map.values());
return values.some(key => valueSet.has(key));
}
});
}
/**
Test all the keys in the Map to match the provided predicate.
@param predicate - The predicate that should be applied against every key in the Map.
*/
keysOfType(predicate) {
return this.addValidator({
message: (_, label, error) => `(${label}) ${error}`,
validator: map => of_type_1.default(map.keys(), 'keys', predicate)
});
}
/**
Test all the values in the Map to match the provided predicate.
@param predicate - The predicate that should be applied against every value in the Map.
*/
valuesOfType(predicate) {
return this.addValidator({
message: (_, label, error) => `(${label}) ${error}`,
validator: map => of_type_1.default(map.values(), 'values', predicate)
});
}
/**
Test a Map to be empty.
*/
get empty() {
return this.addValidator({
message: (map, label) => `Expected ${label} to be empty, got \`${JSON.stringify([...map])}\``,
validator: map => map.size === 0
});
}
/**
Test a Map to be not empty.
*/
get nonEmpty() {
return this.addValidator({
message: (_, label) => `Expected ${label} to not be empty`,
validator: map => map.size > 0
});
}
/**
Test a Map to be deeply equal to the provided Map.
@param expected - Expected Map to match.
*/
deepEqual(expected) {
return this.addValidator({
message: (map, label) => `Expected ${label} to be deeply equal to \`${JSON.stringify([...expected])}\`, got \`${JSON.stringify([...map])}\``,
validator: map => isEqual(map, expected)
});
}
}
exports.MapPredicate = MapPredicate;
+98
View File
@@ -0,0 +1,98 @@
import { Predicate, PredicateOptions } from './predicate';
export declare class NumberPredicate extends Predicate<number> {
/**
@hidden
*/
constructor(options?: PredicateOptions);
/**
Test a number to be in a specified range.
@param start - Start of the range.
@param end - End of the range.
*/
inRange(start: number, end: number): this;
/**
Test a number to be greater than the provided value.
@param number - Minimum value.
*/
greaterThan(number: number): this;
/**
Test a number to be greater than or equal to the provided value.
@param number - Minimum value.
*/
greaterThanOrEqual(number: number): this;
/**
Test a number to be less than the provided value.
@param number - Maximum value.
*/
lessThan(number: number): this;
/**
Test a number to be less than or equal to the provided value.
@param number - Minimum value.
*/
lessThanOrEqual(number: number): this;
/**
Test a number to be equal to a specified number.
@param expected - Expected value to match.
*/
equal(expected: number): this;
/**
Test if a number is an element of the provided list.
@param list - List of possible values.
*/
oneOf(list: readonly number[]): this;
/**
Test a number to be an integer.
*/
get integer(): this;
/**
Test a number to be finite.
*/
get finite(): this;
/**
Test a number to be infinite.
*/
get infinite(): this;
/**
Test a number to be positive.
*/
get positive(): this;
/**
Test a number to be negative.
*/
get negative(): this;
/**
Test a number to be an integer or infinite.
*/
get integerOrInfinite(): this;
/**
Test a number to be in a valid range for a 8-bit unsigned integer.
*/
get uint8(): this;
/**
Test a number to be in a valid range for a 16-bit unsigned integer.
*/
get uint16(): this;
/**
Test a number to be in a valid range for a 32-bit unsigned integer.
*/
get uint32(): this;
/**
Test a number to be in a valid range for a 8-bit signed integer.
*/
get int8(): this;
/**
Test a number to be in a valid range for a 16-bit signed integer.
*/
get int16(): this;
/**
Test a number to be in a valid range for a 32-bit signed integer.
*/
get int32(): this;
}
+189
View File
@@ -0,0 +1,189 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NumberPredicate = void 0;
const is_1 = require("@sindresorhus/is");
const predicate_1 = require("./predicate");
class NumberPredicate extends predicate_1.Predicate {
/**
@hidden
*/
constructor(options) {
super('number', options);
}
/**
Test a number to be in a specified range.
@param start - Start of the range.
@param end - End of the range.
*/
inRange(start, end) {
return this.addValidator({
message: (value, label) => `Expected ${label} to be in range [${start}..${end}], got ${value}`,
validator: value => is_1.default.inRange(value, [start, end])
});
}
/**
Test a number to be greater than the provided value.
@param number - Minimum value.
*/
greaterThan(number) {
return this.addValidator({
message: (value, label) => `Expected ${label} to be greater than ${number}, got ${value}`,
validator: value => value > number
});
}
/**
Test a number to be greater than or equal to the provided value.
@param number - Minimum value.
*/
greaterThanOrEqual(number) {
return this.addValidator({
message: (value, label) => `Expected ${label} to be greater than or equal to ${number}, got ${value}`,
validator: value => value >= number
});
}
/**
Test a number to be less than the provided value.
@param number - Maximum value.
*/
lessThan(number) {
return this.addValidator({
message: (value, label) => `Expected ${label} to be less than ${number}, got ${value}`,
validator: value => value < number
});
}
/**
Test a number to be less than or equal to the provided value.
@param number - Minimum value.
*/
lessThanOrEqual(number) {
return this.addValidator({
message: (value, label) => `Expected ${label} to be less than or equal to ${number}, got ${value}`,
validator: value => value <= number
});
}
/**
Test a number to be equal to a specified number.
@param expected - Expected value to match.
*/
equal(expected) {
return this.addValidator({
message: (value, label) => `Expected ${label} to be equal to ${expected}, got ${value}`,
validator: value => value === expected
});
}
/**
Test if a number is an element of the provided list.
@param list - List of possible values.
*/
oneOf(list) {
return this.addValidator({
message: (value, label) => {
let printedList = JSON.stringify(list);
if (list.length > 10) {
const overflow = list.length - 10;
printedList = JSON.stringify(list.slice(0, 10)).replace(/]$/, `,…+${overflow} more]`);
}
return `Expected ${label} to be one of \`${printedList}\`, got ${value}`;
},
validator: value => list.includes(value)
});
}
/**
Test a number to be an integer.
*/
get integer() {
return this.addValidator({
message: (value, label) => `Expected ${label} to be an integer, got ${value}`,
validator: value => is_1.default.integer(value)
});
}
/**
Test a number to be finite.
*/
get finite() {
return this.addValidator({
message: (value, label) => `Expected ${label} to be finite, got ${value}`,
validator: value => !is_1.default.infinite(value)
});
}
/**
Test a number to be infinite.
*/
get infinite() {
return this.addValidator({
message: (value, label) => `Expected ${label} to be infinite, got ${value}`,
validator: value => is_1.default.infinite(value)
});
}
/**
Test a number to be positive.
*/
get positive() {
return this.addValidator({
message: (value, label) => `Expected ${label} to be positive, got ${value}`,
validator: value => value > 0
});
}
/**
Test a number to be negative.
*/
get negative() {
return this.addValidator({
message: (value, label) => `Expected ${label} to be negative, got ${value}`,
validator: value => value < 0
});
}
/**
Test a number to be an integer or infinite.
*/
get integerOrInfinite() {
return this.addValidator({
message: (value, label) => `Expected ${label} to be an integer or infinite, got ${value}`,
validator: value => is_1.default.integer(value) || is_1.default.infinite(value)
});
}
/**
Test a number to be in a valid range for a 8-bit unsigned integer.
*/
get uint8() {
return this.integer.inRange(0, 255);
}
/**
Test a number to be in a valid range for a 16-bit unsigned integer.
*/
get uint16() {
return this.integer.inRange(0, 65535);
}
/**
Test a number to be in a valid range for a 32-bit unsigned integer.
*/
get uint32() {
return this.integer.inRange(0, 4294967295);
}
/**
Test a number to be in a valid range for a 8-bit signed integer.
*/
get int8() {
return this.integer.inRange(-128, 127);
}
/**
Test a number to be in a valid range for a 16-bit signed integer.
*/
get int16() {
return this.integer.inRange(-32768, 32767);
}
/**
Test a number to be in a valid range for a 32-bit signed integer.
*/
get int32() {
return this.integer.inRange(-2147483648, 2147483647);
}
}
exports.NumberPredicate = NumberPredicate;
+97
View File
@@ -0,0 +1,97 @@
import { Shape, TypeOfShape } from '../utils/match-shape';
import { Predicate, PredicateOptions } from './predicate';
import { BasePredicate } from './base-predicate';
export { Shape };
export declare class ObjectPredicate<T extends object = object> extends Predicate<T> {
/**
@hidden
*/
constructor(options?: PredicateOptions);
/**
Test if an Object is a plain object.
*/
get plain(): this;
/**
Test an object to be empty.
*/
get empty(): this;
/**
Test an object to be not empty.
*/
get nonEmpty(): this;
/**
Test all the values in the object to match the provided predicate.
@param predicate - The predicate that should be applied against every value in the object.
*/
valuesOfType<T>(predicate: BasePredicate<T>): this;
/**
Test all the values in the object deeply to match the provided predicate.
@param predicate - The predicate that should be applied against every value in the object.
*/
deepValuesOfType<T>(predicate: Predicate<T>): this;
/**
Test an object to be deeply equal to the provided object.
@param expected - Expected object to match.
*/
deepEqual(expected: object): this;
/**
Test an object to be of a specific instance type.
@param instance - The expected instance type of the object.
*/
instanceOf(instance: Function): this;
/**
Test an object to include all the provided keys. You can use [dot-notation](https://github.com/sindresorhus/dot-prop) in a key to access nested properties.
@param keys - The keys that should be present in the object.
*/
hasKeys(...keys: readonly string[]): this;
/**
Test an object to include any of the provided keys. You can use [dot-notation](https://github.com/sindresorhus/dot-prop) in a key to access nested properties.
@param keys - The keys that could be a key in the object.
*/
hasAnyKeys(...keys: readonly string[]): this;
/**
Test an object to match the `shape` partially. This means that it ignores unexpected properties. The shape comparison is deep.
The shape is an object which describes how the tested object should look like. The keys are the same as the source object and the values are predicates.
@param shape - Shape to test the object against.
@example
```
import ow from 'ow';
const object = {
unicorn: '🦄',
rainbow: '🌈'
};
ow(object, ow.object.partialShape({
unicorn: ow.string
}));
```
*/
partialShape<S extends Shape = Shape>(shape: S): ObjectPredicate<TypeOfShape<S>>;
/**
Test an object to match the `shape` exactly. This means that will fail if it comes across unexpected properties. The shape comparison is deep.
The shape is an object which describes how the tested object should look like. The keys are the same as the source object and the values are predicates.
@param shape - Shape to test the object against.
@example
```
import ow from 'ow';
ow({unicorn: '🦄'}, ow.object.exactShape({
unicorn: ow.string
}));
```
*/
exactShape<S extends Shape = Shape>(shape: S): ObjectPredicate<TypeOfShape<S>>;
}
+174
View File
@@ -0,0 +1,174 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ObjectPredicate = void 0;
const is_1 = require("@sindresorhus/is");
const dotProp = require("dot-prop");
const isEqual = require("lodash.isequal");
const has_items_1 = require("../utils/has-items");
const of_type_1 = require("../utils/of-type");
const of_type_deep_1 = require("../utils/of-type-deep");
const match_shape_1 = require("../utils/match-shape");
const predicate_1 = require("./predicate");
class ObjectPredicate extends predicate_1.Predicate {
/**
@hidden
*/
constructor(options) {
super('object', options);
}
/**
Test if an Object is a plain object.
*/
get plain() {
return this.addValidator({
message: (_, label) => `Expected ${label} to be a plain object`,
validator: object => is_1.default.plainObject(object)
});
}
/**
Test an object to be empty.
*/
get empty() {
return this.addValidator({
message: (object, label) => `Expected ${label} to be empty, got \`${JSON.stringify(object)}\``,
validator: object => Object.keys(object).length === 0
});
}
/**
Test an object to be not empty.
*/
get nonEmpty() {
return this.addValidator({
message: (_, label) => `Expected ${label} to not be empty`,
validator: object => Object.keys(object).length > 0
});
}
/**
Test all the values in the object to match the provided predicate.
@param predicate - The predicate that should be applied against every value in the object.
*/
valuesOfType(predicate) {
return this.addValidator({
message: (_, label, error) => `(${label}) ${error}`,
validator: object => of_type_1.default(Object.values(object), 'values', predicate)
});
}
/**
Test all the values in the object deeply to match the provided predicate.
@param predicate - The predicate that should be applied against every value in the object.
*/
deepValuesOfType(predicate) {
return this.addValidator({
message: (_, label, error) => `(${label}) ${error}`,
validator: object => of_type_deep_1.default(object, predicate)
});
}
/**
Test an object to be deeply equal to the provided object.
@param expected - Expected object to match.
*/
deepEqual(expected) {
return this.addValidator({
message: (object, label) => `Expected ${label} to be deeply equal to \`${JSON.stringify(expected)}\`, got \`${JSON.stringify(object)}\``,
validator: object => isEqual(object, expected)
});
}
/**
Test an object to be of a specific instance type.
@param instance - The expected instance type of the object.
*/
instanceOf(instance) {
return this.addValidator({
message: (object, label) => {
var _a;
let { name } = (_a = object === null || object === void 0 ? void 0 : object.constructor) !== null && _a !== void 0 ? _a : {};
if (!name || name === 'Object') {
name = JSON.stringify(object);
}
return `Expected ${label} \`${name}\` to be of type \`${instance.name}\``;
},
validator: object => object instanceof instance
});
}
/**
Test an object to include all the provided keys. You can use [dot-notation](https://github.com/sindresorhus/dot-prop) in a key to access nested properties.
@param keys - The keys that should be present in the object.
*/
hasKeys(...keys) {
return this.addValidator({
message: (_, label, missingKeys) => `Expected ${label} to have keys \`${JSON.stringify(missingKeys)}\``,
validator: object => has_items_1.default({
has: item => dotProp.has(object, item)
}, keys)
});
}
/**
Test an object to include any of the provided keys. You can use [dot-notation](https://github.com/sindresorhus/dot-prop) in a key to access nested properties.
@param keys - The keys that could be a key in the object.
*/
hasAnyKeys(...keys) {
return this.addValidator({
message: (_, label) => `Expected ${label} to have any key of \`${JSON.stringify(keys)}\``,
validator: object => keys.some(key => dotProp.has(object, key))
});
}
/**
Test an object to match the `shape` partially. This means that it ignores unexpected properties. The shape comparison is deep.
The shape is an object which describes how the tested object should look like. The keys are the same as the source object and the values are predicates.
@param shape - Shape to test the object against.
@example
```
import ow from 'ow';
const object = {
unicorn: '🦄',
rainbow: '🌈'
};
ow(object, ow.object.partialShape({
unicorn: ow.string
}));
```
*/
partialShape(shape) {
return this.addValidator({
// TODO: Improve this when message handling becomes smarter
message: (_, label, message) => `${message.replace('Expected', 'Expected property')} in ${label}`,
validator: object => match_shape_1.partial(object, shape)
});
}
/**
Test an object to match the `shape` exactly. This means that will fail if it comes across unexpected properties. The shape comparison is deep.
The shape is an object which describes how the tested object should look like. The keys are the same as the source object and the values are predicates.
@param shape - Shape to test the object against.
@example
```
import ow from 'ow';
ow({unicorn: '🦄'}, ow.object.exactShape({
unicorn: ow.string
}));
```
*/
exactShape(shape) {
// TODO [typescript@>=5] If higher-kinded types are supported natively by typescript, refactor `addValidator` to use them to avoid the usage of `any`. Otherwise, bump or remove this TODO.
return this.addValidator({
// TODO: Improve this when message handling becomes smarter
message: (_, label, message) => `${message.replace('Expected', 'Expected property')} in ${label}`,
validator: object => match_shape_1.exact(object, shape)
});
}
}
exports.ObjectPredicate = ObjectPredicate;
+107
View File
@@ -0,0 +1,107 @@
import { BasePredicate, testSymbol } from './base-predicate';
import { Main } from '..';
/**
Function executed when the provided validation fails.
@param value - The tested value.
@param label - Label of the tested value.
@returns {string} - The actual error message.
*/
export declare type ValidatorMessageBuilder<T> = (value: T, label?: string) => string;
/**
@hidden
*/
export interface Validator<T> {
message(value: T, label?: string, result?: any): string;
validator(value: T): unknown;
/**
Provide custom message used by `not` operator.
When absent, the return value of `message()` is used and 'not' is inserted after the first 'to', e.g. `Expected 'smth' to be empty` -> `Expected 'smth' to not be empty`.
*/
negatedMessage?(value: T, label: string): string;
}
/**
@hidden
*/
export interface PredicateOptions {
optional?: boolean;
}
/**
@hidden
*/
export interface Context<T = unknown> extends PredicateOptions {
validators: Array<Validator<T>>;
}
/**
@hidden
*/
export declare const validatorSymbol: unique symbol;
export declare type CustomValidator<T> = (value: T) => {
/**
Should be `true` if the validation is correct.
*/
validator: boolean;
/**
The error message which should be shown if the `validator` is `false`. Or a error function which returns the error message and accepts the label as first argument.
*/
message: string | ((label: string) => string);
};
/**
@hidden
*/
export declare class Predicate<T = unknown> implements BasePredicate<T> {
private readonly type;
private readonly options;
private readonly context;
constructor(type: string, options?: PredicateOptions);
/**
@hidden
*/
[testSymbol](value: T, main: Main, label: string | Function, idLabel: boolean): asserts value is T;
/**
@hidden
*/
get [validatorSymbol](): Array<Validator<T>>;
/**
Invert the following validators.
*/
get not(): this;
/**
Test if the value matches a custom validation function. The validation function should return an object containing a `validator` and `message`. If the `validator` is `false`, the validation fails and the `message` will be used as error message. If the `message` is a function, the function is invoked with the `label` as argument to let you further customize the error message.
@param customValidator - Custom validation function.
*/
validate(customValidator: CustomValidator<T>): this;
/**
Test if the value matches a custom validation function. The validation function should return `true` if the value passes the function. If the function either returns `false` or a string, the function fails and the string will be used as error message.
@param validator - Validation function.
*/
is(validator: (value: T) => boolean | string): this;
/**
Provide a new error message to be thrown when the validation fails.
@param newMessage - Either a string containing the new message or a function returning the new message.
@example
```
ow('🌈', 'unicorn', ow.string.equals('🦄').message('Expected unicorn, got rainbow'));
//=> ArgumentError: Expected unicorn, got rainbow
```
@example
```
ow('🌈', ow.string.minLength(5).message((value, label) => `Expected ${label}, to have a minimum length of 5, got \`${value}\``));
//=> ArgumentError: Expected string, to be have a minimum length of 5, got `🌈`
```
*/
message(newMessage: string | ValidatorMessageBuilder<T>): this;
/**
Register a new validator.
@param validator - Validator to register.
*/
addValidator(validator: Validator<T>): this;
}
+182
View File
@@ -0,0 +1,182 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Predicate = exports.validatorSymbol = void 0;
const is_1 = require("@sindresorhus/is");
const argument_error_1 = require("../argument-error");
const not_1 = require("../operators/not");
const base_predicate_1 = require("./base-predicate");
const generate_argument_error_message_1 = require("../utils/generate-argument-error-message");
/**
@hidden
*/
exports.validatorSymbol = Symbol('validators');
/**
@hidden
*/
class Predicate {
constructor(type, options = {}) {
Object.defineProperty(this, "type", {
enumerable: true,
configurable: true,
writable: true,
value: type
});
Object.defineProperty(this, "options", {
enumerable: true,
configurable: true,
writable: true,
value: options
});
Object.defineProperty(this, "context", {
enumerable: true,
configurable: true,
writable: true,
value: {
validators: []
}
});
this.context = {
...this.context,
...this.options
};
const typeString = this.type.charAt(0).toLowerCase() + this.type.slice(1);
this.addValidator({
message: (value, label) => {
// We do not include type in this label as we do for other messages, because it would be redundant.
const label_ = label === null || label === void 0 ? void 0 : label.slice(this.type.length + 1);
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
return `Expected ${label_ || 'argument'} to be of type \`${this.type}\` but received type \`${is_1.default(value)}\``;
},
validator: value => is_1.default[typeString](value)
});
}
/**
@hidden
*/
[base_predicate_1.testSymbol](value, main, label, idLabel) {
// Create a map of labels -> received errors.
const errors = new Map();
for (const { validator, message } of this.context.validators) {
if (this.options.optional === true && value === undefined) {
continue;
}
let result;
try {
result = validator(value);
}
catch (error) {
// Any errors caught means validators couldn't process the input.
result = error;
}
if (result === true) {
continue;
}
const label2 = is_1.default.function_(label) ? label() : label;
const labelWithTick = (label2 && idLabel) ? `\`${label2}\`` : label2;
const label_ = labelWithTick ?
`${this.type} ${labelWithTick}` :
this.type;
const mapKey = label2 || this.type;
// Get the current errors encountered for this label.
const currentErrors = errors.get(mapKey);
// Pre-generate the error message that will be reported to the user.
const errorMessage = message(value, label_, result);
// If we already have any errors for this label.
if (currentErrors) {
// If we don't already have this error logged, add it.
currentErrors.add(errorMessage);
}
else {
// Set this label and error in the full map.
errors.set(mapKey, new Set([errorMessage]));
}
}
// If we have any errors to report, throw.
if (errors.size > 0) {
// Generate the `error.message` property.
const message = generate_argument_error_message_1.generateArgumentErrorMessage(errors);
throw new argument_error_1.ArgumentError(message, main, errors);
}
}
/**
@hidden
*/
get [exports.validatorSymbol]() {
return this.context.validators;
}
/**
Invert the following validators.
*/
get not() {
return not_1.not(this);
}
/**
Test if the value matches a custom validation function. The validation function should return an object containing a `validator` and `message`. If the `validator` is `false`, the validation fails and the `message` will be used as error message. If the `message` is a function, the function is invoked with the `label` as argument to let you further customize the error message.
@param customValidator - Custom validation function.
*/
validate(customValidator) {
return this.addValidator({
message: (_, label, error) => typeof error === 'string' ?
`(${label}) ${error}` :
error(label),
validator: value => {
const { message, validator } = customValidator(value);
if (validator) {
return true;
}
return message;
}
});
}
/**
Test if the value matches a custom validation function. The validation function should return `true` if the value passes the function. If the function either returns `false` or a string, the function fails and the string will be used as error message.
@param validator - Validation function.
*/
is(validator) {
return this.addValidator({
message: (value, label, error) => (error ?
`(${label}) ${error}` :
`Expected ${label} \`${value}\` to pass custom validation function`),
validator
});
}
/**
Provide a new error message to be thrown when the validation fails.
@param newMessage - Either a string containing the new message or a function returning the new message.
@example
```
ow('🌈', 'unicorn', ow.string.equals('🦄').message('Expected unicorn, got rainbow'));
//=> ArgumentError: Expected unicorn, got rainbow
```
@example
```
ow('🌈', ow.string.minLength(5).message((value, label) => `Expected ${label}, to have a minimum length of 5, got \`${value}\``));
//=> ArgumentError: Expected string, to be have a minimum length of 5, got `🌈`
```
*/
message(newMessage) {
const { validators } = this.context;
validators[validators.length - 1].message = (value, label) => {
if (typeof newMessage === 'function') {
return newMessage(value, label);
}
return newMessage;
};
return this;
}
/**
Register a new validator.
@param validator - Validator to register.
*/
addValidator(validator) {
this.context.validators.push(validator);
return this;
}
}
exports.Predicate = Predicate;
+57
View File
@@ -0,0 +1,57 @@
import { Predicate, PredicateOptions } from './predicate';
export declare class SetPredicate<T = any> extends Predicate<Set<T>> {
/**
@hidden
*/
constructor(options?: PredicateOptions);
/**
Test a Set to have a specific size.
@param size - The size of the Set.
*/
size(size: number): this;
/**
Test a Set to have a minimum size.
@param size - The minimum size of the Set.
*/
minSize(size: number): this;
/**
Test a Set to have a maximum size.
@param size - The maximum size of the Set.
*/
maxSize(size: number): this;
/**
Test a Set to include all the provided items. The items are tested by identity, not structure.
@param items - The items that should be a item in the Set.
*/
has(...items: readonly T[]): this;
/**
Test a Set to include any of the provided items. The items are tested by identity, not structure.
@param items - The items that could be a item in the Set.
*/
hasAny(...items: readonly T[]): this;
/**
Test all the items in the Set to match the provided predicate.
@param predicate - The predicate that should be applied against every item in the Set.
*/
ofType(predicate: Predicate<T>): this;
/**
Test a Set to be empty.
*/
get empty(): this;
/**
Test a Set to be not empty.
*/
get nonEmpty(): this;
/**
Test a Set to be deeply equal to the provided Set.
@param expected - Expected Set to match.
*/
deepEqual(expected: Set<T>): this;
}
+113
View File
@@ -0,0 +1,113 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SetPredicate = void 0;
const isEqual = require("lodash.isequal");
const has_items_1 = require("../utils/has-items");
const of_type_1 = require("../utils/of-type");
const predicate_1 = require("./predicate");
class SetPredicate extends predicate_1.Predicate {
/**
@hidden
*/
constructor(options) {
super('Set', options);
}
/**
Test a Set to have a specific size.
@param size - The size of the Set.
*/
size(size) {
return this.addValidator({
message: (set, label) => `Expected ${label} to have size \`${size}\`, got \`${set.size}\``,
validator: set => set.size === size
});
}
/**
Test a Set to have a minimum size.
@param size - The minimum size of the Set.
*/
minSize(size) {
return this.addValidator({
message: (set, label) => `Expected ${label} to have a minimum size of \`${size}\`, got \`${set.size}\``,
validator: set => set.size >= size,
negatedMessage: (set, label) => `Expected ${label} to have a maximum size of \`${size - 1}\`, got \`${set.size}\``
});
}
/**
Test a Set to have a maximum size.
@param size - The maximum size of the Set.
*/
maxSize(size) {
return this.addValidator({
message: (set, label) => `Expected ${label} to have a maximum size of \`${size}\`, got \`${set.size}\``,
validator: set => set.size <= size,
negatedMessage: (set, label) => `Expected ${label} to have a minimum size of \`${size + 1}\`, got \`${set.size}\``
});
}
/**
Test a Set to include all the provided items. The items are tested by identity, not structure.
@param items - The items that should be a item in the Set.
*/
has(...items) {
return this.addValidator({
message: (_, label, missingItems) => `Expected ${label} to have items \`${JSON.stringify(missingItems)}\``,
validator: set => has_items_1.default(set, items)
});
}
/**
Test a Set to include any of the provided items. The items are tested by identity, not structure.
@param items - The items that could be a item in the Set.
*/
hasAny(...items) {
return this.addValidator({
message: (_, label) => `Expected ${label} to have any item of \`${JSON.stringify(items)}\``,
validator: set => items.some(item => set.has(item))
});
}
/**
Test all the items in the Set to match the provided predicate.
@param predicate - The predicate that should be applied against every item in the Set.
*/
ofType(predicate) {
return this.addValidator({
message: (_, label, error) => `(${label}) ${error}`,
validator: set => of_type_1.default(set, 'values', predicate)
});
}
/**
Test a Set to be empty.
*/
get empty() {
return this.addValidator({
message: (set, label) => `Expected ${label} to be empty, got \`${JSON.stringify([...set])}\``,
validator: set => set.size === 0
});
}
/**
Test a Set to be not empty.
*/
get nonEmpty() {
return this.addValidator({
message: (_, label) => `Expected ${label} to not be empty`,
validator: set => set.size > 0
});
}
/**
Test a Set to be deeply equal to the provided Set.
@param expected - Expected Set to match.
*/
deepEqual(expected) {
return this.addValidator({
message: (set, label) => `Expected ${label} to be deeply equal to \`${JSON.stringify([...expected])}\`, got \`${JSON.stringify([...set])}\``,
validator: set => isEqual(set, expected)
});
}
}
exports.SetPredicate = SetPredicate;
+97
View File
@@ -0,0 +1,97 @@
import { Predicate, PredicateOptions } from './predicate';
export declare class StringPredicate extends Predicate<string> {
/**
@hidden
*/
constructor(options?: PredicateOptions);
/**
Test a string to have a specific length.
@param length - The length of the string.
*/
length(length: number): this;
/**
Test a string to have a minimum length.
@param length - The minimum length of the string.
*/
minLength(length: number): this;
/**
Test a string to have a maximum length.
@param length - The maximum length of the string.
*/
maxLength(length: number): this;
/**
Test a string against a regular expression.
@param regex - The regular expression to match the value with.
*/
matches(regex: RegExp): this;
/**
Test a string to start with a specific value.
@param searchString - The value that should be the start of the string.
*/
startsWith(searchString: string): this;
/**
Test a string to end with a specific value.
@param searchString - The value that should be the end of the string.
*/
endsWith(searchString: string): this;
/**
Test a string to include a specific value.
@param searchString - The value that should be included in the string.
*/
includes(searchString: string): this;
/**
Test if the string is an element of the provided list.
@param list - List of possible values.
*/
oneOf(list: readonly string[]): this;
/**
Test a string to be empty.
*/
get empty(): this;
/**
Test a string to be not empty.
*/
get nonEmpty(): this;
/**
Test a string to be equal to a specified string.
@param expected - Expected value to match.
*/
equals(expected: string): this;
/**
Test a string to be alphanumeric.
*/
get alphanumeric(): this;
/**
Test a string to be alphabetical.
*/
get alphabetical(): this;
/**
Test a string to be numeric.
*/
get numeric(): this;
/**
Test a string to be a valid date.
*/
get date(): this;
/**
Test a non-empty string to be lowercase. Matching both alphabetical & numbers.
*/
get lowercase(): this;
/**
Test a non-empty string to be uppercase. Matching both alphabetical & numbers.
*/
get uppercase(): this;
/**
Test a string to be a valid URL.
*/
get url(): this;
}
+204
View File
@@ -0,0 +1,204 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StringPredicate = void 0;
const is_1 = require("@sindresorhus/is");
const valiDate = require("vali-date");
const predicate_1 = require("./predicate");
class StringPredicate extends predicate_1.Predicate {
/**
@hidden
*/
constructor(options) {
super('string', options);
}
/**
Test a string to have a specific length.
@param length - The length of the string.
*/
length(length) {
return this.addValidator({
message: (value, label) => `Expected ${label} to have length \`${length}\`, got \`${value}\``,
validator: value => value.length === length
});
}
/**
Test a string to have a minimum length.
@param length - The minimum length of the string.
*/
minLength(length) {
return this.addValidator({
message: (value, label) => `Expected ${label} to have a minimum length of \`${length}\`, got \`${value}\``,
validator: value => value.length >= length,
negatedMessage: (value, label) => `Expected ${label} to have a maximum length of \`${length - 1}\`, got \`${value}\``
});
}
/**
Test a string to have a maximum length.
@param length - The maximum length of the string.
*/
maxLength(length) {
return this.addValidator({
message: (value, label) => `Expected ${label} to have a maximum length of \`${length}\`, got \`${value}\``,
validator: value => value.length <= length,
negatedMessage: (value, label) => `Expected ${label} to have a minimum length of \`${length + 1}\`, got \`${value}\``
});
}
/**
Test a string against a regular expression.
@param regex - The regular expression to match the value with.
*/
matches(regex) {
return this.addValidator({
message: (value, label) => `Expected ${label} to match \`${regex}\`, got \`${value}\``,
validator: value => regex.test(value)
});
}
/**
Test a string to start with a specific value.
@param searchString - The value that should be the start of the string.
*/
startsWith(searchString) {
return this.addValidator({
message: (value, label) => `Expected ${label} to start with \`${searchString}\`, got \`${value}\``,
validator: value => value.startsWith(searchString)
});
}
/**
Test a string to end with a specific value.
@param searchString - The value that should be the end of the string.
*/
endsWith(searchString) {
return this.addValidator({
message: (value, label) => `Expected ${label} to end with \`${searchString}\`, got \`${value}\``,
validator: value => value.endsWith(searchString)
});
}
/**
Test a string to include a specific value.
@param searchString - The value that should be included in the string.
*/
includes(searchString) {
return this.addValidator({
message: (value, label) => `Expected ${label} to include \`${searchString}\`, got \`${value}\``,
validator: value => value.includes(searchString)
});
}
/**
Test if the string is an element of the provided list.
@param list - List of possible values.
*/
oneOf(list) {
return this.addValidator({
message: (value, label) => {
let printedList = JSON.stringify(list);
if (list.length > 10) {
const overflow = list.length - 10;
printedList = JSON.stringify(list.slice(0, 10)).replace(/]$/, `,…+${overflow} more]`);
}
return `Expected ${label} to be one of \`${printedList}\`, got \`${value}\``;
},
validator: value => list.includes(value)
});
}
/**
Test a string to be empty.
*/
get empty() {
return this.addValidator({
message: (value, label) => `Expected ${label} to be empty, got \`${value}\``,
validator: value => value === ''
});
}
/**
Test a string to be not empty.
*/
get nonEmpty() {
return this.addValidator({
message: (_, label) => `Expected ${label} to not be empty`,
validator: value => value !== ''
});
}
/**
Test a string to be equal to a specified string.
@param expected - Expected value to match.
*/
equals(expected) {
return this.addValidator({
message: (value, label) => `Expected ${label} to be equal to \`${expected}\`, got \`${value}\``,
validator: value => value === expected
});
}
/**
Test a string to be alphanumeric.
*/
get alphanumeric() {
return this.addValidator({
message: (value, label) => `Expected ${label} to be alphanumeric, got \`${value}\``,
validator: value => /^[a-z\d]+$/i.test(value)
});
}
/**
Test a string to be alphabetical.
*/
get alphabetical() {
return this.addValidator({
message: (value, label) => `Expected ${label} to be alphabetical, got \`${value}\``,
validator: value => /^[a-z]+$/gi.test(value)
});
}
/**
Test a string to be numeric.
*/
get numeric() {
return this.addValidator({
message: (value, label) => `Expected ${label} to be numeric, got \`${value}\``,
validator: value => /^[+-]?\d+$/i.test(value)
});
}
/**
Test a string to be a valid date.
*/
get date() {
return this.addValidator({
message: (value, label) => `Expected ${label} to be a date, got \`${value}\``,
validator: valiDate
});
}
/**
Test a non-empty string to be lowercase. Matching both alphabetical & numbers.
*/
get lowercase() {
return this.addValidator({
message: (value, label) => `Expected ${label} to be lowercase, got \`${value}\``,
validator: value => value.trim() !== '' && value === value.toLowerCase()
});
}
/**
Test a non-empty string to be uppercase. Matching both alphabetical & numbers.
*/
get uppercase() {
return this.addValidator({
message: (value, label) => `Expected ${label} to be uppercase, got \`${value}\``,
validator: value => value.trim() !== '' && value === value.toUpperCase()
});
}
/**
Test a string to be a valid URL.
*/
get url() {
return this.addValidator({
message: (value, label) => `Expected ${label} to be a URL, got \`${value}\``,
validator: is_1.default.urlString
});
}
}
exports.StringPredicate = StringPredicate;
+40
View File
@@ -0,0 +1,40 @@
import { TypedArray } from 'type-fest';
import { Predicate } from './predicate';
export declare class TypedArrayPredicate<T extends TypedArray> extends Predicate<T> {
/**
Test a typed array to have a specific byte length.
@param byteLength - The byte length of the typed array.
*/
byteLength(byteLength: number): this;
/**
Test a typed array to have a minimum byte length.
@param byteLength - The minimum byte length of the typed array.
*/
minByteLength(byteLength: number): this;
/**
Test a typed array to have a minimum byte length.
@param length - The minimum byte length of the typed array.
*/
maxByteLength(byteLength: number): this;
/**
Test a typed array to have a specific length.
@param length - The length of the typed array.
*/
length(length: number): this;
/**
Test a typed array to have a minimum length.
@param length - The minimum length of the typed array.
*/
minLength(length: number): this;
/**
Test a typed array to have a maximum length.
@param length - The maximum length of the typed array.
*/
maxLength(length: number): this;
}
+77
View File
@@ -0,0 +1,77 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TypedArrayPredicate = void 0;
const predicate_1 = require("./predicate");
class TypedArrayPredicate extends predicate_1.Predicate {
/**
Test a typed array to have a specific byte length.
@param byteLength - The byte length of the typed array.
*/
byteLength(byteLength) {
return this.addValidator({
message: (value, label) => `Expected ${label} to have byte length of \`${byteLength}\`, got \`${value.byteLength}\``,
validator: value => value.byteLength === byteLength
});
}
/**
Test a typed array to have a minimum byte length.
@param byteLength - The minimum byte length of the typed array.
*/
minByteLength(byteLength) {
return this.addValidator({
message: (value, label) => `Expected ${label} to have a minimum byte length of \`${byteLength}\`, got \`${value.byteLength}\``,
validator: value => value.byteLength >= byteLength,
negatedMessage: (value, label) => `Expected ${label} to have a maximum byte length of \`${byteLength - 1}\`, got \`${value.byteLength}\``
});
}
/**
Test a typed array to have a minimum byte length.
@param length - The minimum byte length of the typed array.
*/
maxByteLength(byteLength) {
return this.addValidator({
message: (value, label) => `Expected ${label} to have a maximum byte length of \`${byteLength}\`, got \`${value.byteLength}\``,
validator: value => value.byteLength <= byteLength,
negatedMessage: (value, label) => `Expected ${label} to have a minimum byte length of \`${byteLength + 1}\`, got \`${value.byteLength}\``
});
}
/**
Test a typed array to have a specific length.
@param length - The length of the typed array.
*/
length(length) {
return this.addValidator({
message: (value, label) => `Expected ${label} to have length \`${length}\`, got \`${value.length}\``,
validator: value => value.length === length
});
}
/**
Test a typed array to have a minimum length.
@param length - The minimum length of the typed array.
*/
minLength(length) {
return this.addValidator({
message: (value, label) => `Expected ${label} to have a minimum length of \`${length}\`, got \`${value.length}\``,
validator: value => value.length >= length,
negatedMessage: (value, label) => `Expected ${label} to have a maximum length of \`${length - 1}\`, got \`${value.length}\``
});
}
/**
Test a typed array to have a maximum length.
@param length - The maximum length of the typed array.
*/
maxLength(length) {
return this.addValidator({
message: (value, label) => `Expected ${label} to have a maximum length of \`${length}\`, got \`${value.length}\``,
validator: value => value.length <= length,
negatedMessage: (value, label) => `Expected ${label} to have a minimum length of \`${length + 1}\`, got \`${value.length}\``
});
}
}
exports.TypedArrayPredicate = TypedArrayPredicate;
+19
View File
@@ -0,0 +1,19 @@
import { Predicate, PredicateOptions } from './predicate';
export declare class WeakMapPredicate<KeyType extends object = object> extends Predicate<WeakMap<KeyType, unknown>> {
/**
@hidden
*/
constructor(options?: PredicateOptions);
/**
Test a WeakMap to include all the provided keys. The keys are tested by identity, not structure.
@param keys - The keys that should be a key in the WeakMap.
*/
hasKeys(...keys: readonly KeyType[]): this;
/**
Test a WeakMap to include any of the provided keys. The keys are tested by identity, not structure.
@param keys - The keys that could be a key in the WeakMap.
*/
hasAnyKeys(...keys: readonly KeyType[]): this;
}
+36
View File
@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WeakMapPredicate = void 0;
const has_items_1 = require("../utils/has-items");
const predicate_1 = require("./predicate");
class WeakMapPredicate extends predicate_1.Predicate {
/**
@hidden
*/
constructor(options) {
super('WeakMap', options);
}
/**
Test a WeakMap to include all the provided keys. The keys are tested by identity, not structure.
@param keys - The keys that should be a key in the WeakMap.
*/
hasKeys(...keys) {
return this.addValidator({
message: (_, label, missingKeys) => `Expected ${label} to have keys \`${JSON.stringify(missingKeys)}\``,
validator: map => has_items_1.default(map, keys)
});
}
/**
Test a WeakMap to include any of the provided keys. The keys are tested by identity, not structure.
@param keys - The keys that could be a key in the WeakMap.
*/
hasAnyKeys(...keys) {
return this.addValidator({
message: (_, label) => `Expected ${label} to have any key of \`${JSON.stringify(keys)}\``,
validator: map => keys.some(key => map.has(key))
});
}
}
exports.WeakMapPredicate = WeakMapPredicate;
+19
View File
@@ -0,0 +1,19 @@
import { Predicate, PredicateOptions } from './predicate';
export declare class WeakSetPredicate<T extends object = object> extends Predicate<WeakSet<T>> {
/**
@hidden
*/
constructor(options?: PredicateOptions);
/**
Test a WeakSet to include all the provided items. The items are tested by identity, not structure.
@param items - The items that should be a item in the WeakSet.
*/
has(...items: readonly T[]): this;
/**
Test a WeakSet to include any of the provided items. The items are tested by identity, not structure.
@param items - The items that could be a item in the WeakSet.
*/
hasAny(...items: readonly T[]): this;
}
+36
View File
@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WeakSetPredicate = void 0;
const has_items_1 = require("../utils/has-items");
const predicate_1 = require("./predicate");
class WeakSetPredicate extends predicate_1.Predicate {
/**
@hidden
*/
constructor(options) {
super('WeakSet', options);
}
/**
Test a WeakSet to include all the provided items. The items are tested by identity, not structure.
@param items - The items that should be a item in the WeakSet.
*/
has(...items) {
return this.addValidator({
message: (_, label, missingItems) => `Expected ${label} to have items \`${JSON.stringify(missingItems)}\``,
validator: set => has_items_1.default(set, items)
});
}
/**
Test a WeakSet to include any of the provided items. The items are tested by identity, not structure.
@param items - The items that could be a item in the WeakSet.
*/
hasAny(...items) {
return this.addValidator({
message: (_, label) => `Expected ${label} to have any item of \`${JSON.stringify(items)}\``,
validator: set => items.some(item => set.has(item))
});
}
}
exports.WeakSetPredicate = WeakSetPredicate;