Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 32 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ $ npm run bench
```

# Table of contents
- [Key features](#key-features)

- [fastest-validator ![NPM version](https://www.npmjs.com/package/fastest-validator) [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=The%20fastest%20JS%20validator%20library%20for%20NodeJS&url=https://github.com/icebob/fastest-validator&via=Icebobcsi&hashtags=nodejs,javascript)](#fastest-validator-img-src%22httpswwwnpmjscompackagefastest-validator%22-alt%22npm-version%22-img-src%22httpsimgshieldsiotwitterurlhttpshieldsiosvgstylesocial%22-alt%22tweet%22)
- [Key features](#key-features)
- [How fast?](#how-fast)
- [Table of contents](#table-of-contents)
- [Installation](#installation)
Expand All @@ -70,29 +72,31 @@ $ npm run bench
- [Properties](#properties)
- [`boolean`](#boolean)
- [Properties](#properties-1)
- [`date`](#date)
- [`class`](#class)
- [Properties](#properties-2)
- [`email`](#email)
- [`date`](#date)
- [Properties](#properties-3)
- [`enum`](#enum)
- [`email`](#email)
- [Properties](#properties-4)
- [`equal`](#equal)
- [`enum`](#enum)
- [Properties](#properties-5)
- [`forbidden`](#forbidden)
- [`equal`](#equal)
- [Properties](#properties-6)
- [`forbidden`](#forbidden)
- [Properties](#properties-7)
- [`function`](#function)
- [`luhn`](#luhn)
- [`mac`](#mac)
- [`multi`](#multi)
- [`number`](#number)
- [Properties](#properties-7)
- [`object`](#object)
- [Properties](#properties-8)
- [`string`](#string)
- [`object`](#object)
- [Properties](#properties-9)
- [`string`](#string)
- [Properties](#properties-10)
- [`url`](#url)
- [`uuid`](#uuid)
- [Properties](#properties-10)
- [Properties](#properties-11)
- [Custom validator](#custom-validator)
- [Custom validation for built-in rules](#custom-validation-for-built-in-rules)
- [Custom error messages (l10n)](#custom-error-messages-l10n)
Expand Down Expand Up @@ -460,6 +464,24 @@ v.validate({ status: "true" }, {
}); // Valid
```

## `class`
This is a `Class` validator to check the value is an instance of a Class.

```js
const schema = {
rawData: { type: "class", instanceOf: Buffer }
}

v.validate({ rawData: Buffer.from([1, 2, 3]) }, schema); // Valid
v.validate({ rawData: 100 }, schema); // Fail
```

### Properties
Property | Default | Description
-------- | -------- | -----------
`instanceOf` | `null` | Checked Class.


## `date`
This is a `Date` validator.

Expand Down
4 changes: 3 additions & 1 deletion examples/full.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const schema = {
phone: { type: "string", length: 15, custom: v => v.startsWith("+") ? true : [{ type: "phoneNumber" }] },
action: "function",
created: "date",
raw: { type: "class", instanceOf: Buffer },
now: { type: "date", convert: true }
};

Expand Down Expand Up @@ -91,7 +92,8 @@ const obj = {
phone: "+36-70-123-4567",
action: () => {},
created: new Date(),
now: Date.now()
now: Date.now(),
raw: Buffer.from([1,2,3])
};

