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 4.0.7 to 4.1.0

dist/helpers/date.d.ts

9

dist/index.d.ts

@@ -6,2 +6,3 @@ export * from "./Schema";

export * from "./schemas/DateSchema";
export * from "./schemas/DistanceSchema";
export * from "./schemas/EmailSchema";

@@ -15,3 +16,7 @@ export * from "./schemas/KeySchema";

export * from "./schemas/UrlSchema";
export * from "./Invalid";
export * from "./helpers";
export * from "./helpers/date";
export * from "./helpers/distance";
export * from "./helpers/invalid";
export * from "./helpers/number";
export * from "./helpers/schema";
export * from "./helpers/string";

@@ -20,2 +20,3 @@ "use strict";

__exportStar(require("./schemas/DateSchema"), exports);
__exportStar(require("./schemas/DistanceSchema"), exports);
__exportStar(require("./schemas/EmailSchema"), exports);

@@ -29,5 +30,8 @@ __exportStar(require("./schemas/KeySchema"), exports);

__exportStar(require("./schemas/UrlSchema"), exports);
// Export Invalid.
__exportStar(require("./Invalid"), exports);
// Export helpers.
__exportStar(require("./helpers"), exports);
__exportStar(require("./helpers/date"), exports);
__exportStar(require("./helpers/distance"), exports);
__exportStar(require("./helpers/invalid"), exports);
__exportStar(require("./helpers/number"), exports);
__exportStar(require("./helpers/schema"), exports);
__exportStar(require("./helpers/string"), exports);

@@ -1,2 +0,2 @@

import type { Invalid } from "./Invalid";
import type { Invalid } from "./helpers/invalid";
/**

@@ -3,0 +3,0 @@ * SchemaOptions enforces types on the options bag that is passed into SchemaClass to create Schema.

import { Schema, SchemaOptions, SchemaType, ValidateFlags } from "../Schema";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";
/** Coerce an unknown value to an array (if possible). */

@@ -4,0 +4,0 @@ export declare function coerceArray(value: unknown): unknown[] | Invalid;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.array = exports.ArraySchema = exports.coerceArray = void 0;
const Invalid_1 = require("../Invalid");
const invalid_1 = require("../helpers/invalid");
/** Coerce an unknown value to an array (if possible). */

@@ -11,3 +11,3 @@ function coerceArray(value) {

return value;
return new Invalid_1.Invalid("Must be array");
return new invalid_1.Invalid("Must be array");
}

@@ -59,3 +59,3 @@ exports.coerceArray = coerceArray;

const unsafeArray = coerceArray(unsafeValue);
if (unsafeArray instanceof Invalid_1.Invalid)
if (unsafeArray instanceof invalid_1.Invalid)
return unsafeArray;

@@ -66,3 +66,3 @@ // Has contents?

if (this.required)
return new Invalid_1.Invalid("Required");
return new invalid_1.Invalid("Required");
// Return empty array.

@@ -74,6 +74,6 @@ // We know this assertion is okay because we know the array is empty.

if (typeof this.min === "number" && unsafeArray.length < this.min)
return new Invalid_1.Invalid(`Minimum ${this.min} items`);
return new invalid_1.Invalid(`Minimum ${this.min} items`);
// Array longer than max length returns Invalid.
if (typeof this.max === "number" && unsafeArray.length > this.max)
return new Invalid_1.Invalid(`Maximum ${this.max} items`);
return new invalid_1.Invalid(`Maximum ${this.max} items`);
// Check each item against `this.items`

@@ -88,3 +88,3 @@ let changed = false;

