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 5.7.0 to 5.8.0

3

dist/schemas/BooleanSchema.d.ts
import type { Schema, SchemaOptions } from "../Schema";
import type { FalseIfOptional } from "../types";
import { Invalid } from "../helpers/message";
/** Coerce an unknown value to a boolean. */
export declare function coerceBoolean(value: unknown): boolean;
export declare type BooleanSchemaType<R extends boolean = false> = true | FalseIfOptional<R>;
export declare type BooleanSchemaType<R extends boolean = false> = true | (R extends true ? never : false);
export interface BooleanSchemaOptions<R extends boolean> extends SchemaOptions {

@@ -8,0 +7,0 @@ readonly value?: boolean;

@@ -1,13 +0,4 @@

import type { NullIfOptional } from "../types";
import type { Schema, SchemaOptions } from "../Schema";
import { Invalid } from "../helpers/message";
/** Coerce an unknown value to a Color (if possible). */
export declare function coerceColor(value: unknown): string | null | Invalid;
export declare type ColorSchemaType<R extends boolean = boolean> = string | NullIfOptional<R>;
interface ColorOptions<R extends boolean = false> extends SchemaOptions {
readonly value?: string | null;
readonly required?: R;
}
import { StringOptions, StringSchema } from "./StringSchema";
/**
* Schema that defines a valid Color.
* Type of `StringSchema` that defines a valid Color.
*

@@ -20,20 +11,15 @@ * Ensures value is a string, enforces that the string is a valid Color.

*/
export declare class ColorSchema<R extends boolean = false> implements Schema<ColorSchemaType<R>> {
readonly title: string;
readonly description: string;
readonly placeholder: string;
readonly value: string | null;
readonly required: R;
export declare class ColorSchema<T extends string = string, R extends boolean = false> extends StringSchema<T, R> {
readonly multiline = false;
readonly max = 7;
constructor({ title, description, placeholder, value, required }?: ColorOptions<R>);
validate(unsafeValue?: unknown): ColorSchemaType<R> | Invalid;
readonly match: RegExp;
clean(str: string): string;
}
/** Shortcuts for ColorSchema. */
export declare const color: {
(options: ColorOptions<false>): ColorSchema<false>;
(options: ColorOptions<true>): ColorSchema<true>;
(): ColorSchema<false>;
required: ColorSchema<true>;
optional: ColorSchema<false>;
<T extends string>(options: StringOptions<T, false>): ColorSchema<T, false>;
<T extends string>(options: StringOptions<T, true>): ColorSchema<T, true>;
(): ColorSchema<string, false>;
required: ColorSchema<string, true>;
optional: ColorSchema<string, false>;
};
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.color = exports.ColorSchema = exports.coerceColor = void 0;
const message_1 = require("../helpers/message");
exports.color = exports.ColorSchema = void 0;
const StringSchema_1 = require("./StringSchema");
const R_COLOR = /^#[0-9A-F]{6}$/;

@@ -10,17 +10,8 @@ /**

*/
function cleanColor(value) {
const cleanColor = (value) => {
const digits = value.toUpperCase().replace(/[^0-9A-F]/g, "");
return digits ? `#${digits.slice(0, 6)}` : "";
}
/** Coerce an unknown value to a Color (if possible). */
function coerceColor(value) {
if (!value)
return null; // Convert falsy to null.
if (typeof value === "string")
return cleanColor(value) || null;
return new message_1.Invalid("Must be string or null");
}
exports.coerceColor = coerceColor;
};
/**
* Schema that defines a valid Color.
* Type of `StringSchema` that defines a valid Color.
*

@@ -33,30 +24,11 @@ * Ensures value is a string, enforces that the string is a valid Color.

*/
class ColorSchema {
constructor({ title = "", description = "", placeholder = "", value = null, required = false } = {}) {
class ColorSchema extends StringSchema_1.StringSchema {
constructor() {
super(...arguments);
this.multiline = false;
this.max = 7;
this.title = title;
this.description = description;
this.placeholder = placeholder;
this.value = value;
this.required = required;
this.match = R_COLOR;
}
validate(unsafeValue = this.value) {
// Coorce.
const value = coerceColor(unsafeValue);
if (value instanceof message_1.Invalid)
return value;
// Null means 'no color'
if (value === null) {
// Check requiredness.
if (this.required)
return new message_1.Required("Required");
// Return null.
// We know this type assertion is sound because `null` can never be returned if `this.required == true`.
return null;
}
// Check format.
if (!R_COLOR.test(value))
return new message_1.Invalid("Invalid color (must be a hexadecimal color)");
// Return the normalised Color.
return value;
clean(str) {
return cleanColor(super.clean(str));
}

@@ -63,0 +35,0 @@ }

import type { Schema, SchemaOptions } from "../Schema";
import type { NullIfOptional } from "../types";
import { Invalid } from "../helpers/message";
export declare type DateSchemaType<R extends boolean = false> = string | NullIfOptional<R>;
export declare type DateSchemaType<R extends boolean = false> = string | (R extends true ? never : null);
/** Convert an unknown value to a date string (or return Invalid) */

@@ -16,4 +15,4 @@ export declare function coerceDate<T extends unknown>(value: T): Date | null | Invalid;

* Schema that defines a valid date in string YMD format, e.g. `2019-10-04`
* `Date` instances, numbers, strings, are automatically converted to YMD strings.
* `null` is also a valid value if this field is not required.
* - `Date` instances, numbers, strings, are automatically converted to YMD strings.
* - `null` is also a valid value if this field is not required.
*/

@@ -20,0 +19,0 @@ export declare class DateSchema<R extends boolean = false> implements Schema<DateSchemaType<R>> {

@@ -25,4 +25,4 @@ "use strict";

* Schema that defines a valid date in string YMD format, e.g. `2019-10-04`
* `Date` instances, numbers, strings, are automatically converted to YMD strings.
* `null` is also a valid value if this field is not required.
* - `Date` instances, numbers, strings, are automatically converted to YMD strings.
* - `null` is also a valid value if this field is not required.
*/

@@ -29,0 +29,0 @@ class DateSchema {

import { Invalid } from "../helpers/message";
import { SchemaOptions, Schema } from "../Schema";
import { NullIfOptional } from "../types";
import { DistanceUnit } from "../helpers/distance";
export declare type DistanceSchemaType<R extends boolean = false> = number | NullIfOptional<R>;
export declare type DistanceSchemaType<R extends boolean = false> = number | (R extends true ? never : null);
export interface DistanceOptions<R extends boolean = false> extends SchemaOptions {

@@ -31,3 +30,3 @@ readonly unit?: DistanceUnit;

constructor({ title, description, placeholder, value, required, min, max, step, unit, }: DistanceOptions<R>);
validate(unsafeValue?: unknown): number | NullIfOptional<R> | Invalid;
validate(unsafeValue?: unknown): DistanceSchemaType<R> | Invalid;
}

@@ -34,0 +33,0 @@ /** Shortcuts for DistanceSchema. */

@@ -1,14 +0,5 @@

import type { Schema, SchemaOptions } from "../Schema";
import type { NullIfOptional } from "../types";
import { Invalid } from "../helpers/message";
/** Coerce an unknown value to an email (if possible). */
export declare function coerceEmail(value: unknown): string | null | Invalid;
export declare type EmailSchemaType<R extends boolean = false> = string | NullIfOptional<R>;
export interface EmailOptions<R extends boolean = false> extends SchemaOptions {
readonly value?: string | null;
readonly required?: R;
}
import { StringOptions, StringSchema } from "./StringSchema";
/**
* Schema that defines a valid email address.
*
* Type of `StringSchema` that defines a valid email address.
* - Falsy values are converted to `""` empty string.
* - Total length must be 254 characters or fewer (in SMTP email is encoded with `<` and `>` to make 256 characters).

@@ -26,23 +17,16 @@ * - No minimum length is enforced because the email's format is enforced instead.

* - TLD is a segment of 2-63 characters, possibly in `xn--` international format.
*
* `null` is also a valid value if this field is not required.
* Falsy values and empty strings are converted to `null`
*/
export declare class EmailSchema<R extends boolean = false> implements Schema<EmailSchemaType<R>> {
readonly title: string;
readonly description: string;
readonly placeholder: string;
readonly value: string | null;
readonly required: R;
readonly max: number;
constructor({ title, description, placeholder, value, required }?: EmailOptions<R>);
validate(unsafeValue?: unknown): EmailSchemaType<R> | Invalid;
export declare class EmailSchema<T extends string = string, R extends boolean = boolean> extends StringSchema<T, R> {
readonly max = 254;
readonly match: RegExp;
readonly multiline = false;
clean(str: string): string;
}
/** Shortcuts for EmailSchema. */
export declare const email: {
(options: EmailOptions<false>): EmailSchema<false>;
(options: EmailOptions<true>): EmailSchema<true>;
(): EmailSchema<false>;
required: EmailSchema<true>;
optional: EmailSchema<false>;
<T extends string>(options: StringOptions<T, false>): EmailSchema<T, false>;
<T extends string>(options: StringOptions<T, true>): EmailSchema<T, true>;
(): EmailSchema<string, false>;
required: EmailSchema<string, true>;
optional: EmailSchema<string, false>;
};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.email = exports.EmailSchema = exports.coerceEmail = void 0;
const message_1 = require("../helpers/message");
/** Coerce an unknown value to an email (if possible). */
function coerceEmail(value) {
if (!value)
return null; // Convert falsy to null.
if (typeof value === "string")
return value.trim().toLowerCase() || null;
return new message_1.Invalid("Must be string or null");
}
exports.coerceEmail = coerceEmail;
exports.email = exports.EmailSchema = void 0;
const StringSchema_1 = require("./StringSchema");
// RegExps.
const R_EMAIL = /^[a-z0-9](?:[a-zA-Z0-9._+-]{0,62}[a-zA-Z0-9])?@(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.){1,3}(?:[a-z]{2,63}|xn--[a-z0-9-]{0,58}[a-z0-9])$/;
/**
* Schema that defines a valid email address.
*
* Type of `StringSchema` that defines a valid email address.
* - Falsy values are converted to `""` empty string.
* - Total length must be 254 characters or fewer (in SMTP email is encoded with `<` and `>` to make 256 characters).

@@ -31,37 +22,12 @@ * - No minimum length is enforced because the email's format is enforced instead.

* - TLD is a segment of 2-63 characters, possibly in `xn--` international format.
*
* `null` is also a valid value if this field is not required.
* Falsy values and empty strings are converted to `null`
*/
class EmailSchema {
constructor({ title = "", description = "", placeholder = "", value = null, required = false } = {}) {
this.max = 254; // Can't be changed or it wouldn't be a valid email address.
this.title = title;
this.description = description;
this.placeholder = placeholder;
this.value = value;
this.required = required;
class EmailSchema extends StringSchema_1.StringSchema {
constructor() {
super(...arguments);
this.max = 254;
this.match = R_EMAIL;
this.multiline = false;
}
validate(unsafeValue = this.value) {
// Coorce.
const value = coerceEmail(unsafeValue);
if (value instanceof message_1.Invalid)
return value;
// Null means 'no email'
if (!value) {
// Check requiredness.
if (this.required)
return new message_1.Required("Required");
// Return null.
// We know this type assertion is sound because `null` can never be returned if `this.required == true`.
return null;
}
// Check length.
if (value.length > this.max)
return new message_1.Invalid(`Maximum ${this.max} characters`);
// Check format.
if (!R_EMAIL.test(value))
return new message_1.Invalid("Invalid email format");
// Return email.
return value;
clean(str) {
return super.clean(str).toLowerCase();
}

@@ -68,0 +34,0 @@ }

@@ -1,36 +0,17 @@

import type { Schema, SchemaOptions } from "../Schema";
import type { NullIfOptional } from "../types";
import { Invalid } from "../helpers/message";
/** Coerce an unknown value to a key (if possible). */
export declare function coerceKey(value: unknown): string | null | Invalid;
export declare type KeySchemaType<R extends boolean = false> = string | NullIfOptional<R>;
export interface KeyOptions<R extends boolean = false> extends SchemaOptions {
readonly value?: string | null;
readonly required?: R;
readonly match?: RegExp;
}
import { StringOptions, StringSchema } from "./StringSchema";
/**
* Schema that defines a valid database key.
* Ensures value is a non-empty string key of up to `max` characters.
*
* `null` is also a valid value if this field is not required.
* Falsy values and empty strings are converted to `null`
* Type of `StringSchema` that defines a valid database key.
* Ensures value is a non-empty string key matching `[a-zA-Z0-9]{1,64}`
*/
export declare class KeySchema<R extends boolean = false> implements Schema<KeySchemaType<R>> {
readonly title: string;
readonly description: string;
readonly placeholder: string;
readonly value: string | null;
readonly required: R;
export declare class KeySchema<T extends string = string, R extends boolean = false> extends StringSchema<T, R> {
readonly match: RegExp;
constructor({ title, description, placeholder, value, required, match }?: KeyOptions<R>);
validate(unsafeValue?: unknown): KeySchemaType<R> | Invalid;
readonly multiline = false;
}
/** Shortcuts for KeySchema. */
export declare const key: {
(options: KeyOptions<false>): KeySchema<false>;
(options: KeyOptions<true>): KeySchema<true>;
(): KeySchema<false>;
required: KeySchema<true>;
optional: KeySchema<false>;
<T extends string>(options: StringOptions<T, false>): KeySchema<T, false>;
<T extends string>(options: StringOptions<T, true>): KeySchema<T, true>;
(): KeySchema<string, false>;
required: KeySchema<string, true>;
optional: KeySchema<string, false>;
};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.key = exports.KeySchema = exports.coerceKey = void 0;
const message_1 = require("../helpers/message");
/** Coerce an unknown value to a key (if possible). */
function coerceKey(value) {
if (typeof value === "number")
return value.toString(); // Zero is a valid key.
if (!value)
return null; // Convert falsy to null.
if (typeof value === "string")
return value.trim() || null;
return new message_1.Invalid("Must be string or null");
}
exports.coerceKey = coerceKey;
exports.key = exports.KeySchema = void 0;
const StringSchema_1 = require("./StringSchema");
// Default key only allows [a-zA-Z0-9] and 1-64 characters.
const R_KEY = /[a-zA-Z0-9]{1,64}/;
/**
* Schema that defines a valid database key.
* Ensures value is a non-empty string key of up to `max` characters.
*
* `null` is also a valid value if this field is not required.
* Falsy values and empty strings are converted to `null`
* Type of `StringSchema` that defines a valid database key.
* Ensures value is a non-empty string key matching `[a-zA-Z0-9]{1,64}`
*/
class KeySchema {
constructor({ title = "", description = "", placeholder = "", value = null, required = false, match = R_KEY } = {}) {
this.title = title;
this.description = description;
this.placeholder = placeholder;
this.value = value;
this.required = required;
this.match = match;
class KeySchema extends StringSchema_1.StringSchema {
constructor() {
super(...arguments);
this.match = R_KEY;
this.multiline = false;
}
validate(unsafeValue = this.value) {
// Coorce.
const value = coerceKey(unsafeValue);
if (value instanceof message_1.Invalid)
return value;
// Null means 'no key'
if (!value) {
// Check requiredness.
if (this.required)
return new message_1.Required("Required");
// Return.
// We know this type assertion is sound because `null` can never be returned if `this.required == true`.
return null;
}
// Check match format RegExp.
if (!this.match.test(value))
return new message_1.Invalid("Invalid key format");
// Return key.
return value;
}
}

@@ -55,0 +18,0 @@ exports.KeySchema = KeySchema;

import type { Schema, SchemaOptions } from "../Schema";
import type { NullIfOptional } from "../types";
import { Invalid } from "../helpers/message";
/** Coerce an unknown value to a number (if possible). */
export declare function coerceNumber(value: unknown): number | null | Invalid;
export declare type NumberSchemaType<T extends number = number, R extends boolean = false> = T | NullIfOptional<R>;
export declare type NumberSchemaType<T extends number = number, R extends boolean = false> = T | (R extends true ? never : null);
export interface NumberOptions<T extends number = number, R extends boolean = false> extends SchemaOptions {

@@ -8,0 +7,0 @@ readonly value?: number | null;

import type { Schema, Schemas, SchemasType, SchemaOptions } from "../Schema";
import type { NullIfOptional, UnknownObject } from "../types";
import type { UnknownObject } from "../types";
import { Invalid } from "../helpers/message";
/** Coerce an unknown value to an object (if possible). */
export declare function coerceObject(value: unknown): UnknownObject | null | Invalid;
export declare type ObjectSchemaType<S extends Schemas = Schemas, R extends boolean = false> = Readonly<SchemasType<S>> | NullIfOptional<R>;
export declare type ObjectSchemaType<S extends Schemas = Schemas, R extends boolean = false> = Readonly<SchemasType<S>> | (R extends true ? never : null);
export interface ObjectSchemaOptions<S extends Schemas = Schemas, R extends boolean = false> extends SchemaOptions {
readonly props: S;
readonly value?: SchemasType<S> | NullIfOptional<R>;
readonly value?: ObjectSchemaType<S, R>;
readonly required?: R;

@@ -11,0 +11,0 @@ }

@@ -1,35 +0,19 @@

import type { Schema, SchemaOptions } from "../Schema";
import type { NullIfOptional } from "../types";
import { Invalid } from "../helpers/message";
/** Coerce an unknown value into a phone number (if possible). */
export declare function coercePhone(value: unknown): string | null | Invalid;
export declare type PhoneSchemaType<R extends boolean = boolean> = string | NullIfOptional<R>;
export interface PhoneOptions<R extends boolean = false> extends SchemaOptions {
readonly value?: string | null;
readonly required?: R;
}
import { StringOptions, StringSchema } from "./StringSchema";
/**
* Schema that defines a valid phone number.
* Multiple string formats are automatically converted to E.164 format.
*
* `null` is also a valid value if this field is not required.
* Falsy values and empty strings are converted to `null`
* Type of `StringSchema` that defines a valid phone number.
* - Multiple string formats are automatically converted to E.164 format (starting with `+` plus).
* - Falsy values are converted to `""` empty string.
*/
export declare class PhoneSchema<R extends boolean = false> implements Schema<PhoneSchemaType<R>> {
readonly title: string;
readonly description: string;
readonly placeholder: string;
readonly value: string | null;
readonly required: R;
export declare class PhoneSchema<T extends string = string, R extends boolean = false> extends StringSchema<T, R> {
readonly match: RegExp;
readonly max: number;
constructor({ title, description, placeholder, value, required }?: PhoneOptions<R>);
validate(unsafeValue?: unknown): PhoneSchemaType<R> | Invalid;
clean(str: string): string;
}
/** Shortcuts for PhoneSchema. */
export declare const phone: {
(options: PhoneOptions<false>): PhoneSchema<false>;
(options: PhoneOptions<true>): PhoneSchema<true>;
(): PhoneSchema<false>;
required: PhoneSchema<true>;
optional: PhoneSchema<false>;
<T extends string>(options: StringOptions<T, false>): PhoneSchema<T, false>;
<T extends string>(options: StringOptions<T, true>): PhoneSchema<T, true>;
(): PhoneSchema<string, false>;
required: PhoneSchema<string, true>;
optional: PhoneSchema<string, false>;
};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.phone = exports.PhoneSchema = exports.coercePhone = void 0;
const message_1 = require("../helpers/message");
exports.phone = exports.PhoneSchema = void 0;
const StringSchema_1 = require("./StringSchema");
/**

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

*/
function cleanPhone(value) {
const cleanPhone = (value) => {
// Strip characters that aren't 0-9 or `+` plus (including whitespace).

@@ -15,14 +15,3 @@ const digits = value.replace(/[^0-9+]/g, "");

return digits.substr(0, 1) + digits.substr(1).replace(/[^0-9]/g, "");
}
/** Coerce an unknown value into a phone number (if possible). */
function coercePhone(value) {
if (!value)
return null; // Convert falsy to null (including empty string).
if (typeof value === "number")
return value.toString();
if (typeof value === "string")
return cleanPhone(value) || null; // Return the clean phone number (also convert empty string to null).
return new message_1.Invalid("Must be string or null");
}
exports.coercePhone = coercePhone;
};
// Valid phone number is max 16 digits made up of:

@@ -33,39 +22,14 @@ // - Country code (`+` plus character and 1-3 digits, e.g. `+44` or `+1`).

/**
* Schema that defines a valid phone number.
* Multiple string formats are automatically converted to E.164 format.
*
* `null` is also a valid value if this field is not required.
* Falsy values and empty strings are converted to `null`
* Type of `StringSchema` that defines a valid phone number.
* - Multiple string formats are automatically converted to E.164 format (starting with `+` plus).
* - Falsy values are converted to `""` empty string.
*/
class PhoneSchema {
constructor({ title = "", description = "", placeholder = "", value = null, required = false } = {}) {
class PhoneSchema extends StringSchema_1.StringSchema {
constructor() {
super(...arguments);
this.match = R_PHONE;
this.max = 16; // Valid phone number is 16 digits or fewer (15 numerals with a leading `+` plus).
this.title = title;
this.description = description;
this.placeholder = placeholder;
this.value = value;
this.required = required;
}
validate(unsafeValue = this.value) {
// Coorce.
const value = coercePhone(unsafeValue);
if (value instanceof message_1.Invalid)
return value;
// Null means 'no phone'
if (!value) {
// Check requiredness.
if (this.required)
return new message_1.Required("Required");
// Return null.
// We know this type assertion is sound because `null` can never be returned if `this.required == true`.
return null;
}
// Check length.
if (value.length > this.max)
return new message_1.Invalid(`Maximum ${this.max} characters`);
// Check format.
if (!R_PHONE.test(value))
return new message_1.Invalid("Invalid phone number (must be an international number starting with `+` plus)");
// Return phone.
return value;
clean(str) {
return cleanPhone(super.clean(str));
}

@@ -72,0 +36,0 @@ }

import type { Schema, SchemaOptions } from "../Schema";
import type { EmptyIfOptional } from "../types";
import { Invalid } from "../helpers/message";
/** Coerce an unknown value to a string (if possible). */
export declare function coerceString(value: unknown): string | Invalid;
export declare type StringSchemaType<T extends string = string, R extends boolean = boolean> = T | EmptyIfOptional<R>;
export interface StringOptions<T extends string = string, R extends boolean = false> extends SchemaOptions {
export declare type StringSchemaType<T extends string = string, R extends boolean = boolean> = T | (R extends true ? never : "");
export interface StringOptions<T extends string = string, R extends boolean = boolean> extends SchemaOptions {
readonly value?: string;

@@ -54,6 +53,6 @@ readonly required?: R;

/**
* Clean a phone number string by removing characters that aren't digits.
* Clean a string by removing characters that aren't digits.
* Might be empty string if the string contained only invalid characters.
*/
clean(value: string): string;
clean(str: string): string;
}

@@ -60,0 +59,0 @@ /** Shortcuts for StringSchema. */

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

// Strip control characters.
const value = uncleanValue.trim().replace(this.multiline ? R_CONTROL_CHARS_MULTILINE : R_CONTROL_CHARS, "");
const value = this.clean(uncleanValue);
// Empty?

@@ -67,3 +67,3 @@ if (!value.length) {

// Return.
return "";
return value;
}

@@ -95,8 +95,8 @@ // Check max.

/**
* Clean a phone number string by removing characters that aren't digits.
* Clean a string by removing characters that aren't digits.
* Might be empty string if the string contained only invalid characters.
*/
clean(value) {
clean(str) {
// Trim and always strip `\r` — only strip `\n` if multiline is truthy.
return value.trim().replace(this.multiline ? R_CONTROL_CHARS_MULTILINE : R_CONTROL_CHARS, "");
return str.trim().replace(this.multiline ? R_CONTROL_CHARS_MULTILINE : R_CONTROL_CHARS, "");
}

@@ -103,0 +103,0 @@ }

@@ -1,43 +0,27 @@

import type { NullIfOptional } from "../types";
import type { Schema, SchemaOptions } from "../Schema";
import { Invalid } from "../helpers/message";
/** Coerce an unknown value to a URL (if possible). */
export declare function coerceUrl(value: unknown): string | null | Invalid;
export declare type UrlSchemaType<R extends boolean = boolean> = string | NullIfOptional<R>;
interface UrlOptions<R extends boolean = false> extends SchemaOptions {
readonly value?: string | null;
readonly required?: R;
import { StringOptions, StringSchema, StringSchemaType } from "./StringSchema";
export interface UrlOptions<T extends string = string, R extends boolean = false> extends StringOptions<T, R> {
readonly schemes?: string[];
readonly hosts?: string[] | null;
readonly max?: number;
}
/**
* Schema that defines a valid URL.
*
* Ensures value is a string, enforces that the string is a valid URL.
* Checks URL scheme against a whitelist (always), and checks URL domain against a whitelist (optional).
* `null` is also a valid value if this field is not required.
*
* URLs are limited to 512 characters (this can be changed with `max`), but generally these won't be data: URIs so this is a reasonable limit.
* Type of `StringSchema` that defines a valid URL.
* - Checks URL scheme against a whitelist (always), and checks URL domain against a whitelist (optional).
* - URLs are limited to 512 characters, but generally these won't be data: URIs so this is a reasonable limit.
* - Falsy values are converted to `""` empty string.
*/
export declare class UrlSchema<R extends boolean = false> implements Schema<UrlSchemaType<R>> {
readonly title: string;
readonly description: string;
readonly placeholder: string;
readonly value: string | null;
readonly required: R;
export declare class UrlSchema<T extends string, R extends boolean = false> extends StringSchema<T, R> {
readonly schemes: string[];
readonly hosts: string[] | null;
readonly max: number;
constructor({ title, description, placeholder, value, required, schemes, hosts, max, }?: UrlOptions<R>);
validate(unsafeValue?: unknown): UrlSchemaType<R> | Invalid;
readonly max = 512;
constructor({ schemes, hosts, ...options }?: UrlOptions<T, R>);
validate(unsafeValue?: unknown): StringSchemaType<T, R> | Invalid;
}
/** Shortcuts for UrlSchema. */
export declare const url: {
(options: UrlOptions<false>): UrlSchema<false>;
(options: UrlOptions<true>): UrlSchema<true>;
(): UrlSchema<false>;
required: UrlSchema<true>;
optional: UrlSchema<false>;
<T extends string>(options: UrlOptions<T, false>): UrlSchema<T, false>;
<T extends string>(options: UrlOptions<T, true>): UrlSchema<T, true>;
(): UrlSchema<string, false>;
required: UrlSchema<string, true>;
optional: UrlSchema<string, false>;
};
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.url = exports.UrlSchema = exports.coerceUrl = void 0;
exports.url = exports.UrlSchema = void 0;
const message_1 = require("../helpers/message");
/** Coerce an unknown value to a URL (if possible). */
function coerceUrl(value) {
if (!value)
return null; // Convert falsy to null.
if (typeof value === "string")
return value.trim() || null;
return new message_1.Invalid("Must be string or null");
}
exports.coerceUrl = coerceUrl;
const StringSchema_1 = require("./StringSchema");
/**
* Schema that defines a valid URL.
*
* Ensures value is a string, enforces that the string is a valid URL.
* Checks URL scheme against a whitelist (always), and checks URL domain against a whitelist (optional).
* `null` is also a valid value if this field is not required.
*
* URLs are limited to 512 characters (this can be changed with `max`), but generally these won't be data: URIs so this is a reasonable limit.
* Type of `StringSchema` that defines a valid URL.
* - Checks URL scheme against a whitelist (always), and checks URL domain against a whitelist (optional).
* - URLs are limited to 512 characters, but generally these won't be data: URIs so this is a reasonable limit.
* - Falsy values are converted to `""` empty string.
*/
class UrlSchema {
constructor({ title = "", description = "", placeholder = "", value = null, required = false, schemes = ["http:", "https:"], hosts = null, max = 512, } = {}) {
class UrlSchema extends StringSchema_1.StringSchema {
constructor({ schemes = ["http:", "https:"], hosts = null, ...options } = {}) {
super(options);
this.max = 512;
this.title = title;
this.description = description;
this.placeholder = placeholder;
this.value = value;
this.required = required;
this.schemes = schemes;
this.hosts = hosts;
this.max = max;
}
validate(unsafeValue = this.value) {
// Coorce.
const value = coerceUrl(unsafeValue);
const value = super.validate(unsafeValue);
if (value instanceof message_1.Invalid)
return value;
// Null means 'no URL'
if (value === null) {
// Check requiredness.
if (this.required)
return new message_1.Required("Required");
// Return null.
// We know this type assertion is sound because `null` can never be returned if `this.required == true`.
return null;
}
if (!value)
return value;
// Parse the URL using URL class (available in Node 10 and modern browsers).

@@ -57,7 +34,4 @@ let u;

// Definitely not valid.
return new message_1.Invalid("Invalid URL format");
return new message_1.Invalid("Invalid format");
}
// Check length again.
if (u.href.length > this.max)
return new message_1.Invalid(`Maximum ${this.max} characters`);
// Check scheme and domain exist in whitelists.

@@ -72,3 +46,3 @@ if (!this.schemes.includes(u.protocol))

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

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

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

@@ -81,0 +55,0 @@ // Return the normalised URL.

@@ -1,7 +0,1 @@

/** Helper type that allows `null` if `R` (required) is false. */
export declare type NullIfOptional<R extends boolean> = R extends true ? never : null;
/** Helper type that allows `false` if `R` (required) is false. */
export declare type FalseIfOptional<R extends boolean> = R extends true ? never : false;
/** Helper type that allows empty string if `R` (required) is false. */
export declare type EmptyIfOptional<R extends boolean> = R extends true ? never : "";
/**

@@ -8,0 +2,0 @@ * Unknown object: an object whose properties are unknown.

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

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

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