Skip to content

Commit

Permalink
fix: revise behavior of required keyword and move it into the object …
Browse files Browse the repository at this point in the history
…scope it is used for; update docs; minor moving of types for better readability
  • Loading branch information
mikaelvesavuori committed Mar 5, 2024
1 parent bd1991c commit 04d668f
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 39 deletions.
33 changes: 25 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,7 @@ The `errors` object includes an aggregation of any errors, both those relating t
Since version `1.0.3` both error formats have the same shape:

```json
[
{ "key": "blip", "value": 123, "success": false, "error": "Invalid type" }
]
[{ "key": "blip", "value": 123, "success": false, "error": "Invalid type" }]
```

### Using schemas
Expand Down Expand Up @@ -119,6 +117,8 @@ A valid input for this particular schema is:

By default, unknown properties will be allowed and valid. Setting `additionalProperties` to `false` enables you to disallow any unlisted properties.

Since version `1.0.10` it _only_ works in the direct scope of its location, as per below:

```json
{
"properties": {
Expand All @@ -130,9 +130,9 @@ By default, unknown properties will be allowed and valid. Setting `additionalPro
},
"third": {
"type": "string"
}
},
"additionalProperties": false
},
"additionalProperties": false
}
}
```

Expand All @@ -149,7 +149,7 @@ A payload like this...

...would therefore break the validation.

The same can be done with nested objects:
The same can be done with nested objects, by setting `additionalProperties` in the scope of the object:

```json
{
Expand All @@ -175,7 +175,7 @@ So this would not work:
"blip": "beep bloop",
"inside": {
"thing": "scary monster",
"somethingElse": "...?"
"somethingThatIsNotAllowed": "...?"
}
}
```
Expand All @@ -184,6 +184,23 @@ So this would not work:

For each level of nesting, including within objects, a `required` key with an array of strings _may_ be used to describe properties that must exist at that location.

Even the lowest-level `required` will be _within_ the `properties` key after version `1.0.10`.

This example requires both the `personal_data` object, as well as the inner `name` string:

```json
{
"properties": {
"personal_data": {
"type": "object",
"name": { "type": "string" },
"required": ["name"]
},
"required": ["personal_data"]
}
}
```

#### Types

The `type` is the only **required** item-level object. Allowed types are:
Expand Down
4 changes: 2 additions & 2 deletions src/domain/MikroValid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export class MikroValid {
for (const key in schema) {
const propertyKey = schema[key];
const inputKey: ValidationValue = input[key];
const isAdditionalsOk = propertyKey.additionalProperties ?? true;
const isInnerAdditionalsOk = propertyKey.additionalProperties ?? true;

errors = this.checkForRequiredKeysErrors(
propertyKey.required || [],
Expand All @@ -125,7 +125,7 @@ export class MikroValid {
Object.keys(inputKey),
Object.keys(propertyKey),
errors,
isAdditionalsOk
isInnerAdditionalsOk
);

this.handleNestedObject(inputKey as Record<string, any>, propertyKey, results, errors);
Expand Down
28 changes: 14 additions & 14 deletions src/interfaces/MikroValid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@ export type ValidationResult = {

export type ValidationFormat = 'alphanumeric' | 'date' | 'email' | 'hexColor' | 'numeric' | 'url';

export type ValidationValue =
| string
| string[]
| number
| number[]
| boolean
| boolean[]
| Record<string, any>
| Record<string, any>[];

export type ValidationTypes = 'string' | 'number' | 'boolean' | 'object' | 'array';

export type ValidationError = Result;

interface RootProperties<Required> {
required?: Array<Required>;
additionalProperties?: boolean;
Expand Down Expand Up @@ -84,17 +98,3 @@ export type FirstLevelDefinition<S> = RootProperties<
export type SchemaDefinition<S> = AllTypes<Extract<ExcludeFromAllTypes<S, keyof S>, string>> & {
[Key in keyof S as ExcludeFromAllTypes<S, Key>]: SchemaDefinition<S[Key]>;
};

export type ValidationValue =
| string
| string[]
| number
| number[]
| boolean
| boolean[]
| Record<string, any>
| Record<string, any>[];

export type ValidationTypes = 'string' | 'number' | 'boolean' | 'object' | 'array';

export type ValidationError = Result;
30 changes: 15 additions & 15 deletions tests/MikroValid.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,9 @@ test('It should validate a nested object', (t) => {
box: {
type: 'string'
}
}
},
required: ['boxes']
},
required: ['boxes']
}
},
{
boxes: { box: 'stuff' }
Expand Down Expand Up @@ -305,9 +305,9 @@ test('It should invalidate multiple errors separately', (t) => {
type: 'string'
},
required: ['first', 'second', 'third']
}
},
required: ['box']
},
required: ['box']
}
},
{ box: { first: 1, third: 3 } }
);
Expand Down Expand Up @@ -728,9 +728,9 @@ test('It should validate an input with additional properties that are allowed',
},
third: {
type: 'string'
}
},
additionalProperties: true
},
additionalProperties: true
}
},
{
first: 'the first',
Expand Down Expand Up @@ -828,9 +828,9 @@ test('It should validate a Flow Component', (t) => {
},
code: {
type: 'string'
}
},
required: ['component', 'memory', 'architecture', 'runtime', 'code']
},
required: ['component', 'memory', 'architecture', 'runtime', 'code']
}
},
{
component: 'function',
Expand Down Expand Up @@ -871,9 +871,9 @@ test('It should validate a App Component', (t) => {
type: 'string',
minLength: 1,
maxLength: 200
}
},
required: ['component', 'name', 'imageSource', 'url', 'altText']
},
required: ['component', 'name', 'imageSource', 'url', 'altText']
}
},
{
component: 'image',
Expand Down

0 comments on commit 04d668f

Please sign in to comment.