const value = items.validate(current, flags);
if (value instanceof Invalid_1.Invalid) {
if (value instanceof invalid_1.Invalid) {
invalid = true;

@@ -101,3 +101,3 @@ invalids[i.toString()] = value.message;

if (invalid)
return new Invalid_1.Invalid("Invalid items", invalids);
return new invalid_1.Invalid("Invalid items", invalids);
// Return the new array if it changed.

@@ -104,0 +104,0 @@ // We know this assertion is okay because if it wasn't, we would've returned Invalid.

import type { Schema, SchemaOptions } from "../Schema";
import type { FalseIfOptional } from "../types";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";
/** Coerce an unknown value to a boolean. */

@@ -5,0 +5,0 @@ export declare function coerceBoolean(value: unknown): boolean;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.boolean = exports.BooleanSchema = exports.coerceBoolean = void 0;
const Invalid_1 = require("../Invalid");
const invalid_1 = require("../helpers/invalid");
/** Coerce an unknown value to a boolean. */

@@ -26,3 +26,3 @@ function coerceBoolean(value) {

if (this.required && !value)
return new Invalid_1.Invalid("Required");
return new invalid_1.Invalid("Required");
// Return boolean.

@@ -29,0 +29,0 @@ return value;

import type { NullIfOptional } from "../types";
import type { Schema, SchemaOptions } from "../Schema";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";
/** Coerce an unknown value to a Color (if possible). */

@@ -5,0 +5,0 @@ export declare function coerceColor(value: unknown): string | null | Invalid;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.color = exports.ColorSchema = exports.coerceColor = void 0;
const Invalid_1 = require("../Invalid");
const invalid_1 = require("../helpers/invalid");
const R_COLOR = /^#[0-9A-F]{6}$/;

@@ -20,3 +20,3 @@ /**

return cleanColor(value) || null;
return new Invalid_1.Invalid("Must be string or null");
return new invalid_1.Invalid("Must be string or null");
}

@@ -45,3 +45,3 @@ exports.coerceColor = coerceColor;

const value = coerceColor(unsafeValue);
if (value instanceof Invalid_1.Invalid)
if (value instanceof invalid_1.Invalid)
return value;

@@ -52,3 +52,3 @@ // Null means 'no color'

if (this.required)
return new Invalid_1.Invalid("Required");
return new invalid_1.Invalid("Required");
// Return null.

@@ -60,3 +60,3 @@ // We know this type assertion is sound because `null` can never be returned if `this.required == true`.

if (!R_COLOR.test(value))
return new Invalid_1.Invalid("Invalid color (must be a hexadecimal color)");
return new invalid_1.Invalid("Invalid color (must be a hexadecimal color)");
// Return the normalised Color.

@@ -63,0 +63,0 @@ return value;

import type { Schema, SchemaOptions } from "../Schema";
import type { NullIfOptional } from "../types";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";
export declare type DateSchemaType<R extends boolean = false> = string | NullIfOptional<R>;
/** Convert an unknown value to a date string (or return Invalid) */
export declare function coerceDate<T extends unknown>(value: T): Date | null | Invalid;
/** Convert a `Date()` instance to a YMD string like "2015-09-12" */
export declare function dateToString(value?: Date): string;
export declare type DateInputs = Date | string | number | null | (() => DateInputs);

@@ -10,0 +8,0 @@ export interface DateOptions<R extends boolean = false> extends SchemaOptions {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.date = exports.DateSchema = exports.dateToString = exports.coerceDate = void 0;
const Invalid_1 = require("../Invalid");
exports.date = exports.DateSchema = exports.coerceDate = void 0;
const invalid_1 = require("../helpers/invalid");
const date_1 = require("../helpers/date");
/** Convert an unknown value to a date string (or return Invalid) */

@@ -19,10 +20,5 @@ function coerceDate(value) {

return new Date(value); // Strings are converted to dates (except empty string which should be "").
return new Invalid_1.Invalid("Must be date, number, string, or null");
return new invalid_1.Invalid("Must be date, number, string, or null");
}
exports.coerceDate = coerceDate;
/** Convert a `Date()` instance to a YMD string like "2015-09-12" */
function dateToString(value = new Date()) {
return value.toISOString().substr(0, 10);
}
exports.dateToString = dateToString;
/**

@@ -46,3 +42,3 @@ * Schema that defines a valid date in string YMD format, e.g. `2019-10-04`

const value = coerceDate(unsafeValue);
if (value instanceof Invalid_1.Invalid)
if (value instanceof invalid_1.Invalid)
return value;

@@ -53,3 +49,3 @@ // Explicit null means 'no date'.

if (this.required)
return new Invalid_1.Invalid("Required");
return new invalid_1.Invalid("Required");
// Return null.

@@ -61,12 +57,12 @@ // We know this type assertion is sound because `null` can never be returned if `this.required == true`.

if (Number.isNaN(value.getTime()))
return new Invalid_1.Invalid("Invalid date");
return new invalid_1.Invalid("Invalid date");
// Enforce min/max.
const minDate = coerceDate(this.min);
if (minDate instanceof Date && value.getTime() < minDate.getTime())
return new Invalid_1.Invalid(`Minimum ${minDate.toLocaleDateString()}`);
return new invalid_1.Invalid(`Minimum ${minDate.toLocaleDateString()}`);
const maxDate = coerceDate(this.max);
if (maxDate instanceof Date && value.getTime() > maxDate.getTime())
return new Invalid_1.Invalid(`Maximum ${maxDate.toLocaleDateString()}`);
return new invalid_1.Invalid(`Maximum ${maxDate.toLocaleDateString()}`);
// Return the valid date string.
return dateToString(value);
return date_1.getYmd(value);
}

@@ -73,0 +69,0 @@ }

import type { Schema, SchemaOptions } from "../Schema";
import type { NullIfOptional } from "../types";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";
/** Coerce an unknown value to an email (if possible). */

@@ -5,0 +5,0 @@ export declare function coerceEmail(value: unknown): string | null | Invalid;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.email = exports.EmailSchema = exports.coerceEmail = void 0;
const Invalid_1 = require("../Invalid");
const invalid_1 = require("../helpers/invalid");
/** Coerce an unknown value to an email (if possible). */

@@ -11,3 +11,3 @@ function coerceEmail(value) {

return value.trim().toLowerCase() || null;
return new Invalid_1.Invalid("Must be string or null");
return new invalid_1.Invalid("Must be string or null");
}

@@ -48,3 +48,3 @@ exports.coerceEmail = coerceEmail;

const value = coerceEmail(unsafeValue);
if (value instanceof Invalid_1.Invalid)
if (value instanceof invalid_1.Invalid)
return value;

@@ -55,3 +55,3 @@ // Null means 'no email'

if (this.required)
return new Invalid_1.Invalid("Required");
return new invalid_1.Invalid("Required");
// Return null.

@@ -63,6 +63,6 @@ // We know this type assertion is sound because `null` can never be returned if `this.required == true`.

if (value.length > this.max)
return new Invalid_1.Invalid(`Maximum ${this.max} characters`);
return new invalid_1.Invalid(`Maximum ${this.max} characters`);
// Check format.
if (!R_EMAIL.test(value))
return new Invalid_1.Invalid("Invalid email format");
return new invalid_1.Invalid("Invalid email format");
// Return email.

@@ -69,0 +69,0 @@ return value;

import type { Schema, SchemaOptions } from "../Schema";
import type { NullIfOptional } from "../types";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";
/** Coerce an unknown value to a key (if possible). */

@@ -5,0 +5,0 @@ export declare function coerceKey(value: unknown): string | null | Invalid;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.key = exports.KeySchema = exports.coerceKey = void 0;
const Invalid_1 = require("../Invalid");
const invalid_1 = require("../helpers/invalid");
/** Coerce an unknown value to a key (if possible). */

@@ -13,3 +13,3 @@ function coerceKey(value) {

return value.trim() || null;
return new Invalid_1.Invalid("Must be string or null");
return new invalid_1.Invalid("Must be string or null");
}

@@ -38,3 +38,3 @@ exports.coerceKey = coerceKey;

const value = coerceKey(unsafeValue);
if (value instanceof Invalid_1.Invalid)
if (value instanceof invalid_1.Invalid)
return value;

@@ -45,3 +45,3 @@ // Null means 'no key'

if (this.required)
return new Invalid_1.Invalid("Required");
return new invalid_1.Invalid("Required");
// Return.

@@ -53,3 +53,3 @@ // We know this type assertion is sound because `null` can never be returned if `this.required == true`.

if (!this.match.test(value))
return new Invalid_1.Invalid("Invalid key format");
return new invalid_1.Invalid("Invalid key format");
// Return key.

@@ -56,0 +56,0 @@ return value;

import type { Schema, SchemaOptions, SchemaType, ValidateFlags } from "../Schema";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";
/** Coerce an unknown value to a map (if possible). */

@@ -4,0 +4,0 @@ export declare function coerceMap(value: unknown): Record<string, unknown> | Invalid;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.map = exports.MapSchema = exports.coerceMap = void 0;
const Invalid_1 = require("../Invalid");
const invalid_1 = require("../helpers/invalid");
/** Coerce an unknown value to a map (if possible). */

@@ -11,3 +11,3 @@ function coerceMap(value) {

return value;
return new Invalid_1.Invalid("Must be object");
return new invalid_1.Invalid("Must be object");
}

@@ -39,3 +39,3 @@ exports.coerceMap = coerceMap;

const unsafeObject = coerceMap(unsafeValue);
if (unsafeObject instanceof Invalid_1.Invalid)
if (unsafeObject instanceof invalid_1.Invalid)
return unsafeObject;

@@ -48,3 +48,3 @@ // Get number of properties.

if (this.required)
return new Invalid_1.Invalid("Required");
return new invalid_1.Invalid("Required");
// Return empty object.

@@ -56,5 +56,5 @@ // We know this type assertion is sound because we know value is empty.

if (typeof this.min === "number" && length < this.min)
return new Invalid_1.Invalid(`Minimum ${this.min} items`);
return new invalid_1.Invalid(`Minimum ${this.min} items`);
if (typeof this.max === "number" && length > this.max)
return new Invalid_1.Invalid(`Maximum ${this.max} items`);
return new invalid_1.Invalid(`Maximum ${this.max} items`);
// Check value against against `this.items`

@@ -68,3 +68,3 @@ let changed = false;

const value = this.items.validate(current, flags);
if (value instanceof Invalid_1.Invalid) {
if (value instanceof invalid_1.Invalid) {
invalid = true;

@@ -81,3 +81,3 @@ invalids[key] = value.message;

if (invalid)
return new Invalid_1.Invalid("Invalid format", invalids);
return new invalid_1.Invalid("Invalid format", invalids);
// Return immuatably (return output if changes were made, or exact input otherwise).

@@ -84,0 +84,0 @@ return (changed ? output : unsafeObject);

import type { Schema, SchemaOptions } from "../Schema";
import type { NullIfOptional } from "../types";
import { Invalid } from "../Invalid";
/**
* Convert a stringy number into a number.
*
* @param str The string to convert.
* @return The number, null (valid, meaning no number).
*/
export declare function stringToNumber(str: string): number | null;
/**
* Round numbers to a given step.
*
* @param num The number to round.
* @param step=0 The rounding to round to, e.g. `2` or `0.1`
* @returns The number rounded to the step.
*/
export declare function roundToStep(num: number, step: number): number;
import { Invalid } from "../helpers/invalid";
/** Coerce an unknown value to a number (if possible). */

@@ -20,0 +5,0 @@ export declare function coerceNumber(value: unknown): number | null | Invalid;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.number = exports.NumberSchema = exports.coerceNumber = exports.roundToStep = exports.stringToNumber = void 0;
const Invalid_1 = require("../Invalid");
// RegExps.
const R_NUMERIC = /[0-9]/;
const R_MINUS = /-/g;
/**
* Convert a stringy number into a number.
*
* @param str The string to convert.
* @return The number, null (valid, meaning no number).
*/
function stringToNumber(str) {
// Undefined if not a string.
if (typeof str !== "string")
return NaN;
// Null if empty string.
if (str.length === 0)
return null;
// Undefined if string has no numeric characters.
const firstNumeric = str.search(R_NUMERIC);
if (firstNumeric === -1)
return null;
// Negative if a minus sign appears before any numerics.
// Double negatives are resolved (i.e. three "-" minus signs → one minus sign)
const prefix = str.substr(0, firstNumeric); // Get starting portion of string without numbers.
const signs = prefix ? prefix.split(R_MINUS).length - 1 : 0; // Number of minus signs.
const negative = !!(signs % 2); // Negative (odd minus signs) or positive (even minus signs).
// Get all the non-numeric and non-dot characters, then explode by dot.
const nums = str.replace(/[^0-9.]+/g, "").split(/\.+/);
// Combine back together the negative sign, main number, and decimal numbers
const clean = (negative ? "-" : "") + nums[0] + (nums.length > 1 ? `.${nums.slice(1).join("")}` : "");
// Convert to number.
const num = Number.parseFloat(clean);
// Might be NaN (because e.g. 'abc' was passed').
return !Number.isNaN(num) ? num : null;
}
exports.stringToNumber = stringToNumber;
/**
* Round numbers to a given step.
*
* @param num The number to round.
* @param step=0 The rounding to round to, e.g. `2` or `0.1`
* @returns The number rounded to the step.
*/
function roundToStep(num, step) {
if (step < 0.00001)
throw new Error("roundToStep() does not work accurtely with steps smaller than 0.00001");
return Math.round(num / step) * step;
}
exports.roundToStep = roundToStep;
exports.number = exports.NumberSchema = exports.coerceNumber = void 0;
const invalid_1 = require("../helpers/invalid");
const number_1 = require("../helpers/number");
/** Coerce an unknown value to a number (if possible). */

@@ -60,7 +13,8 @@ function coerceNumber(value) {

if (typeof value === "string") {
const numValue = stringToNumber(value);
const numValue = number_1.stringToNumber(value);
if (typeof numValue === "number")
return numValue;
return new invalid_1.Invalid("Must be numeric");
}
return new Invalid_1.Invalid("Must be number or null");
return new invalid_1.Invalid("Must be number or null");
}

@@ -87,3 +41,3 @@ exports.coerceNumber = coerceNumber;

let value = coerceNumber(unsafeValue);
if (value instanceof Invalid_1.Invalid)
if (value instanceof invalid_1.Invalid)
return value;

@@ -94,3 +48,3 @@ // Null means 'no number'

if (this.required)
return new Invalid_1.Invalid("Required");
return new invalid_1.Invalid("Required");
// Return null.

@@ -102,11 +56,11 @@ // We know this type assertion is sound because `null` can never be returned if `this.required == true`.

if (!Number.isFinite(value))
return new Invalid_1.Invalid("Must be finite number");
return new invalid_1.Invalid("Must be finite number");
// Check min and max.
if (typeof this.max === "number" && value > this.max)
return new Invalid_1.Invalid(`Maximum ${this.max}`);
return new invalid_1.Invalid(`Maximum ${this.max}`);
if (typeof this.min === "number" && value < this.min)
return new Invalid_1.Invalid(`Minimum ${this.min}`);
return new invalid_1.Invalid(`Minimum ${this.min}`);
// Round to step.
if (typeof this.step === "number")
value = roundToStep(value, this.step);
value = number_1.roundToStep(value, this.step);
// Check options format.

@@ -116,7 +70,7 @@ if (this.options) {

if (!this.options.includes(value))
return new Invalid_1.Invalid("Unknown value");
return new invalid_1.Invalid("Unknown value");
}
else {
if (!(value.toString() in this.options))
return new Invalid_1.Invalid("Unknown value");
return new invalid_1.Invalid("Unknown value");
}

@@ -123,0 +77,0 @@ }

import type { Schema, Schemas, SchemasType, SchemaOptions, ValidateFlags } from "../Schema";
import type { NullIfOptional, DeepPartial, UnknownObject } from "../types";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";
/** Coerce an unknown value to an object (if possible). */

@@ -5,0 +5,0 @@ export declare function coerceObject(value: unknown): UnknownObject | null | Invalid;

@@ -5,3 +5,3 @@ "use strict";

exports.object = exports.ObjectSchema = exports.coerceObject = void 0;
const Invalid_1 = require("../Invalid");
const invalid_1 = require("../helpers/invalid");
/** Coerce an unknown value to an object (if possible). */

@@ -13,3 +13,3 @@ function coerceObject(value) {

return value;
return new Invalid_1.Invalid("Must be object");
return new invalid_1.Invalid("Must be object");
}

@@ -35,3 +35,3 @@ exports.coerceObject = coerceObject;

const unsafeObj = coerceObject(unsafeValue);
if (unsafeObj instanceof Invalid_1.Invalid)
if (unsafeObj instanceof invalid_1.Invalid)
return unsafeObj;

@@ -42,3 +42,3 @@ // Null means 'no object'

if (this.required)
return new Invalid_1.Invalid("Required");
return new invalid_1.Invalid("Required");
// Return.

@@ -59,3 +59,3 @@ // We know this type assertion is sound because `null` can never be returned if `this.required == true`.

const safeProp = schema.validate(unsafeProp, flags);
if (safeProp instanceof Invalid_1.Invalid) {
if (safeProp instanceof invalid_1.Invalid) {
invalid = true;

@@ -81,3 +81,3 @@ invalids[key] = safeProp.message;

const safeProp = schema.validate(unsafeProp, flags);
if (safeProp instanceof Invalid_1.Invalid) {
if (safeProp instanceof invalid_1.Invalid) {
invalid = true;

@@ -98,3 +98,3 @@ invalids[key] = safeProp.message;

if (invalid)
return new Invalid_1.Invalid("Invalid format", invalids);
return new invalid_1.Invalid("Invalid format", invalids);
// Return immuatably (return output if changes were made, or exact input otherwise).

@@ -101,0 +101,0 @@ return (changed ? safeObj : unsafeObj);

import type { Schema, SchemaOptions } from "../Schema";
import type { NullIfOptional } from "../types";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";
/** Coerce an unknown value into a phone number (if possible). */

@@ -5,0 +5,0 @@ export declare function coercePhone(value: unknown): string | null | Invalid;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.phone = exports.PhoneSchema = exports.coercePhone = void 0;
const Invalid_1 = require("../Invalid");
const invalid_1 = require("../helpers/invalid");
/**

@@ -23,3 +23,3 @@ * Clean a phone number string by removing characters that aren't digits.

return cleanPhone(value) || null; // Return the clean phone number (also convert empty string to null).
return new Invalid_1.Invalid("Must be string or null");
return new invalid_1.Invalid("Must be string or null");
}

@@ -50,3 +50,3 @@ exports.coercePhone = coercePhone;

const value = coercePhone(unsafeValue);
if (value instanceof Invalid_1.Invalid)
if (value instanceof invalid_1.Invalid)
return value;

@@ -57,3 +57,3 @@ // Null means 'no phone'

if (this.required)
return new Invalid_1.Invalid("Required");
return new invalid_1.Invalid("Required");
// Return null.

@@ -65,6 +65,6 @@ // We know this type assertion is sound because `null` can never be returned if `this.required == true`.

if (value.length > this.max)
return new Invalid_1.Invalid(`Maximum ${this.max} characters`);
return new invalid_1.Invalid(`Maximum ${this.max} characters`);
// Check format.
if (!R_PHONE.test(value))
return new Invalid_1.Invalid("Invalid phone number (must be an international number starting with `+` plus)");
return new invalid_1.Invalid("Invalid phone number (must be an international number starting with `+` plus)");
// Return phone.

@@ -71,0 +71,0 @@ return value;

import type { Schema, SchemaOptions } from "../Schema";
import type { EmptyIfOptional } from "../types";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";
/** Coerce an unknown value to a string (if possible). */

@@ -5,0 +5,0 @@ export declare function coerceString(value: unknown): string | Invalid;

@@ -5,3 +5,3 @@ "use strict";

exports.string = exports.StringSchema = exports.coerceString = void 0;
const Invalid_1 = require("../Invalid");
const invalid_1 = require("../helpers/invalid");
/** Coerce an unknown value to a string (if possible). */

@@ -15,3 +15,3 @@ function coerceString(value) {

return ""; // Convert falsy to empty string.
return new Invalid_1.Invalid("Must be string");
return new invalid_1.Invalid("Must be string");
}

@@ -58,3 +58,3 @@ exports.coerceString = coerceString;

const uncleanValue = coerceString(unsafeValue);
if (uncleanValue instanceof Invalid_1.Invalid)
if (uncleanValue instanceof invalid_1.Invalid)
return uncleanValue;

@@ -67,3 +67,3 @@ // Strip control characters.

if (this.required)
return new Invalid_1.Invalid("Required");
return new invalid_1.Invalid("Required");
// Return.

@@ -74,6 +74,6 @@ return "";

if (typeof this.max === "number" && value.length > this.max)
return new Invalid_1.Invalid(`Maximum ${this.max} characters`);
return new invalid_1.Invalid(`Maximum ${this.max} characters`);
// Check min.
if (typeof this.min === "number" && value.length < this.min)
return new Invalid_1.Invalid(`Minimum ${this.min} characters`);
return new invalid_1.Invalid(`Minimum ${this.min} characters`);
// Check enum format.

@@ -83,7 +83,7 @@ if (this.options) {

if (!this.options.includes(value))
return new Invalid_1.Invalid("Unknown value");
return new invalid_1.Invalid("Unknown value");
}
else {
if (!(value in this.options))
return new Invalid_1.Invalid("Unknown value");
return new invalid_1.Invalid("Unknown value");
}

@@ -93,3 +93,3 @@ }

if (this.match && !this.match.test(value))
return new Invalid_1.Invalid("Invalid format");
return new invalid_1.Invalid("Invalid format");
// Return string.

@@ -96,0 +96,0 @@ // This type assertion is okay because the checks above make it so.

import type { NullIfOptional } from "../types";
import type { Schema, SchemaOptions } from "../Schema";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";
/** Coerce an unknown value to a URL (if possible). */

@@ -5,0 +5,0 @@ export declare function coerceUrl(value: unknown): string | null | Invalid;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.url = exports.UrlSchema = exports.coerceUrl = void 0;
const Invalid_1 = require("../Invalid");
const invalid_1 = require("../helpers/invalid");
/** Coerce an unknown value to a URL (if possible). */

@@ -11,3 +11,3 @@ function coerceUrl(value) {

return value.trim() || null;
return new Invalid_1.Invalid("Must be string or null");
return new invalid_1.Invalid("Must be string or null");
}

@@ -39,3 +39,3 @@ exports.coerceUrl = coerceUrl;

const value = coerceUrl(unsafeValue);
if (value instanceof Invalid_1.Invalid)
if (value instanceof invalid_1.Invalid)
return value;

@@ -46,3 +46,3 @@ // Null means 'no URL'

if (this.required)
return new Invalid_1.Invalid("Required");
return new invalid_1.Invalid("Required");
// Return null.

@@ -60,12 +60,12 @@ // We know this type assertion is sound because `null` can never be returned if `this.required == true`.

// Definitely not valid.
return new Invalid_1.Invalid("Invalid URL format");
return new invalid_1.Invalid("Invalid URL format");
}
// Check length again.
if (u.href.length > this.max)
return new Invalid_1.Invalid(`Maximum ${this.max} characters`);
return new invalid_1.Invalid(`Maximum ${this.max} characters`);
// Check scheme and domain exist in whitelists.
if (!this.schemes.includes(u.protocol))
return new Invalid_1.Invalid(`Scheme "${u.protocol}" is not allowed`);
return new invalid_1.Invalid(`Scheme "${u.protocol}" is not allowed`);
if (this.hosts && !this.hosts.includes(u.host))
return new Invalid_1.Invalid(`Domain "${u.host}" is not allowed`);
return new invalid_1.Invalid(`Domain "${u.host}" is not allowed`);
// Check domain.

@@ -75,3 +75,3 @@ if (u.host.length) {

if (u.host.length > 253)
return new Invalid_1.Invalid(`Invalid URL format`);
return new invalid_1.Invalid(`Invalid URL format`);
// Each host segment is no more than 63 characters.

@@ -81,3 +81,3 @@ const bits = u.host.split(".");

if (bits[i].length > 63)
return new Invalid_1.Invalid(`Invalid URL format`);
return new invalid_1.Invalid(`Invalid URL format`);
}

@@ -84,0 +84,0 @@ // Return the normalised URL.

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

@@ -10,2 +10,3 @@ "author": "Dave Houlbrooke <dave@shax.com>",

"main": "dist/index.js",
"exports": "dist/index.js",
"types": "dist/index.d.ts",

@@ -12,0 +13,0 @@ "engineStrict": true,

@@ -152,3 +152,3 @@ # Schemaglobin: Validate unknown user input against schemas

```ts
import { boolean, string, number, date, email, phone, url, key, array, object, map } from "schemaglobin";
import { boolean, string, number, date, distance, email, phone, url, key, array, object, map } from "schemaglobin";

@@ -161,2 +161,3 @@ // Create schemas.

const dateSchema = date({ required: true, ...etc });
const distanceSchema = distance({ required: true, unit: "foot", ...etc });
const emailSchema = email({ required: true, ...etc });

@@ -166,5 +167,5 @@ const phoneSchema = phone({ required: true, ...etc });

const keySchema = key({ required: true, ...etc });
const arraySchema = array({ required: true, ...etc });
const objectSchema = object({ required: true, ...etc });
const mapSchema = object({ required: true, ...etc });
const arraySchema = array({ required: true, items: etc, ...etc });
const objectSchema = object({ required: true, props: etc, ...etc });
const mapSchema = object({ required: true, items: etc, ...etc });

@@ -174,5 +175,6 @@ // Successful validation.

stringSchema.validate("abc"); // Returns "abc"
numberSchema.validate(12345); // Returns "123"
numberSchema.validate(12345); // Returns 12345
colorSchema.validate("#00CCFF"); // Returns "#00CCFF"
dateSchema.validate("1995"); // Returns "1995-01-01"
distanceSchema.validate("100 yd"); // Returns 300 (converted to feet).
emailSchema.validate("me@x.com"); // Returns "me@x.com"

@@ -190,2 +192,3 @@ phoneSchema.validate("+1234567890"); // Returns "+1234567890"

dateSchema.validate("aaaaaaa"); // Returns Invalid("Invalid date")
distanceSchema.validate("aaaaaaa"); // Returns Invalid("Invalid distance")
colorSchema.validate(true); // Returns Invalid("Must be string or null")

@@ -326,2 +329,19 @@ emailSchema.validate("111111"); // Returns Invalid("Invalid email format")

### `array()`
The `array()` creator function creates a `ArraySchema` instance that can validate arrays and their contents:
- Arrays are valid, e.g. `[1,2,3]`
- Contents of the array can be validated with `options.items`
- Falsy values are converted to `[]` empty array.
- `[]` empty array is an invalid value if `options.required` is truthy.
`array()` also allows the following options:
- `options.value: [] = []` - The default value which will be used if the value is `undefined`
- `options.required: boolean = false` - If true, then empty arrays will return `Invalid("Required")`
- `options.min: number = null` - The minimum number of items allowed.
- `options.max: number = null` - The maximum number of items allowed.
- `options.items: Schema` (required) - Schema that will be used to validate the contents of the array.
### `boolean()`

@@ -342,46 +362,15 @@

### `string()`
### `color()`
The `string()` creator function creates a `StringSchema` instance:
The `color()` creator function creates a `ColorSchema` instance that can validate hexadecimal color strings:
- Strings are valid values.
- Strings in hex color format are valid, e.g. `#00CCFF`
- Whitespace is trimmed automatically.
- Control characters are stripped automatically.
- Newlines (and tabs) are stripped unless the `multiline` option is `true`
- Numbers are converted to string automatically.
- Falsy values are converted to `""` empty string
- Default value is `""` empty string
- `""` empty string is an invalid value if `options.required` is truthy.
`string()` also allows the following options:
- `options.value: string = ""` - The default value which will be used if the value is `undefined`
- `options.required: boolean = false` - If true, then empty strings will return `Invalid("Required")`
- `options.min: number = 0` - The minimum number of characters allowed.
- `options.max: number = null` - The maximum number of characters allowed.
- `options.options?: string[] | { string: string }` - Explicit list of allowed values as either:
1. An array of strings where each string is an allowed value.
2. An object where each string key is an allowed value, and the corresponding value is a user-facing title for the option.
- `options.match: RegExp = null` - A regular expression that the string must match.
- `options.multiline: boolean = false` - Whether the string allows newlines or not
### `number()`
The `number()` creator function creates a `NumberSchema` instance that can validate numbers:
- Numbers are valid values.
- `0` zero is a valid value.
- Falsy values are converted to `null`
- `null` is an invalid value if `options.required` is truthy.
`number()` also allows the following options:
`color()` also allows the following options:
- `options.value: number | null = null` - The default value which will be used if the value is `undefined`
- `options.value: Date = null` - The default value which will be used if the value is `undefined`
- `options.required: boolean = false` - If true, then null values will return `Invalid("Required")`
- `options.min: number = null` - The minimum number allowed.
- `options.max: number = null` - The maximum number allowed.
- `options.options: number[] | { number: string } = null` - Explicit list of allowed values as either:
1. An array of numbers where each number is an allowed value.
2. An object where each number key is an allowed value and the corresponding value can be a user-facing title for the option.
- `options.step: number = null` - The step size for the the number (the value will be rounded to the closest step).

@@ -407,15 +396,21 @@ ### `date()`

### `color()`
### `distance()`
The `color()` creator function creates a `ColorSchema` instance that can validate hexadecimal color strings:
The `distance()` creator function creates a `DistanceSchema` instance that can validate distance numbers:
- Strings in hex color format are valid, e.g. `#00CCFF`
- Whitespace is trimmed automatically.
- Numbers are valid values (and are assumed to be the base unit).
- Numeric strings are valid values and are converted to numbers.
- Numeric strings with unit suffixes (e.g. `10km` or `99 inches`) are valid values and are converted to a number and converted to the base unit.
- `0` zero is a valid value.
- Falsy values are converted to `null`
- `null` is an invalid value if `options.required` is truthy.
`color()` also allows the following options:
`distance()` also allows the following options:
- `options.value: Date = null` - The default value which will be used if the value is `undefined`
- `options.value: number | null = null` - The default value which will be used if the value is `undefined`
- `options.required: boolean = false` - If true, then null values will return `Invalid("Required")`
- `options.min: number = null` - The minimum number allowed.
- `options.max: number = null` - The maximum number allowed.
- `options.step: number = null` - The step size for the the number (the value will be rounded to the closest step).
- `options.unit: DistanceUnit = "meter"` - The base unit for this schema.

@@ -437,49 +432,70 @@ ### `email()`

### `url()`
### `key()`
The `url()` creator function creates a `UrlSchema` instance that can validate URLs:
The `key()` creator function creates a `KeySchema` instance that can validate database key strings:
- Strings that are valid email addresses are valid, e.g. `https://x.com` or `data:anything`
- Strings that are valid database keys are valid, e.g. `abc` or `AAAA1234`
- By default key strings can only contain `a-zA-Z0-9` or `-` hyphen.
- Whitespace is trimmed automatically.
- Falsy values are converted to `null`
- `null` is an invalid value if `options.required` is truthy
- `null` is an invalid value if `options.required` is truthy.
`url()` also allows the following options:
`key()` also allows the following options:
- `options.value: string = null` - The default value which will be used if the value is `undefined`
- `options.required: boolean = false` - If true, then null values will return `Invalid("Required")`
- `options.schemes: string[] = ["http:", "https:"]` - Whitelist of allowed URL schemes.
- `options.hosts: string[] = null` - List of allowed hostnames, e.g. `["google.com"]`
- `options.max: number = 512` - Maximum length of a URL.
- `options.match: RegExp = /[a-zA-Z0-9-]{1,24}/` - Format the database key must match.
### `phone()`
### `map()`
The `phone()` creator function creates a `PhoneSchema` instance that can validate URLs:
The `map()` creator function creates a `MapSchema` instance that can validate an object containing a list of key: value entries:
- Strings that are valid phone numbers are valid, e.g. `+441234567890`
- Whitespace is trimmed automatically.
- Non-digit characters are stripped automatically.
- Objects are valid, e.g. `{ a: 1, b: 2, c: 3 }`
- Contents of the object can be validated with `options.props`
- Falsy values are converted to `{}` empty object.
- `{}` empty object is an invalid value if `options.required` is truthy.
`map()` also allows the following options:
- `options.value: {} = {}` - The default value which will be used if the value is `undefined`
- `options.required: boolean = false` - If true, then empty objects will return `Invalid("Required")`
- `options.min: number = null` - The minimum number of items allowed.
- `options.max: number = null` - The maximum number of items allowed.
- `options.items: Schema` (required) - Schema that will be used to validate all properties in the object.
### `number()`
The `number()` creator function creates a `NumberSchema` instance that can validate numbers:
- Numbers are valid values.
- Strings that can be converted to numbers are valid values.
- `0` zero is a valid value.
- Falsy values are converted to `null`
- `null` is an invalid value if `options.required` is truthy.
`phone()` also allows the following options:
`number()` also allows the following options:
- `options.value: string = null` - The default value which will be used if the value is `undefined`
- `options.value: number | null = null` - The default value which will be used if the value is `undefined`
- `options.required: boolean = false` - If true, then null values will return `Invalid("Required")`
- `options.min: number = null` - The minimum number allowed.
- `options.max: number = null` - The maximum number allowed.
- `options.options: number[] | { number: string } = null` - Explicit list of allowed values as either:
1. An array of numbers where each number is an allowed value.
2. An object where each number key is an allowed value and the corresponding value can be a user-facing title for the option.
- `options.step: number = null` - The step size for the the number (the value will be rounded to the closest step).
### `key()`
### `phone()`
The `key()` creator function creates a `KeySchema` instance that can validate database key strings:
The `phone()` creator function creates a `PhoneSchema` instance that can validate URLs:
- Strings that are valid database keys are valid, e.g. `abc` or `AAAA1234`
- By default key strings can only contain `a-zA-Z0-9` or `-` hyphen.
- Strings that are valid phone numbers are valid, e.g. `+441234567890`
- Whitespace is trimmed automatically.
- Non-digit characters are stripped automatically.
- Falsy values are converted to `null`
- `null` is an invalid value if `options.required` is truthy.
`key()` also allows the following options:
`phone()` also allows the following options:
- `options.value: string = null` - The default value which will be used if the value is `undefined`
- `options.required: boolean = false` - If true, then null values will return `Invalid("Required")`
- `options.match: RegExp = /[a-zA-Z0-9-]{1,24}/` - Format the database key must match.

@@ -506,35 +522,43 @@ ### `object()`

### `array()`
### `string()`
The `array()` creator function creates a `ArraySchema` instance that can validate arrays and their contents:
The `string()` creator function creates a `StringSchema` instance:
- Arrays are valid, e.g. `[1,2,3]`
- Contents of the array can be validated with `options.items`
- Falsy values are converted to `[]` empty array.
- `[]` empty array is an invalid value if `options.required` is truthy.
- Strings are valid values.
- Whitespace is trimmed automatically.
- Control characters are stripped automatically.
- Newlines (and tabs) are stripped unless the `multiline` option is `true`
- Numbers are converted to string automatically.
- Falsy values are converted to `""` empty string
- Default value is `""` empty string
- `""` empty string is an invalid value if `options.required` is truthy.
`array()` also allows the following options:
`string()` also allows the following options:
- `options.value: [] = []` - The default value which will be used if the value is `undefined`
- `options.required: boolean = false` - If true, then empty arrays will return `Invalid("Required")`
- `options.min: number = null` - The minimum number of items allowed.
- `options.max: number = null` - The maximum number of items allowed.
- `options.items: Schema` (required) - Schema that will be used to validate the contents of the array.
- `options.value: string = ""` - The default value which will be used if the value is `undefined`
- `options.required: boolean = false` - If true, then empty strings will return `Invalid("Required")`
- `options.min: number = 0` - The minimum number of characters allowed.
- `options.max: number = null` - The maximum number of characters allowed.
- `options.options?: string[] | { string: string }` - Explicit list of allowed values as either:
1. An array of strings where each string is an allowed value.
2. An object where each string key is an allowed value, and the corresponding value is a user-facing title for the option.
- `options.match: RegExp = null` - A regular expression that the string must match.
- `options.multiline: boolean = false` - Whether the string allows newlines or not
### `map()`
### `url()`
The `map()` creator function creates a `MapSchema` instance that can validate an object containing a list of key: value entries:
The `url()` creator function creates a `UrlSchema` instance that can validate URLs:
- Objects are valid, e.g. `{ a: 1, b: 2, c: 3 }`
- Contents of the object can be validated with `options.props`
- Falsy values are converted to `{}` empty object.
- `{}` empty object is an invalid value if `options.required` is truthy.
- Strings that are valid email addresses are valid, e.g. `https://x.com` or `data:anything`
- Whitespace is trimmed automatically.
- Falsy values are converted to `null`
- `null` is an invalid value if `options.required` is truthy
`map()` also allows the following options:
`url()` also allows the following options:
- `options.value: {} = {}` - The default value which will be used if the value is `undefined`
- `options.required: boolean = false` - If true, then empty objects will return `Invalid("Required")`
- `options.min: number = null` - The minimum number of items allowed.
- `options.max: number = null` - The maximum number of items allowed.
- `options.items: Schema` (required) - Schema that will be used to validate all properties in the object.
- `options.value: string = null` - The default value which will be used if the value is `undefined`
- `options.required: boolean = false` - If true, then null values will return `Invalid("Required")`
- `options.schemes: string[] = ["http:", "https:"]` - Whitelist of allowed URL schemes.
- `options.hosts: string[] = null` - List of allowed hostnames, e.g. `["google.com"]`
- `options.max: number = 512` - Maximum length of a URL.

@@ -546,3 +570,3 @@ ### Shortcuts

```js
import { boolean, date, email, key, number, phone, string, url } from "schemaglobin";
import { boolean, date, distance, email, key, number, phone, string, url } from "schemaglobin";

@@ -552,4 +576,8 @@ // The following is equivalent to e.g. boolean({ required: true }).validate()

boolean.optional.validate(false);
color.required.validate("#00CCFF");
color.optional.validate(null);
date.required.validate(new Date());
date.optional.validate(null);
distance.required.validate("123 km");
distance.optional.validate(null);
email.required.validate("dave@x.com");

@@ -568,4 +596,2 @@ email.optional.validate(null);

url.optional.validate(null);
color.required.validate("#00CCFF");
color.optional.validate(null);
```

@@ -572,0 +598,0 @@

@@ -9,2 +9,3 @@ // Export schema.

export * from "./schemas/DateSchema";
export * from "./schemas/DistanceSchema";
export * from "./schemas/EmailSchema";

@@ -19,6 +20,8 @@ export * from "./schemas/KeySchema";

// Export Invalid.
export * from "./Invalid";
// Export helpers.
export * from "./helpers";
export * from "./helpers/date";
export * from "./helpers/distance";
export * from "./helpers/invalid";
export * from "./helpers/number";
export * from "./helpers/schema";
export * from "./helpers/string";

@@ -1,2 +0,2 @@

import type { Invalid } from "./Invalid";
import type { Invalid } from "./helpers/invalid";

@@ -3,0 +3,0 @@ /**

import { Schema, SchemaOptions, SchemaType, ValidateFlags } from "../Schema";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";

@@ -4,0 +4,0 @@ /** Coerce an unknown value to an array (if possible). */

import type { Schema, SchemaOptions } from "../Schema";
import type { FalseIfOptional } from "../types";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";

@@ -5,0 +5,0 @@ /** Coerce an unknown value to a boolean. */

import type { NullIfOptional } from "../types";
import type { Schema, SchemaOptions } from "../Schema";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";

@@ -5,0 +5,0 @@ const R_COLOR = /^#[0-9A-F]{6}$/;

import type { Schema, SchemaOptions } from "../Schema";
import type { NullIfOptional } from "../types";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";
import { getYmd } from "../helpers/date";

@@ -19,7 +20,2 @@ // Types.

/** Convert a `Date()` instance to a YMD string like "2015-09-12" */
export function dateToString(value: Date = new Date()): string {
return value.toISOString().substr(0, 10);
}
// Options.

@@ -83,3 +79,3 @@ export type DateInputs = Date | string | number | null | (() => DateInputs);

// Return the valid date string.
return dateToString(value);
return getYmd(value);
}

@@ -86,0 +82,0 @@ }

import type { Schema, SchemaOptions } from "../Schema";
import type { NullIfOptional } from "../types";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";

@@ -5,0 +5,0 @@ /** Coerce an unknown value to an email (if possible). */

import type { Schema, SchemaOptions } from "../Schema";
import type { NullIfOptional } from "../types";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";

@@ -5,0 +5,0 @@ /** Coerce an unknown value to a key (if possible). */

import type { Schema, SchemaOptions, SchemaType, ValidateFlags } from "../Schema";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";

@@ -4,0 +4,0 @@ /** Coerce an unknown value to a map (if possible). */

import type { Schema, SchemaOptions } from "../Schema";
import type { NullIfOptional } from "../types";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";
import { stringToNumber, roundToStep } from "../helpers/number";
// RegExps.
const R_NUMERIC = /[0-9]/;
const R_MINUS = /-/g;
/**
* Convert a stringy number into a number.
*
* @param str The string to convert.
* @return The number, null (valid, meaning no number).
*/
export function stringToNumber(str: string): number | null {
// Undefined if not a string.
if (typeof str !== "string") return NaN;
// Null if empty string.
if (str.length === 0) return null;
// Undefined if string has no numeric characters.
const firstNumeric = str.search(R_NUMERIC);
if (firstNumeric === -1) return null;
// Negative if a minus sign appears before any numerics.
// Double negatives are resolved (i.e. three "-" minus signs → one minus sign)
const prefix = str.substr(0, firstNumeric); // Get starting portion of string without numbers.
const signs = prefix ? prefix.split(R_MINUS).length - 1 : 0; // Number of minus signs.
const negative = !!(signs % 2); // Negative (odd minus signs) or positive (even minus signs).
// Get all the non-numeric and non-dot characters, then explode by dot.
const nums = str.replace(/[^0-9.]+/g, "").split(/\.+/);
// Combine back together the negative sign, main number, and decimal numbers
const clean = (negative ? "-" : "") + nums[0] + (nums.length > 1 ? `.${nums.slice(1).join("")}` : "");
// Convert to number.
const num = Number.parseFloat(clean);
// Might be NaN (because e.g. 'abc' was passed').
return !Number.isNaN(num) ? num : null;
}
/**
* Round numbers to a given step.
*
* @param num The number to round.
* @param step=0 The rounding to round to, e.g. `2` or `0.1`
* @returns The number rounded to the step.
*/
export function roundToStep(num: number, step: number): number {
if (step < 0.00001) throw new Error("roundToStep() does not work accurtely with steps smaller than 0.00001");
return Math.round(num / step) * step;
}
/** Coerce an unknown value to a number (if possible). */

@@ -64,2 +13,3 @@ export function coerceNumber(value: unknown): number | null | Invalid {

if (typeof numValue === "number") return numValue;
return new Invalid("Must be numeric");
}

@@ -66,0 +16,0 @@ return new Invalid("Must be number or null");

@@ -5,3 +5,3 @@ /* eslint-disable no-dupe-class-members */

import type { NullIfOptional, DeepPartial, UnknownObject } from "../types";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";

@@ -8,0 +8,0 @@ /** Coerce an unknown value to an object (if possible). */

import type { Schema, SchemaOptions } from "../Schema";
import type { NullIfOptional } from "../types";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";

@@ -5,0 +5,0 @@ /**

@@ -5,3 +5,3 @@ /* eslint-disable no-control-regex */

import type { EmptyIfOptional } from "../types";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";

@@ -8,0 +8,0 @@ /** Coerce an unknown value to a string (if possible). */

import type { NullIfOptional } from "../types";
import type { Schema, SchemaOptions } from "../Schema";
import { Invalid } from "../Invalid";
import { Invalid } from "../helpers/invalid";

@@ -5,0 +5,0 @@ /** Coerce an unknown value to a URL (if possible). */

@@ -149,4 +149,4 @@ import { Schema, array, string, number, object, StringSchema, NumberSchema, ArraySchema, Invalid } from "../../src";

if (invalid instanceof Invalid && invalid.messages) {
expect(invalid.messages[0]).toBe("Must be number or null"); // arr[0] failed.
expect(invalid.messages[2]).toBe("Must be number or null"); // arr[2] failed.
expect(invalid.messages[0]).toBe("Must be numeric"); // arr[0] failed.
expect(invalid.messages[2]).toBe("Must be numeric"); // arr[2] failed.
expect(Object.keys(invalid.messages).length).toBe(2); // No additional errors (arr[1] passed).

@@ -153,0 +153,0 @@ }

@@ -1,2 +0,2 @@

import { date, DateSchema, dateToString, Invalid } from "../../src";
import { date, DateSchema, getYmd, Invalid } from "../../src";

@@ -83,3 +83,3 @@ // Tests.

const schema = date({ value: Date.now });
expect(schema.validate(undefined)).toBe(dateToString(new Date()));
expect(schema.validate(undefined)).toBe(getYmd(new Date()));
});

@@ -125,8 +125,1 @@ });

});
describe("dateToString()", () => {
test("Correctly converts date to string", () => {
expect(dateToString(new Date("2019-11-27"))).toBe("2019-11-27");
expect(dateToString(new Date("0001-01-01"))).toBe("0001-01-01");
expect(dateToString(new Date("9999-12-31"))).toBe("9999-12-31");
});
});