const res = v.validate(obj, schema);
Expand Down
20 changes: 19 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ declare module 'fastest-validator' {
'any'
| 'array'
| 'boolean'
| 'class'
| 'custom'
| 'date'
| 'email'
Expand Down Expand Up @@ -90,6 +91,21 @@ declare module 'fastest-validator' {
convert?: boolean;
}

/**
* Validation schema definition for "class" built-in validator
* @see https://github.com/icebob/fastest-validator#class
*/
interface RuleClass<T = any> extends RuleCustom {
/**
* Name of built-in validator
*/
type: 'class';
/**
* Checked Class
*/
instanceOf?: T;
}

/**
* Validation schema definition for "date" built-in validator
* @see https://github.com/icebob/fastest-validator#date
Expand Down Expand Up @@ -662,6 +678,7 @@ declare module 'fastest-validator' {
RuleAny
| RuleArray
| RuleBoolean
| RuleClass
| RuleDate
| RuleEmail
| RuleEqual
Expand Down Expand Up @@ -745,7 +762,7 @@ declare module 'fastest-validator' {
messages?: MessagesType,

/**
* Default settings for rules
* Default settings for rules
*/
defaults?: {
[key in ValidationRuleName]: ValidationSchema
Expand Down Expand Up @@ -856,6 +873,7 @@ declare module 'fastest-validator' {
RuleAny,
RuleArray,
RuleBoolean,
RuleClass,
RuleDate,
RuleEmail,
RuleEnum,
Expand Down
2 changes: 2 additions & 0 deletions lib/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,6 @@ module.exports = {

uuid: "The '{field}' field must be a valid UUID.",
uuidVersion: "The '{field}' field must be a valid UUID version provided.",

classInstanceOf: "The '{field}' field must be an instance of the '{expected}' class."
};
29 changes: 29 additions & 0 deletions lib/rules/class.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"use strict";

/** Signature: function(value, field, parent, errors, context)
*/
module.exports = function({ schema, messages, customValidation }, path, context) {
const src = [];

if (context.customs[path]) {
context.customs[path].instanceOf = schema.instanceOf;
} else {
context.customs[path] = { instanceOf: schema.instanceOf };
}

const className = schema.instanceOf.name ? schema.instanceOf.name : "<UnknowClass>";

src.push(`
if (!(value instanceof context.customs["${path}"].instanceOf))
${this.makeError({ type: "classInstanceOf", actual: "value", expected: "'" + className + "'", messages })}
`);

src.push(`
${customValidation("value")}
return value;
`);

return {
source: src.join("\n")
};
};
1 change: 1 addition & 0 deletions lib/validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ function loadRules() {
any: require("./rules/any"),
array: require("./rules/array"),
boolean: require("./rules/boolean"),
class: require("./rules/class"),
custom: require("./rules/custom"),
date: require("./rules/date"),
email: require("./rules/email"),
Expand Down
17 changes: 17 additions & 0 deletions test/rules/class.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"use strict";

const Validator = require("../../lib/validator");
const v = new Validator();

describe("Test rule: class", () => {

it("should value instanceOf Buffer", () => {
const check = v.compile({ rawData: { type: "class", instanceOf: Buffer } });
const message = "The 'rawData' field must be an instance of the 'Buffer' class.";

expect(check({ rawData: "1234"})).toEqual([{ type: "classInstanceOf", field: "rawData", actual: "1234", expected: "Buffer", message }]);
expect(check({ rawData: [1, 2, 3]})).toEqual([{ type: "classInstanceOf", field: "rawData", actual: [1, 2, 3], expected: "Buffer", message }]);
expect(check({ rawData: Buffer.from([1, 2, 3]) })).toEqual(true);
expect(check({ rawData: Buffer.alloc(3) })).toEqual(true);
});
});
18 changes: 18 additions & 0 deletions test/typescript/rules/class.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/// <reference path="../../../index.d.ts" /> // here we make a reference to exists module definition
import ValidatorType from 'fastest-validator'; // here we importing type definition of default export

const Validator: typeof ValidatorType = require('../../../index'); // here we importing real Validator Constructor
const v: ValidatorType = new Validator();

describe("Test rule: class", () => {

it("should value instanceOf Buffer", () => {
const check = v.compile({ rawData: { type: "class", instanceOf: Buffer } });
const message = "The 'rawData' field must be an instance of the 'Buffer' class.";

expect(check({ rawData: "1234"})).toEqual([{ type: "classInstanceOf", field: "rawData", actual: "1234", expected: "Buffer", message }]);
expect(check({ rawData: [1, 2, 3]})).toEqual([{ type: "classInstanceOf", field: "rawData", actual: [1, 2, 3], expected: "Buffer", message }]);
expect(check({ rawData: Buffer.from([1, 2, 3]) })).toEqual(true);
expect(check({ rawData: Buffer.alloc(3) })).toEqual(true);
});
});
2 changes: 1 addition & 1 deletion test/typescript/validator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('TypeScript Definitions', () => {
expect(v.validate).toBeInstanceOf(Function);
expect(v.add).toBeInstanceOf(Function);

expect(Object.keys(v.rules)).toHaveProperty('length', 18);
expect(Object.keys(v.rules)).toHaveProperty('length', 19);
});

it('should create instance with custom messages', () => {
Expand Down
10 changes: 5 additions & 5 deletions test/validator.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe("Test constructor", () => {
expect(v.validate).toBeInstanceOf(Function);
expect(v.add).toBeInstanceOf(Function);

expect(Object.keys(v.rules).length).toBe(18);
expect(Object.keys(v.rules).length).toBe(19);
});

it("should create instance with custom messages", () => {
Expand Down Expand Up @@ -299,7 +299,7 @@ describe("Test compile (integration test)", () => {
expect(res).toBe(true);
expect(customValidator.mock.calls[0][2]).toBe("customValue");
});
}); */
}); */
});

describe("Test aliases", () => {
Expand Down Expand Up @@ -364,7 +364,7 @@ describe("Test custom validation for built-in rules", () => {


it("should compile without error", () => {

check = v.compile({
num: {
type: "number",
Expand Down Expand Up @@ -399,7 +399,7 @@ describe("Test default settings", () => {
strict: "remove"
}
}
});
});

it("should consider default settings", () => {
const check = v.compile({
Expand Down Expand Up @@ -452,4 +452,4 @@ describe("Test default settings", () => {
}
});
});
});
});