diff --git a/README.md b/README.md
index ec5143f..4539c13 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@ This module works in __ESM__ projects (using _import_) and __CJS__ (using _requi
## The problem
-Usually, when you make an endpoint (with express for example) you need to validate the incomind data before to modify your server state. In thoses cases, just the validation part taket a lot of space in your file, for example:
+Usually, when you make an endpoint (with express for example) you need to validate the incoming data before to modify your server state. In those cases, just the validation part taken a lot of space in your file, for example:
```ts
import express, { json } from 'express';
@@ -158,9 +158,11 @@ export const auditor = new Auditor({
Options:
- `min` _(optional)_: `number`;
- > If the incoming string has a length lower than the value setted, the `Auditor` instance will throws an `WrongLengthError` instance.
+ > If the incoming string has a length __lower__ than the value setted, the `Auditor` instance will throws an `WrongLengthError` instance.
- `max` _(optional)_: `number`;
- > If the incoming string has a length higher than the value setted, the `Auditor` instance will throws an `WrongLengthError` instance.
+ > If the incoming string has a length __higher__ than the value setted, the `Auditor` instance will throws an `WrongLengthError` instance.
+- `cut` _(optional)_: `boolean`;
+ > If this option is enabled, when the length of the incoming string is longer than the `max` value settled, the output value will be cutted instead to throws an error.
- `trim` _(optional)_: `boolean`;
> Trims the incoming string __before to make any length validation__.
@@ -180,9 +182,9 @@ export const auditor = new Auditor({
Options:
- `min` _(optional)_: `number`;
- > If the incoming value has lower than the value setted, the `Auditor` instance will throws an `WrongLengthError` instance.
+ > If the incoming value has __lower__ than the value setted, the `Auditor` instance will throws an `WrongLengthError` instance.
- `max` _(optional)_: `number`;
- > If the incoming value has higher than the value setted, the `Auditor` instance will throws an `WrongLengthError` instance.
+ > If the incoming value has __higher__ than the value setted, the `Auditor` instance will throws an `WrongLengthError` instance.
Example:
```ts
@@ -217,9 +219,9 @@ Options:
- `items` _(required)_: `BaseType`;
> With this option you can specify the structure of every item stored in the array, using the same options described in the past types described. __You can declare nested arrays, or object arrays too.__
- `min` _(optional)_: `number`;
- > If the incoming array has a length lower than the value setted, the `Auditor` instance will throws an `WrongLengthError` instance.
+ > If the incoming array has a length __lower__ than the value setted, the `Auditor` instance will throws an `WrongLengthError` instance.
- `max` _(optional)_: `number`;
- > If the incoming array has a length higher than the value setted, the `Auditor` instance will throws an `WrongLengthError` instance.
+ > If the incoming array has a length __higher__ than the value setted, the `Auditor` instance will throws an `WrongLengthError` instance.
Example 01 (array of `string`):
```ts
@@ -339,4 +341,27 @@ export const auditor = new Auditor({
}
}
});
+```
+
+## Utilities
+### `this.structure`
+Gets the actual structure of the current instance. Whith this you attach them to another more complex instance.
+
+```ts
+const auditorChild = new Auditor({
+ type: 'object',
+ keys: {
+ id: { type: 'number', min: 1 },
+ text: { type: 'string' }
+ }
+});
+
+const auditorParent = new Auditor({
+ type: 'object',
+ keys: {
+ objA: auditor.child.structure,
+ objB: auditor.child.structure,
+ }
+});
+
```
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index eacf697..109819f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,17 +1,17 @@
{
"name": "audit-var",
- "version": "2.0.1",
+ "version": "2.1.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "audit-var",
- "version": "2.0.1",
+ "version": "2.1.0",
"license": "MIT",
"devDependencies": {
- "@types/node": "^18.0.1",
- "ava": "^4.3.0",
- "ts-node": "^10.8.2",
+ "@types/node": "^18.7.13",
+ "ava": "^4.3.1",
+ "ts-node": "^10.9.1",
"typescript": "^4.7.4"
}
},
@@ -112,9 +112,9 @@
"dev": true
},
"node_modules/@types/node": {
- "version": "18.0.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.1.tgz",
- "integrity": "sha512-CmR8+Tsy95hhwtZBKJBs0/FFq4XX7sDZHlGGf+0q+BRZfMbOTkzkj0AFAuTyXbObDIoanaBBW0+KEW+m3N16Wg==",
+ "version": "18.7.13",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.13.tgz",
+ "integrity": "sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw==",
"dev": true
},
"node_modules/acorn": {
@@ -246,9 +246,9 @@
}
},
"node_modules/ava": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ava/-/ava-4.3.0.tgz",
- "integrity": "sha512-Ap0u8rp8wOBN6CxshgxrPSe191e8g52RWGoXeDB57ubo4fyZyStfI6OxQi/bl0yxIDEOYHhCiGwihbzlMNJw3Q==",
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/ava/-/ava-4.3.1.tgz",
+ "integrity": "sha512-zdSp9QxRTmN5hJeGmg+ZjUKL5yHFLMcP/0KBla8GH25XD8Xm7Uc34CDFlwqGL6JXtjNbVkJ0Zw+DqcTf4ggCCA==",
"dev": true,
"dependencies": {
"acorn": "^8.7.1",
@@ -1836,9 +1836,9 @@
}
},
"node_modules/ts-node": {
- "version": "10.8.2",
- "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.2.tgz",
- "integrity": "sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==",
+ "version": "10.9.1",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
+ "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
"dev": true,
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
@@ -2216,9 +2216,9 @@
"dev": true
},
"@types/node": {
- "version": "18.0.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.1.tgz",
- "integrity": "sha512-CmR8+Tsy95hhwtZBKJBs0/FFq4XX7sDZHlGGf+0q+BRZfMbOTkzkj0AFAuTyXbObDIoanaBBW0+KEW+m3N16Wg==",
+ "version": "18.7.13",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.13.tgz",
+ "integrity": "sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw==",
"dev": true
},
"acorn": {
@@ -2305,9 +2305,9 @@
"dev": true
},
"ava": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ava/-/ava-4.3.0.tgz",
- "integrity": "sha512-Ap0u8rp8wOBN6CxshgxrPSe191e8g52RWGoXeDB57ubo4fyZyStfI6OxQi/bl0yxIDEOYHhCiGwihbzlMNJw3Q==",
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/ava/-/ava-4.3.1.tgz",
+ "integrity": "sha512-zdSp9QxRTmN5hJeGmg+ZjUKL5yHFLMcP/0KBla8GH25XD8Xm7Uc34CDFlwqGL6JXtjNbVkJ0Zw+DqcTf4ggCCA==",
"dev": true,
"requires": {
"acorn": "^8.7.1",
@@ -3418,9 +3418,9 @@
}
},
"ts-node": {
- "version": "10.8.2",
- "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.2.tgz",
- "integrity": "sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==",
+ "version": "10.9.1",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
+ "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
"dev": true,
"requires": {
"@cspotcode/source-map-support": "^0.8.0",
diff --git a/package.json b/package.json
index 2551d18..3155daf 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "audit-var",
- "version": "2.0.1",
+ "version": "2.1.0",
"type": "module",
"description": "Inspects variables according to a defined structure",
"main": "./dist/cjs/index.js",
@@ -41,9 +41,9 @@
},
"homepage": "https://github.com/sleep-written/audit-var#readme",
"devDependencies": {
- "@types/node": "^18.0.1",
- "ava": "^4.3.0",
- "ts-node": "^10.8.2",
+ "@types/node": "^18.7.13",
+ "ava": "^4.3.1",
+ "ts-node": "^10.9.1",
"typescript": "^4.7.4"
}
}
diff --git a/src/auditor.ts b/src/auditor.ts
index 086d956..937cac5 100644
--- a/src/auditor.ts
+++ b/src/auditor.ts
@@ -2,13 +2,34 @@ import { Types, ResponseType } from './interfaces/index.js';
import { recursiveConv } from './converters/index.js';
export class Auditor {
- private _def: T;
+ private _structure: T;
- constructor(definition: T) {
- this._def = definition;
+ /**
+ * Gets the actual structure declared in the constructor.
+ * Useful if you want to use this as a nested structure in
+ * another `Auditor` instance for example.
+ */
+ get structure(): T {
+ return this._structure;
}
+ /**
+ * Creates an instance of `Auditor` class. With this instance you can validate
+ * untyped objects with the structure defined in the constructor.
+ * @param structure The structure do you want to use to validate objects.
+ */
+ constructor(structure: T) {
+ this._structure = structure;
+ }
+
+ /**
+ * Checks recursively (when is required) the structure of an object.
+ * If the target doesn't meets the required structured (declared in the
+ * constructor), this method will throws an error, otherwise will returns
+ * a typed and normalized version of the incoming target.
+ * @param target The object do you want to eval its structure.
+ */
audit(target: any): ResponseType {
- return recursiveConv(this._def, target, []);
+ return recursiveConv(this._structure, target, []);
}
}
diff --git a/src/converters/string-conv.ts b/src/converters/string-conv.ts
index d09fa35..870f1c1 100644
--- a/src/converters/string-conv.ts
+++ b/src/converters/string-conv.ts
@@ -28,7 +28,11 @@ export const stringConv: converterFunct = (d, t, p) => {
(typeof d.max === 'number') &&
(v.length > d.max)
) {
- throw new WrongLengthError(p, `The length of the string is higher than ${d.max}.`);
+ if (!d.cut) {
+ throw new WrongLengthError(p, `The length of the string is higher than ${d.max}.`);
+ } else {
+ return v.slice(0, d.max);
+ }
}
// Valid string
diff --git a/src/interfaces/array-type.ts b/src/interfaces/array-type.ts
index 16716e0..fcb4bde 100644
--- a/src/interfaces/array-type.ts
+++ b/src/interfaces/array-type.ts
@@ -5,8 +5,26 @@ import { BooleanType } from './boolean-type.js';
import { ObjectType } from './object-type.js';
export interface ArrayType extends BaseType<'array'> {
+ /**
+ * If the incoming array has a length __lower__ than the value
+ * setted, the `Auditor` instance will throws an `WrongLengthError`
+ * instance.
+ */
min?: number;
+
+ /**
+ * If the incoming array has a length __higher__ than the value
+ * setted, the `Auditor` instance will throws an `WrongLengthError`
+ * instance.
+ */
max?: number;
+
+ /**
+ * With this option you can specify the structure of every
+ * item stored in the array, using the same options described
+ * in the past types described. __You can declare nested arrays,
+ * or object arrays too.__
+ */
items:
ArrayType |
NumberType |
diff --git a/src/interfaces/date-type.ts b/src/interfaces/date-type.ts
index a4abe6d..771e412 100644
--- a/src/interfaces/date-type.ts
+++ b/src/interfaces/date-type.ts
@@ -1,5 +1,12 @@
import { BaseType } from './base-type.js';
export interface DateType extends BaseType<'date'> {
+ /**
+ * If this value is `true`, the `Auditor` instance will try to parse strings
+ * with a valid JSON Date format (like `'2022-12-31T03:00:00.000Z'`). If the
+ * convertion is sucessfull, the returned value will be a `Date` type,
+ * otherwise, the `Auditor` instance will throws an `InvalidJSONDateError`
+ * instance.
+ */
fromJSON?: boolean;
}
\ No newline at end of file
diff --git a/src/interfaces/number-type.ts b/src/interfaces/number-type.ts
index 5346c33..c7fa3fb 100644
--- a/src/interfaces/number-type.ts
+++ b/src/interfaces/number-type.ts
@@ -1,6 +1,17 @@
import { BaseType } from './base-type.js';
export interface NumberType extends BaseType<'number'> {
+ /**
+ * If the incoming value has __lower__ than the value setted,
+ * the `Auditor` instance will throws an `WrongLengthError`
+ * instance.
+ */
min?: number;
+
+ /**
+ * If the incoming value has __higher__ than the value setted,
+ * the `Auditor` instance will throws an `WrongLengthError`
+ * instance.
+ */
max?: number;
}
diff --git a/src/interfaces/object-type.ts b/src/interfaces/object-type.ts
index 2f95778..fbb96d2 100644
--- a/src/interfaces/object-type.ts
+++ b/src/interfaces/object-type.ts
@@ -7,6 +7,9 @@ import { StringType } from './string-type.js';
import { BooleanType } from './boolean-type.js';
export interface ObjectType extends BaseType<'object'> {
+ /**
+ * Defines the type of data expected for every key of the incoming object.
+ */
keys: Record<
string,
ArrayType |
diff --git a/src/interfaces/string-type.ts b/src/interfaces/string-type.ts
index 4509378..6c80df6 100644
--- a/src/interfaces/string-type.ts
+++ b/src/interfaces/string-type.ts
@@ -1,7 +1,27 @@
import { BaseType } from './base-type.js';
export interface StringType extends BaseType<'string'> {
+ /**
+ * Trims the incoming string __before to make any length validation.__
+ */
trim?: boolean;
+
+ /**
+ * If the incoming string has a length __lower__ than the value setted,
+ * the `Auditor` instance will throws an `WrongLengthError` instance.
+ */
min?: number;
+
+ /**
+ * If the incoming string has a length __higher__ than the value setted,
+ * the `Auditor` instance will throws an `WrongLengthError` instance.
+ */
max?: number;
+
+ /**
+ * If this option is enabled, when the length of the incoming string is
+ * longer than the max value settled, the output value will be cutted
+ * instead to throws an error.
+ */
+ cut?: boolean;
}
diff --git a/src/tests/string.test.ts b/src/tests/string.test.ts
index 180ac28..5833a3f 100644
--- a/src/tests/string.test.ts
+++ b/src/tests/string.test.ts
@@ -9,6 +9,24 @@ test('optional = false; value = "jajaja"', t => {
t.is(val, 'jajaja');
});
+test('optional = false; value = "jajajajajajaj" (max: 3)', t => {
+ const aud = new Auditor({ type: 'string', max: 3 });
+ t.throws(
+ () => {
+ aud.audit('jajajajajajaj');
+ },
+ {
+ message: 'The length of the string is higher than 3.'
+ }
+ );
+});
+
+test('optional = false; value = "jajajajajajaj" (max: 3, cut: true)', t => {
+ const aud = new Auditor({ type: 'string', max: 3, cut: true });
+ const val = aud.audit('jajajajajajaj');
+ t.is(val, 'jaj');
+});
+
test('optional = false; value = undefined', t => {
const aud = new Auditor({ type: 'string' });
t.throws(