@@ -136,3 +136,3 @@ import { map, string, number, boolean, NumberSchema, MapSchema, Invalid } from "../../src";

if (invalid instanceof Invalid && invalid.messages) {
expect(invalid.messages.str).toEqual("Must be number or null");
expect(invalid.messages.str).toEqual("Must be numeric");
expect(Object.keys(invalid.messages).length).toBe(1); // No additional errors.

@@ -139,0 +139,0 @@ }

@@ -1,2 +0,2 @@

import { number, NumberSchema, Invalid, roundToStep, stringToNumber } from "../../src";
import { number, NumberSchema, Invalid } from "../../src";

@@ -67,3 +67,3 @@ // Tests.

test("Non-number strings return Invalid", () => {
expect(schema.validate("abc")).toEqual(new Invalid("Must be number or null"));
expect(schema.validate("abc")).toEqual(new Invalid("Must be numeric"));
});

@@ -172,60 +172,2 @@ test("Non-numbers return Invalid", () => {

});
describe("roundToStep()", () => {
test("Numbers are rounded correctly", () => {
expect(roundToStep(51, 100)).toBe(100);
expect(roundToStep(50, 100)).toBe(100); // Rounds up when exactly halfway.
expect(roundToStep(149, 100)).toBe(100);
expect(roundToStep(4, 2)).toBe(4);
expect(roundToStep(3, 2)).toBe(4); // Rounds up when exactly halfway.
expect(roundToStep(2, 2)).toBe(2);
expect(roundToStep(1001, 1)).toBe(1001);
expect(roundToStep(100.0, 1)).toBe(100);
expect(roundToStep(100.001, 0.001)).toBe(100.001);
expect(roundToStep(100.001, 0.001)).not.toBe(100);
expect(roundToStep(100.00001, 0.00001)).toBe(100.00001);
expect(roundToStep(100.00001, 0.0001)).toBe(100);
});
});
describe("stringToNumber()", () => {
test("Strings with numbers are converted to numbers", () => {
expect(stringToNumber("0")).toBe(0);
expect(stringToNumber("1")).toBe(1);
});
test("Decimal places are converted correctly", () => {
expect(stringToNumber("1.555")).toBe(1.555);
expect(stringToNumber("123.456")).toBe(123.456);
expect(stringToNumber("1.5.5.5")).toBe(1.555);
expect(stringToNumber("99999.9.9.9.9.9")).toBe(99999.99999);
});
test("Signs are converted correctly", () => {
expect(stringToNumber("-1")).toBe(-1);
expect(stringToNumber("--1")).toBe(1);
expect(stringToNumber("---1")).toBe(-1);
expect(stringToNumber("----1")).toBe(1);
expect(stringToNumber("+1")).toBe(1);
expect(stringToNumber("++1")).toBe(1);
expect(stringToNumber("+++1")).toBe(1);
expect(stringToNumber("++++1")).toBe(1);
expect(stringToNumber("+-+1")).toBe(-1);
expect(stringToNumber("-+-+1")).toBe(1);
expect(stringToNumber("1.5")).toBe(1.5);
expect(stringToNumber("-1.5")).toBe(-1.5);
expect(stringToNumber("--1.5")).toBe(1.5);
expect(stringToNumber("---1.5")).toBe(-1.5);
expect(stringToNumber("----1.5")).toBe(1.5);
});
test("Complicated numbers are fixed correctly", () => {
expect(stringToNumber("99999.9.9.9.9.9")).toBe(99999.99999);
expect(stringToNumber("-99999.9.9.9.9.9")).toBe(-99999.99999);
expect(stringToNumber("--99999.9.9.9.9.9")).toBe(99999.99999);
expect(stringToNumber("---99999.9.9.9.9.9")).toBe(-99999.99999);
});
test("Empty string returns null", () => {
expect(stringToNumber("")).toBe(null);
});
test("Non-numbers return null", () => {
expect(stringToNumber("a")).toBe(null);
expect(stringToNumber("Willow perceptiveness purely sportsmanship namaste victoriously?")).toBe(null);
});
});
});

@@ -226,3 +226,3 @@ import { object, number, StringSchema, NumberSchema, BooleanSchema, ObjectSchema, Invalid } from "../../src";

if (invalid instanceof Invalid && invalid.messages) {
expect(invalid.messages.dogs).toEqual("Must be number or null");
expect(invalid.messages.dogs).toEqual("Must be numeric");
expect(invalid.messages.cats).toEqual("Required");

@@ -368,3 +368,3 @@ expect(Object.keys(invalid.messages).length).toBe(2); // No additional errors.

if (invalid instanceof Invalid && invalid.messages) {
expect(invalid.messages.dogs).toEqual("Must be number or null");
expect(invalid.messages.dogs).toEqual("Must be numeric");
expect(invalid.messages.cats).toEqual("Required");

@@ -371,0 +371,0 @@ expect(Object.keys(invalid.messages).length).toBe(2); // No additional errors (it doesn't matter that turtles is missing).

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