schemaglobin
Advanced tools
Comparing version 3.2.0 to 3.3.0
@@ -56,3 +56,2 @@ import { Schema, SchemaWithSchemas, SchemaOptions, SchemaType } from "../types"; | ||
validate(unsafeValue?: unknown): ReadonlyArray<SchemaType<S>> | Invalid; | ||
private validateSchema; | ||
} | ||
@@ -59,0 +58,0 @@ /** Shortcuts for ArraySchema. */ |
@@ -60,7 +60,7 @@ "use strict"; | ||
// Coorce. | ||
const value = this.coerce(unsafeValue); | ||
if (value instanceof Invalid_1.Invalid) | ||
return value; | ||
const unsafeArray = this.coerce(unsafeValue); | ||
if (unsafeArray instanceof Invalid_1.Invalid) | ||
return unsafeArray; | ||
// Has contents? | ||
if (!value.length) { | ||
if (!unsafeArray.length) { | ||
// Check requiredness. | ||
@@ -71,23 +71,18 @@ if (this.required) | ||
// We know this assertion is okay because we know the array is empty. | ||
return value; | ||
return unsafeArray; | ||
} | ||
// Array shorter than min length returns Invalid. | ||
if (typeof this.min === "number" && value.length < this.min) | ||
if (typeof this.min === "number" && unsafeArray.length < this.min) | ||
return new Invalid_1.Invalid(`Minimum ${this.min} items`); | ||
// Array longer than max length returns Invalid. | ||
if (typeof this.max === "number" && value.length > this.max) | ||
if (typeof this.max === "number" && unsafeArray.length > this.max) | ||
return new Invalid_1.Invalid(`Maximum ${this.max} items`); | ||
// Check each item against `this.items` | ||
return this.validateSchema(value); | ||
} | ||
// Validate an array against a subschema. | ||
// Only returns a new instance of the object if it has changed (for immutability). | ||
validateSchema(input) { | ||
let changed = false; | ||
let invalid = false; | ||
const items = this.items; | ||
const output = []; | ||
const safeArray = []; | ||
const invalids = {}; | ||
let changed = false; | ||
let invalid = false; | ||
for (let i = 0, l = input.length; i < l; i++) { | ||
const current = input[i]; | ||
for (let i = 0, l = unsafeArray.length; i < l; i++) { | ||
const current = unsafeArray[i]; | ||
const value = items.validate(current); | ||
@@ -101,3 +96,3 @@ if (value instanceof Invalid_1.Invalid) { | ||
changed = true; | ||
output.push(value); | ||
safeArray.push(value); | ||
} | ||
@@ -110,3 +105,3 @@ } | ||
// We know this assertion is okay because if it wasn't, we would've returned Invalid. | ||
return (changed ? output : input); | ||
return (changed ? safeArray : unsafeArray); | ||
} | ||
@@ -113,0 +108,0 @@ } |
@@ -35,7 +35,2 @@ import { Schema, SchemaWithSchemas, SchemaOptions, SchemaType } from "../types"; | ||
validate(unsafeValue?: unknown): Readonly<Record<string, SchemaType<S>>> | Invalid; | ||
/** | ||
* Validate an object's contents. | ||
* Only returns a new instance of the object if it has changed (for immutability). | ||
*/ | ||
private validateItems; | ||
} | ||
@@ -42,0 +37,0 @@ /** Shortcuts for MapSchema. */ |
@@ -38,7 +38,7 @@ "use strict"; | ||
// Coorce. | ||
const value = this.coerce(unsafeValue); | ||
if (value instanceof Invalid_1.Invalid) | ||
return value; | ||
const unsafeObject = this.coerce(unsafeValue); | ||
if (unsafeObject instanceof Invalid_1.Invalid) | ||
return unsafeObject; | ||
// Get number of properties. | ||
const length = Object.keys(value).length; | ||
const length = Object.keys(unsafeObject).length; | ||
// Has contents? | ||
@@ -51,3 +51,3 @@ if (!length) { | ||
// We know this type assertion is sound because we know value is empty. | ||
return value; | ||
return unsafeObject; | ||
} | ||
@@ -60,30 +60,19 @@ // Check min and max. | ||
// Check value against against `this.items` | ||
return this.validateItems(value); | ||
} | ||
/** | ||
* Validate an object's contents. | ||
* Only returns a new instance of the object if it has changed (for immutability). | ||
*/ | ||
validateItems(input) { | ||
let changed = false; | ||
let invalid = false; | ||
const output = {}; | ||
const invalids = {}; | ||
let changed = false; | ||
let invalid = false; | ||
// Validate the object against `this.items` | ||
const items = this.items; | ||
if (items) { | ||
Object.entries(input).forEach(([key, current]) => { | ||
// Validate the value. | ||
const value = items.validate(current); | ||
if (value instanceof Invalid_1.Invalid) { | ||
invalid = true; | ||
invalids[key] = value.message; | ||
} | ||
else { | ||
if (value !== current) | ||
changed = true; | ||
output[key] = value; | ||
} | ||
}); | ||
} | ||
Object.entries(unsafeObject).forEach(([key, current]) => { | ||
// Validate the value. | ||
const value = this.items.validate(current); | ||
if (value instanceof Invalid_1.Invalid) { | ||
invalid = true; | ||
invalids[key] = value.message; | ||
} | ||
else { | ||
if (value !== current) | ||
changed = true; | ||
output[key] = value; | ||
} | ||
}); | ||
// If any Schema threw Invalid, return an Invalids. | ||
@@ -93,3 +82,3 @@ if (invalid) | ||
// Return immuatably (return output if changes were made, or exact input otherwise). | ||
return (changed ? output : input); | ||
return (changed ? output : unsafeObject); | ||
} | ||
@@ -96,0 +85,0 @@ } |
@@ -40,8 +40,14 @@ import { Schema, SchemaWithSchemas, SchemaOptions, SchemaType, NullIfOptional } from "../types"; | ||
}> | NullIfOptional<R> | Invalid; | ||
schema<K extends keyof S & string>(key: K): S[K]; | ||
/** | ||
* Validate an object's contents. | ||
* Only returns a new instance of the object if it has changed (for immutability). | ||
* Like `validate()` method but works on a Partial value. | ||
* e.g. Missing properties in the object don't cause Invalid to be thrown. | ||
* | ||
* - Props that don't appear in `options.props` are silently removed. | ||
* | ||
* @returns The valid partial value, or an Invalid summarising the issues. | ||
*/ | ||
private validateSchema; | ||
partialValidate(unsafeValue: unknown): Readonly<Partial<{ | ||
[K in keyof S]: SchemaType<S[K]>; | ||
}>> | NullIfOptional<R> | Invalid; | ||
schema<K extends keyof S & string>(key: K): S[K]; | ||
} | ||
@@ -48,0 +54,0 @@ /** Shortcuts for ObjectSchema. */ |
@@ -28,7 +28,7 @@ "use strict"; | ||
// Coorce. | ||
const value = this.coerce(unsafeValue); | ||
if (value instanceof Invalid_1.Invalid) | ||
return value; | ||
const unsafeObj = this.coerce(unsafeValue); | ||
if (unsafeObj instanceof Invalid_1.Invalid) | ||
return unsafeObj; | ||
// Null means 'no object' | ||
if (value === null) { | ||
if (unsafeObj === null) { | ||
// Check requiredness. | ||
@@ -41,39 +41,77 @@ if (this.required) | ||
} | ||
// Check value against against `this.props` | ||
return this.validateSchema(value); | ||
// Validate the object against `this.props` | ||
let changed = false; | ||
let invalid = false; | ||
const safeObj = {}; | ||
const invalids = {}; | ||
const entries = Object.entries(this.props); | ||
entries.forEach(([key, schema]) => { | ||
const unsafeProp = unsafeObj[key]; | ||
const safeProp = schema.validate(unsafeProp); | ||
if (safeProp instanceof Invalid_1.Invalid) { | ||
invalid = true; | ||
invalids[key] = safeProp.message; | ||
} | ||
else { | ||
if (safeProp !== unsafeProp) | ||
changed = true; | ||
safeObj[key] = safeProp; | ||
} | ||
}); | ||
// If input has keys that aren't in props, then these keys are _excess_ and we need to return output. | ||
if (Object.keys(unsafeObj).length > entries.length) | ||
changed = true; | ||
// If any Schema threw Invalid, return an Invalids. | ||
if (invalid) | ||
return new Invalid_1.Invalid("Invalid format", invalids); | ||
// Return immuatably (return output if changes were made, or exact input otherwise). | ||
return (changed ? safeObj : unsafeObj); | ||
} | ||
// Implement SchemasSchema | ||
schema(key) { | ||
return this.props[key]; | ||
} | ||
/** | ||
* Validate an object's contents. | ||
* Only returns a new instance of the object if it has changed (for immutability). | ||
* Like `validate()` method but works on a Partial value. | ||
* e.g. Missing properties in the object don't cause Invalid to be thrown. | ||
* | ||
* - Props that don't appear in `options.props` are silently removed. | ||
* | ||
* @returns The valid partial value, or an Invalid summarising the issues. | ||
*/ | ||
validateSchema(input) { | ||
const output = {}; | ||
const invalids = {}; | ||
partialValidate(unsafeValue) { | ||
// Coorce. | ||
const unsafeObj = this.coerce(unsafeValue); | ||
if (unsafeObj instanceof Invalid_1.Invalid) | ||
return unsafeObj; | ||
// Null means 'no object' | ||
if (unsafeObj === null) { | ||
// Check requiredness. | ||
if (this.required) | ||
return new Invalid_1.Invalid("Required"); | ||
// Return. | ||
// We know this type assertion is sound because `null` can never be returned if `this.required == true`. | ||
return null; | ||
} | ||
// Check (partial) value against against `this.props` | ||
let changed = false; | ||
let invalid = false; | ||
// Validate the object against `this.props` | ||
const props = this.props; | ||
if (props) { | ||
const entries = Object.entries(props); | ||
entries.forEach(([key, schema]) => { | ||
const current = input[key]; | ||
const value = schema.validate(current); | ||
if (value instanceof Invalid_1.Invalid) { | ||
const safeObj = {}; | ||
const invalids = {}; | ||
Object.entries(unsafeObj).forEach(([key, unsafeProp]) => { | ||
if (key in this.props) { | ||
// Known props: validate against schema. | ||
const schema = this.props[key]; | ||
const safeProp = schema.validate(unsafeProp); | ||
if (safeProp instanceof Invalid_1.Invalid) { | ||
invalid = true; | ||
invalids[key] = value.message; | ||
invalids[key] = safeProp.message; | ||
} | ||
else { | ||
if (value !== current) | ||
if (safeProp !== unsafeProp) | ||
changed = true; | ||
output[key] = value; | ||
safeObj[key] = safeProp; | ||
} | ||
}); | ||
// If input has keys that aren't in props, then these keys are _excess_ and we need to return output. | ||
if (Object.keys(input).length > entries.length) | ||
} | ||
else { | ||
// Unknown prop: needs to be stripped from the return. | ||
changed = true; | ||
} | ||
} | ||
}); | ||
// If any Schema threw Invalid, return an Invalids. | ||
@@ -83,4 +121,8 @@ if (invalid) | ||
// Return immuatably (return output if changes were made, or exact input otherwise). | ||
return (changed ? output : input); | ||
return (changed ? safeObj : unsafeObj); | ||
} | ||
// Implement SchemasSchema | ||
schema(key) { | ||
return this.props[key]; | ||
} | ||
} | ||
@@ -87,0 +129,0 @@ exports.ObjectSchema = ObjectSchema; |
{ | ||
"name": "schemaglobin", | ||
"description": "Validate user-entered data.", | ||
"version": "3.2.0", | ||
"version": "3.3.0", | ||
"repository": "https://github.com/dhoulb/schemaglobin", | ||
@@ -6,0 +6,0 @@ "author": "Dave Houlbrooke <dave@shax.com>", |
@@ -454,2 +454,7 @@ # Schemaglobin: Validate unknown user input against schemas | ||
`ObjectSchema` instances also provide the following methods: | ||
- `partialValidate(value: Partial<T>)` - Validate a _partial_ object where some properties are missing (normal `validate()` would return `Invalid` if required properties were missing). | ||
- `schema(key: string)` - Get the subschema from `options.props` that corresponds to `key` | ||
### `array()` | ||
@@ -456,0 +461,0 @@ |
@@ -92,7 +92,7 @@ import { Schema, SchemaWithSchemas, SchemaOptions, SchemaType } from "../types"; | ||
// Coorce. | ||
const value = this.coerce(unsafeValue); | ||
if (value instanceof Invalid) return value; | ||
const unsafeArray = this.coerce(unsafeValue); | ||
if (unsafeArray instanceof Invalid) return unsafeArray; | ||
// Has contents? | ||
if (!value.length) { | ||
if (!unsafeArray.length) { | ||
// Check requiredness. | ||
@@ -103,26 +103,21 @@ if (this.required) return new Invalid("Required"); | ||
// We know this assertion is okay because we know the array is empty. | ||
return value as ReadonlyArray<SchemaType<S>>; | ||
return unsafeArray as ReadonlyArray<SchemaType<S>>; | ||
} | ||
// Array shorter than min length returns Invalid. | ||
if (typeof this.min === "number" && value.length < this.min) return new Invalid(`Minimum ${this.min} items`); | ||
if (typeof this.min === "number" && unsafeArray.length < this.min) | ||
return new Invalid(`Minimum ${this.min} items`); | ||
// Array longer than max length returns Invalid. | ||
if (typeof this.max === "number" && value.length > this.max) return new Invalid(`Maximum ${this.max} items`); | ||
if (typeof this.max === "number" && unsafeArray.length > this.max) | ||
return new Invalid(`Maximum ${this.max} items`); | ||
// Check each item against `this.items` | ||
return this.validateSchema(value); | ||
} | ||
// Validate an array against a subschema. | ||
// Only returns a new instance of the object if it has changed (for immutability). | ||
private validateSchema(input: unknown[]): ReadonlyArray<SchemaType<S>> | Invalid { | ||
let changed = false; | ||
let invalid = false; | ||
const items = this.items; | ||
const output: unknown[] = []; | ||
const safeArray: unknown[] = []; | ||
const invalids: { [name: string]: string } = {}; | ||
let changed = false; | ||
let invalid = false; | ||
for (let i = 0, l = input.length; i < l; i++) { | ||
const current = input[i]; | ||
for (let i = 0, l = unsafeArray.length; i < l; i++) { | ||
const current = unsafeArray[i]; | ||
const value = items.validate(current); | ||
@@ -134,3 +129,3 @@ if (value instanceof Invalid) { | ||
if (value !== current) changed = true; | ||
output.push(value); | ||
safeArray.push(value); | ||
} | ||
@@ -144,3 +139,3 @@ } | ||
// We know this assertion is okay because if it wasn't, we would've returned Invalid. | ||
return (changed ? output : input) as ReadonlyArray<SchemaType<S>>; | ||
return (changed ? safeArray : unsafeArray) as ReadonlyArray<SchemaType<S>>; | ||
} | ||
@@ -147,0 +142,0 @@ } |
@@ -71,7 +71,7 @@ import { Schema, SchemaWithSchemas, SchemaOptions, SchemaType } from "../types"; | ||
// Coorce. | ||
const value = this.coerce(unsafeValue); | ||
if (value instanceof Invalid) return value; | ||
const unsafeObject = this.coerce(unsafeValue); | ||
if (unsafeObject instanceof Invalid) return unsafeObject; | ||
// Get number of properties. | ||
const length = Object.keys(value).length; | ||
const length = Object.keys(unsafeObject).length; | ||
@@ -85,3 +85,3 @@ // Has contents? | ||
// We know this type assertion is sound because we know value is empty. | ||
return value as Record<string, SchemaType<S>>; | ||
return unsafeObject as Record<string, SchemaType<S>>; | ||
} | ||
@@ -94,31 +94,18 @@ | ||
// Check value against against `this.items` | ||
return this.validateItems(value); | ||
} | ||
/** | ||
* Validate an object's contents. | ||
* Only returns a new instance of the object if it has changed (for immutability). | ||
*/ | ||
private validateItems(input: Record<string, unknown>): Record<string, SchemaType<S>> | Invalid { | ||
let changed = false; | ||
let invalid = false; | ||
const output: Record<string, unknown> = {}; | ||
const invalids: Record<string, string> = {}; | ||
let changed = false; | ||
let invalid = false; | ||
Object.entries(unsafeObject).forEach(([key, current]) => { | ||
// Validate the value. | ||
const value = this.items.validate(current); | ||
if (value instanceof Invalid) { | ||
invalid = true; | ||
invalids[key] = value.message; | ||
} else { | ||
if (value !== current) changed = true; | ||
output[key] = value; | ||
} | ||
}); | ||
// Validate the object against `this.items` | ||
const items = this.items; | ||
if (items) { | ||
Object.entries(input).forEach(([key, current]) => { | ||
// Validate the value. | ||
const value = items.validate(current); | ||
if (value instanceof Invalid) { | ||
invalid = true; | ||
invalids[key] = value.message; | ||
} else { | ||
if (value !== current) changed = true; | ||
output[key] = value; | ||
} | ||
}); | ||
} | ||
// If any Schema threw Invalid, return an Invalids. | ||
@@ -128,3 +115,3 @@ if (invalid) return new Invalid("Invalid format", invalids); | ||
// Return immuatably (return output if changes were made, or exact input otherwise). | ||
return (changed ? output : input) as Record<string, SchemaType<S>>; | ||
return (changed ? output : unsafeObject) as Record<string, SchemaType<S>>; | ||
} | ||
@@ -131,0 +118,0 @@ } |
@@ -60,7 +60,7 @@ import { Schema, SchemaWithSchemas, SchemaOptions, SchemaType, NullIfOptional } from "../types"; | ||
// Coorce. | ||
const value = this.coerce(unsafeValue); | ||
if (value instanceof Invalid) return value; | ||
const unsafeObj = this.coerce(unsafeValue); | ||
if (unsafeObj instanceof Invalid) return unsafeObj; | ||
// Null means 'no object' | ||
if (value === null) { | ||
if (unsafeObj === null) { | ||
// Check requiredness. | ||
@@ -74,41 +74,78 @@ if (this.required) return new Invalid("Required"); | ||
// Check value against against `this.props` | ||
return this.validateSchema(value); | ||
} | ||
// Validate the object against `this.props` | ||
let changed = false; | ||
let invalid = false; | ||
const safeObj: { [key: string]: unknown } = {}; | ||
const invalids: { [key: string]: string } = {}; | ||
const entries = Object.entries(this.props); | ||
entries.forEach(([key, schema]) => { | ||
const unsafeProp = unsafeObj[key]; | ||
const safeProp = schema.validate(unsafeProp); | ||
if (safeProp instanceof Invalid) { | ||
invalid = true; | ||
invalids[key] = safeProp.message; | ||
} else { | ||
if (safeProp !== unsafeProp) changed = true; | ||
safeObj[key] = safeProp; | ||
} | ||
}); | ||
// Implement SchemasSchema | ||
schema<K extends keyof S & string>(key: K): S[K] { | ||
return this.props[key]; | ||
// If input has keys that aren't in props, then these keys are _excess_ and we need to return output. | ||
if (Object.keys(unsafeObj).length > entries.length) changed = true; | ||
// If any Schema threw Invalid, return an Invalids. | ||
if (invalid) return new Invalid("Invalid format", invalids); | ||
// Return immuatably (return output if changes were made, or exact input otherwise). | ||
return (changed ? safeObj : unsafeObj) as { [K in keyof S]: SchemaType<S[K]> }; | ||
} | ||
/** | ||
* Validate an object's contents. | ||
* Only returns a new instance of the object if it has changed (for immutability). | ||
* Like `validate()` method but works on a Partial value. | ||
* e.g. Missing properties in the object don't cause Invalid to be thrown. | ||
* | ||
* - Props that don't appear in `options.props` are silently removed. | ||
* | ||
* @returns The valid partial value, or an Invalid summarising the issues. | ||
*/ | ||
private validateSchema(input: UnknownObject): { [K in keyof S]: SchemaType<S[K]> } | Invalid { | ||
const output: { [key: string]: unknown } = {}; | ||
const invalids: { [key: string]: string } = {}; | ||
partialValidate( | ||
unsafeValue: unknown, | ||
): Readonly<Partial<{ [K in keyof S]: SchemaType<S[K]> }>> | NullIfOptional<R> | Invalid { | ||
// Coorce. | ||
const unsafeObj = this.coerce(unsafeValue); | ||
if (unsafeObj instanceof Invalid) return unsafeObj; | ||
// Null means 'no object' | ||
if (unsafeObj === null) { | ||
// Check requiredness. | ||
if (this.required) return new Invalid("Required"); | ||
// Return. | ||
// We know this type assertion is sound because `null` can never be returned if `this.required == true`. | ||
return null as NullIfOptional<R>; | ||
} | ||
// Check (partial) value against against `this.props` | ||
let changed = false; | ||
let invalid = false; | ||
// Validate the object against `this.props` | ||
const props = this.props; | ||
if (props) { | ||
const entries = Object.entries(props); | ||
entries.forEach(([key, schema]) => { | ||
const current = input[key]; | ||
const value = (schema as Schema).validate(current); | ||
if (value instanceof Invalid) { | ||
const safeObj: { [key: string]: unknown } = {}; | ||
const invalids: { [key: string]: string } = {}; | ||
Object.entries(unsafeObj).forEach(([key, unsafeProp]) => { | ||
if (key in this.props) { | ||
// Known props: validate against schema. | ||
const schema = this.props[key]; | ||
const safeProp = schema.validate(unsafeProp); | ||
if (safeProp instanceof Invalid) { | ||
invalid = true; | ||
invalids[key] = value.message; | ||
invalids[key] = safeProp.message; | ||
} else { | ||
if (value !== current) changed = true; | ||
output[key] = value; | ||
if (safeProp !== unsafeProp) changed = true; | ||
safeObj[key] = safeProp; | ||
} | ||
}); | ||
} else { | ||
// Unknown prop: needs to be stripped from the return. | ||
changed = true; | ||
} | ||
}); | ||
// If input has keys that aren't in props, then these keys are _excess_ and we need to return output. | ||
if (Object.keys(input).length > entries.length) changed = true; | ||
} | ||
// If any Schema threw Invalid, return an Invalids. | ||
@@ -118,4 +155,9 @@ if (invalid) return new Invalid("Invalid format", invalids); | ||
// Return immuatably (return output if changes were made, or exact input otherwise). | ||
return (changed ? output : input) as { [K in keyof S]: SchemaType<S[K]> }; | ||
return (changed ? safeObj : unsafeObj) as { [K in keyof S]: SchemaType<S[K]> }; | ||
} | ||
// Implement SchemasSchema | ||
schema<K extends keyof S & string>(key: K): S[K] { | ||
return this.props[key]; | ||
} | ||
} | ||
@@ -122,0 +164,0 @@ |
@@ -177,2 +177,99 @@ import { | ||
}); | ||
describe("partialValidate()", () => { | ||
test("Non-objects throw error", () => { | ||
const schema = object({ props: {} }); | ||
expect(schema.partialValidate("abc")).toEqual(new Invalid("Must be object")); | ||
expect(schema.partialValidate(123)).toEqual(new Invalid("Must be object")); | ||
expect(schema.partialValidate(true)).toEqual(new Invalid("Must be object")); | ||
}); | ||
test("Falsy values return null", () => { | ||
const schema = object({ props: {} }); | ||
expect(schema.partialValidate(0)).toBe(null); | ||
expect(schema.partialValidate(null)).toBe(null); | ||
expect(schema.partialValidate(false)).toBe(null); | ||
}); | ||
describe("options.required", () => { | ||
test("Required null objects return Required", () => { | ||
const schema = object({ props: {}, required: true }); | ||
expect(schema.partialValidate(null)).toEqual(new Invalid("Required")); | ||
}); | ||
test("Required non-null objects are not invalid", () => { | ||
const schema = object({ props: {}, required: true }); | ||
const obj = {}; | ||
expect(schema.partialValidate(obj)).toBe(obj); | ||
}); | ||
test("Non-required empty objects do not return Required", () => { | ||
const schema = object({ props: {}, required: false }); | ||
const obj = {}; | ||
expect(schema.partialValidate(obj)).toBe(obj); | ||
}); | ||
}); | ||
describe("options.props", () => { | ||
test("Object with no missing props that validates is returned unchanged", () => { | ||
const a = { num: 123, str: "abc", bool: true }; | ||
const schema = object({ | ||
props: { | ||
num: new NumberSchema(), | ||
str: new StringSchema(), | ||
bool: new BooleanSchema(), | ||
}, | ||
}); | ||
expect(schema.partialValidate(a)).toBe(a); | ||
}); | ||
test("Object with missing props that validates is returned unchanged", () => { | ||
const a = { num: 123 }; | ||
const schema = object({ | ||
props: { | ||
num: new NumberSchema(), | ||
str: new StringSchema(), | ||
bool: new BooleanSchema(), | ||
}, | ||
}); | ||
expect(schema.partialValidate(a)).toBe(a); | ||
}); | ||
test("Object with props and fixable schema is fixed", () => { | ||
const schema = object({ | ||
props: { | ||
num: new NumberSchema(), | ||
str: new StringSchema(), | ||
bool: new BooleanSchema(), | ||
}, | ||
}); | ||
expect(schema.partialValidate({ num: "123", str: 123 })).toEqual({ num: 123, str: "123" }); | ||
}); | ||
test("Object with props has unknown fields stripped", () => { | ||
const schema = object({ | ||
props: { | ||
num: new NumberSchema(), | ||
str: new StringSchema({ value: "abcdef" }), | ||
bool: new BooleanSchema(), | ||
}, | ||
}); | ||
expect( | ||
schema.partialValidate({ | ||
num: 123, | ||
str: "abcdef", | ||
excess: "should be removed", | ||
}), | ||
).toEqual({ num: 123, str: "abcdef" }); // Excess is removed. | ||
}); | ||
test("Objects with unfixable errors in subschemas returns Invalids", () => { | ||
const schema = object({ | ||
props: { | ||
dogs: new NumberSchema(), | ||
turtles: new NumberSchema(), | ||
cats: new NumberSchema({ required: true }), | ||
}, | ||
}); | ||
const invalid = schema.partialValidate({ dogs: "abc", cats: false }); | ||
expect(invalid).toBeInstanceOf(Object); | ||
if (invalid instanceof Invalid && invalid.messages) { | ||
expect(invalid.messages.dogs).toEqual("Must be number or null"); | ||
expect(invalid.messages.cats).toEqual("Required"); | ||
expect(Object.keys(invalid.messages).length).toBe(2); // No additional errors (it doesn't matter that turtles is missing). | ||
} | ||
}); | ||
}); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
218036
4659
541