Skip to content

Commit

Permalink
Changes:
Browse files Browse the repository at this point in the history
- Added dictionary support
  • Loading branch information
sleep-written committed Feb 23, 2023
1 parent def7b23 commit d05159c
Show file tree
Hide file tree
Showing 11 changed files with 152 additions and 4 deletions.
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ export const auditor = new Auditor({

Options:
- `items` _(required)_: `BaseType<T>`;
> 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.__
> 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, object arrays, or nested dictionaries too.__
- `min` _(optional)_: `number`;
> If the incoming array has a length __lower__ than the value setted, the `Auditor` instance will throws an `WrongLengthError` instance.
- `max` _(optional)_: `number`;
Expand Down Expand Up @@ -343,6 +343,34 @@ export const auditor = new Auditor({
});
```

### Type `record`
Options:
- `items` _(required)_: `BaseType<T>`;
> With this option you can specify the structure of every item stored for each key inside of the, using the same options described in the past types described. __You can declare nested arrays, object arrays, or nested dictionaries too.__
```ts
import { Auditor } from 'audit-var';

// The incoming data
const target = {
joder: { id: 666, nick: 'ghostlug' },
shavo: { id: 666, nick: 'dir en grey' },
};

// The auditor
const auditor = new Auditor({
type: 'record',
items: {
type: 'object',
keys: {
id: { type: 'number' },
nick: { type: 'string' }
}
}
});
```


## Utilities
### `this.structure`
Gets the actual structure of the current instance. Whith this you attach them to another more complex instance.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "audit-var",
"version": "2.1.0",
"version": "2.2.0",
"type": "module",
"description": "Inspects variables according to a defined structure",
"main": "./dist/cjs/index.js",
Expand Down
24 changes: 24 additions & 0 deletions src/converters/record-conv.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { InvalidTypeError, NotOptionalError } from '../errors/index.js';
import { converterFunct, RecordType } from '../interfaces/index.js';
import { recursiveConv } from './recursive-conv.js';

export const recordConv: converterFunct<RecordType> = (d, t, p) => {
if (t == null) {
if (!d.optional) {
throw new NotOptionalError(p);
} else {
return undefined;
}
} else if (typeof t !== 'object') {
throw new InvalidTypeError(d.type, p);
} else {
const resp: any = {};
for (const key of Object.keys(t)) {
const path = [...p, key];
const item = recursiveConv(d.items, t[key], path);
resp[key] = item;
}

return resp;
}
};
4 changes: 4 additions & 0 deletions src/converters/recursive-conv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { booleanConv } from './boolean-conv.js';
import { numberConv } from './number-conv.js';
import { objectConv } from './object-conv.js';
import { stringConv } from './string-conv.js';
import { recordConv } from './record-conv.js';
import { arrayConv } from './array-conv.js';
import { dateConv } from './date-conv.js';

Expand All @@ -26,6 +27,9 @@ export const recursiveConv: converterFunct<Types> = (d, t, p) => {
case 'object':
return objectConv(d, t, p);

case 'record':
return recordConv(d, t, p);

default:
throw new Error('Unsupported type');
}
Expand Down
4 changes: 3 additions & 1 deletion src/interfaces/array-type.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { BaseType } from './base-type.js';
import { NumberType } from './number-type.js';
import { StringType } from './string-type.js';
import { BooleanType } from './boolean-type.js';
import { ObjectType } from './object-type.js';
import { RecordType } from './record-type.js';
import { BooleanType } from './boolean-type.js';

export interface ArrayType extends BaseType<'array'> {
/**
Expand Down Expand Up @@ -30,5 +31,6 @@ export interface ArrayType extends BaseType<'array'> {
NumberType |
StringType |
ObjectType |
RecordType |
BooleanType;
}
1 change: 1 addition & 0 deletions src/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export { converterFunct } from './converter-funct.js';
export { BaseType } from './base-type.js';
export { ArrayType } from './array-type.js';
export { ObjectType } from './object-type.js';
export { RecordType } from './record-type.js';

export { DateType } from './date-type.js';
export { NumberType } from './number-type.js';
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/object-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ArrayType } from './array-type.js';
import { DateType } from './date-type.js';
import { NumberType } from './number-type.js';
import { StringType } from './string-type.js';
import { RecordType } from './record-type.js';
import { BooleanType } from './boolean-type.js';

export interface ObjectType extends BaseType<'object'> {
Expand All @@ -14,7 +15,7 @@ export interface ObjectType extends BaseType<'object'> {
string,
ArrayType |
ObjectType |

RecordType |
DateType |
NumberType |
StringType |
Expand Down
22 changes: 22 additions & 0 deletions src/interfaces/record-type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { BaseType } from './base-type.js';
import { NumberType } from './number-type.js';
import { StringType } from './string-type.js';
import { BooleanType } from './boolean-type.js';
import { ObjectType } from './object-type.js';
import { ArrayType } from './array-type.js';

export interface RecordType extends BaseType<'record'> {
/**
* With this option you can specify the structure of every
* item stored in the record, using the same options described
* in the past types described. __You can declare nested arrays,
* or object arrays too.__
*/
items:
ArrayType |
RecordType |
NumberType |
StringType |
ObjectType |
BooleanType;
}
6 changes: 6 additions & 0 deletions src/interfaces/response-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { DateType } from './date-type.js';
import { ArrayType } from './array-type.js';
import { StringType } from './string-type.js';
import { ObjectType } from './object-type.js';
import { RecordType } from './record-type.js';

export type ResponseType<T extends Types> =
T extends DateType
Expand Down Expand Up @@ -34,6 +35,11 @@ export type ResponseType<T extends Types> =
? ResponseType<T['items']>[] | undefined
: ResponseType<T['items']>[]

: T extends RecordType
? T['optional'] extends true
? Record<string, ResponseType<T['items']>> | undefined
: Record<string, ResponseType<T['items']>>

: T extends ObjectType
? T['optional'] extends true
? { [K in keyof T['keys']]: ResponseType<T['keys'][K]> } | undefined
Expand Down
2 changes: 2 additions & 0 deletions src/interfaces/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import { ArrayType } from './array-type.js';
import { ObjectType } from './object-type.js';
import { NumberType } from './number-type.js';
import { StringType } from './string-type.js';
import { RecordType } from './record-type.js';
import { BooleanType } from './boolean-type.js';

export type Types =
DateType |
ArrayType |
RecordType |
ObjectType |
NumberType |
StringType |
Expand Down
58 changes: 58 additions & 0 deletions src/tests/record.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import test from 'ava';

import { Auditor } from '../auditor.js';
import { InvalidTypeError } from '../errors/index.js';

test('Test Record<string, string>', t => {
const targetOk = {
foo: 'bar',
goo: 'baz'
};

const targetEr = {
foo: 'bar',
goo: 777
};

const auditor = new Auditor({
type: 'record',
items: { type: 'string' }
});

const result = auditor.audit(targetOk);
t.deepEqual(result, targetOk);
t.throws(
() => { auditor.audit(targetEr) },
{ instanceOf: InvalidTypeError }
);
});

test('Test Record<string, { id: number; nick: string; }>', t => {
const targetOk = {
joder: { id: 666, nick: 'ghostlug' },
shavo: { id: 666, nick: 'dir en grey' },
};

const targetEr = {
joder: { id: 'lol', nick: 'ghostlug' },
shavo: { id: 666, nick: 'dir en grey' },
};

const auditor = new Auditor({
type: 'record',
items: {
type: 'object',
keys: {
id: { type: 'number' },
nick: { type: 'string' }
}
}
});

const resp = auditor.audit(targetOk);
t.deepEqual(resp, targetOk);
t.throws(
() => { auditor.audit(targetEr) },
{ instanceOf: InvalidTypeError }
);
});

0 comments on commit d05159c

Please sign in to comment.