Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

schemaglobin

Package Overview
Dependencies
Maintainers
1
Versions
64
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

schemaglobin - npm Package Compare versions

Comparing version 3.3.0 to 3.3.1

3

dist/schemas/ObjectSchema.d.ts

@@ -44,2 +44,3 @@ import { Schema, SchemaWithSchemas, SchemaOptions, SchemaType, NullIfOptional } from "../types";

*
* - Recursive! Nested ObjectSchema instances are also partially validated.
* - Props that don't appear in `options.props` are silently removed.

@@ -50,3 +51,3 @@ *

partialValidate(unsafeValue: unknown): Readonly<Partial<{
[K in keyof S]: SchemaType<S[K]>;
[K in keyof S]: Partial<SchemaType<S[K]>>;
}>> | NullIfOptional<R> | Invalid;

@@ -53,0 +54,0 @@ schema<K extends keyof S & string>(key: K): S[K];

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Invalid_1 = require("../Invalid");
// Whether we're in 'partial' mode or not.
let partial = false;
/**

@@ -45,56 +47,28 @@ * Schema that defines a valid object.

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)
if (partial) {
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] = safeProp.message;
}
else {
if (safeProp !== unsafeProp)
changed = true;
safeObj[key] = safeProp;
}
}
else {
// Unknown prop: needs to be stripped from the return.
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);
}
/**
* 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.
*/
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;
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];
else {
const entries = Object.entries(this.props);
entries.forEach(([key, schema]) => {
const unsafeProp = unsafeObj[key];
const safeProp = schema.validate(unsafeProp);

@@ -110,8 +84,7 @@ if (safeProp instanceof Invalid_1.Invalid) {

}
}
else {
// Unknown prop: needs to be stripped from the return.
});
// 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.

@@ -123,2 +96,23 @@ if (invalid)

}
/**
* Like `validate()` method but works on a Partial value.
* e.g. Missing properties in the object don't cause Invalid to be thrown.
*
* - Recursive! Nested ObjectSchema instances are also partially validated.
* - Props that don't appear in `options.props` are silently removed.
*
* @returns The valid partial value, or an Invalid summarising the issues.
*/
partialValidate(unsafeValue) {
try {
partial = true;
const value = this.validate(unsafeValue);
partial = false;
return value;
}
catch (err) {
partial = false;
throw err;
}
}
// Implement SchemasSchema

@@ -125,0 +119,0 @@ schema(key) {

{
"name": "schemaglobin",
"description": "Validate user-entered data.",
"version": "3.3.0",
"version": "3.3.1",
"repository": "https://github.com/dhoulb/schemaglobin",

@@ -6,0 +6,0 @@ "author": "Dave Houlbrooke <dave@shax.com>",

@@ -14,2 +14,5 @@ import { Schema, SchemaWithSchemas, SchemaOptions, SchemaType, NullIfOptional } from "../types";

// Whether we're in 'partial' mode or not.
let partial = false;
/**

@@ -79,17 +82,37 @@ * Schema that defines a valid object.

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;
}
});
if (partial) {
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] = safeProp.message;
} else {
if (safeProp !== unsafeProp) changed = true;
safeObj[key] = safeProp;
}
} else {
// Unknown prop: needs to be stripped from the return.
changed = true;
}
});
} else {
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;
}
});
// 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 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;
}

@@ -107,2 +130,3 @@ // If any Schema threw Invalid, return an Invalids.

*
* - Recursive! Nested ObjectSchema instances are also partially validated.
* - Props that don't appear in `options.props` are silently removed.

@@ -114,45 +138,12 @@ *

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>;
): Readonly<Partial<{ [K in keyof S]: Partial<SchemaType<S[K]>> }>> | NullIfOptional<R> | Invalid {
try {
partial = true;
const value = this.validate(unsafeValue);
partial = false;
return value;
} catch (err) {
partial = false;
throw err;
}
// Check (partial) value against against `this.props`
let changed = false;
let invalid = false;
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] = safeProp.message;
} else {
if (safeProp !== unsafeProp) changed = true;
safeObj[key] = safeProp;
}
} else {
// Unknown prop: needs to be stripped from the return.
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]> };
}

@@ -159,0 +150,0 @@

@@ -254,4 +254,43 @@ import {

}),
).toEqual({ num: 123, str: "abcdef" }); // Excess is removed.
).toEqual({
num: 123,
str: "abcdef",
// excess is removed.
});
});
test("Deeply nested objects are also partially validated", () => {
const schema = object({
props: {
num: new NumberSchema(),
str: new StringSchema({ value: "abcdef" }),
bool: new BooleanSchema(),
obj: new ObjectSchema({
props: {
num: new NumberSchema(),
str: new StringSchema({ value: "abcdef" }),
bool: new BooleanSchema(),
},
}),
},
});
expect(
schema.partialValidate({
num: 123,
str: "abcdef",
obj: {
num: 123,
str: "abcdef",
},
}),
).toEqual({
num: 123,
str: "abcdef",
// bool is allowed to be missing.
obj: {
num: 123,
str: "abcdef",
// bool is allowed to be missing.
},
});
});
test("Objects with unfixable errors in subschemas returns Invalids", () => {

@@ -258,0 +297,0 @@ const schema = object({

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc