schemaglobin
Advanced tools
Comparing version 2.0.0 to 3.0.0
@@ -1,4 +0,4 @@ | ||
import { Schema, SchemaOptions, SchemaType } from "../types"; | ||
import { Schema, SchemaWithSchemas, SchemaOptions, SchemaType } from "../types"; | ||
import { Invalid } from "../Invalid"; | ||
interface ArrayOptions<S extends Schema = Schema, R extends boolean = false> extends SchemaOptions<R> { | ||
interface ArrayOptions<S extends Schema = Schema, R extends boolean = false> extends SchemaOptions { | ||
readonly items: S; | ||
@@ -8,2 +8,3 @@ readonly value?: ReadonlyArray<SchemaType<S>>; | ||
readonly max?: number | null; | ||
readonly required?: R; | ||
} | ||
@@ -37,3 +38,3 @@ /** | ||
*/ | ||
export declare class ArraySchema<S extends Schema = Schema, R extends boolean = false> implements Schema<ReadonlyArray<SchemaType<S>>, R> { | ||
export declare class ArraySchema<S extends Schema = Schema, R extends boolean = false> implements SchemaWithSchemas<ReadonlyArray<SchemaType<S>>> { | ||
readonly title: string; | ||
@@ -54,2 +55,3 @@ readonly description: string; | ||
constructor({ title, description, placeholder, value, required, min, max, items, }: ArrayOptions<S, R>); | ||
schema(): S; | ||
private coerce; | ||
@@ -56,0 +58,0 @@ validate(unsafeValue?: unknown): ReadonlyArray<SchemaType<S>> | Invalid; |
@@ -47,2 +47,6 @@ "use strict"; | ||
} | ||
// Implement SchemasSchema | ||
schema() { | ||
return this.items; | ||
} | ||
coerce(value) { | ||
@@ -49,0 +53,0 @@ if (!value) |
import { Schema, SchemaOptions, FalseIfOptional } from "../types"; | ||
import { Invalid } from "../Invalid"; | ||
declare type BooleanOptions<R extends boolean> = SchemaOptions<R>; | ||
interface BooleanOptions<R extends boolean> extends SchemaOptions { | ||
readonly value?: boolean; | ||
readonly required?: R; | ||
} | ||
/** | ||
* Schema that defines a valid boolean. | ||
*/ | ||
export declare class BooleanSchema<R extends boolean = false> implements Schema<true | FalseIfOptional<R>, R> { | ||
export declare class BooleanSchema<R extends boolean = false> implements Schema<true | FalseIfOptional<R>> { | ||
readonly title: string; | ||
readonly description: string; | ||
readonly placeholder: string; | ||
readonly value: unknown; | ||
readonly value: boolean; | ||
readonly required: R; | ||
@@ -13,0 +16,0 @@ constructor({ title, description, placeholder, value, required, }?: BooleanOptions<R>); |
@@ -8,3 +8,4 @@ import { Schema, SchemaOptions, NullIfOptional } from "../types"; | ||
export declare type DateInputs = Date | string | number | null | (() => DateInputs); | ||
export interface DateOptions<R extends boolean = false> extends SchemaOptions<R> { | ||
export interface DateOptions<R extends boolean = false> extends SchemaOptions { | ||
readonly required?: R; | ||
readonly value?: DateInputs; | ||
@@ -19,3 +20,3 @@ readonly min?: DateInputs; | ||
*/ | ||
export declare class DateSchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>, R> { | ||
export declare class DateSchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>> { | ||
readonly title: string; | ||
@@ -22,0 +23,0 @@ readonly description: string; |
import { Schema, SchemaOptions, NullIfOptional } from "../types"; | ||
import { Invalid } from "../Invalid"; | ||
interface EmailOptions<R extends boolean = false> extends SchemaOptions<R> { | ||
value?: string | null; | ||
interface EmailOptions<R extends boolean = false> extends SchemaOptions { | ||
readonly value?: string | null; | ||
readonly required?: R; | ||
} | ||
@@ -25,3 +26,3 @@ /** | ||
*/ | ||
export declare class EmailSchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>, R> { | ||
export declare class EmailSchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>> { | ||
readonly title: string; | ||
@@ -28,0 +29,0 @@ readonly description: string; |
import { Schema, SchemaOptions, NullIfOptional } from "../types"; | ||
import { Invalid } from "../Invalid"; | ||
interface KeyOptions<R extends boolean = false> extends SchemaOptions<R> { | ||
interface KeyOptions<R extends boolean = false> extends SchemaOptions { | ||
readonly value?: string | null; | ||
readonly required?: R; | ||
readonly match?: RegExp; | ||
@@ -14,3 +15,3 @@ } | ||
*/ | ||
export declare class KeySchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>, R> { | ||
export declare class KeySchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>> { | ||
readonly title: string; | ||
@@ -17,0 +18,0 @@ readonly description: string; |
@@ -1,6 +0,7 @@ | ||
import { Schema, SchemaOptions, SchemaType } from "../types"; | ||
import { Schema, SchemaWithSchemas, SchemaOptions, SchemaType } from "../types"; | ||
import { Invalid } from "../Invalid"; | ||
interface MapOptions<S extends Schema = Schema, R extends boolean = false> extends SchemaOptions<R> { | ||
interface MapOptions<S extends Schema = Schema, R extends boolean = false> extends SchemaOptions { | ||
readonly items: S; | ||
readonly value?: Record<string, SchemaType<S>> | null; | ||
readonly required?: R; | ||
readonly min?: number | null; | ||
@@ -13,3 +14,3 @@ readonly max?: number | null; | ||
*/ | ||
export declare class MapSchema<S extends Schema = Schema, R extends boolean = false> implements Schema<Readonly<Record<string, SchemaType<S>>>, R> { | ||
export declare class MapSchema<S extends Schema = Schema, R extends boolean = false> implements SchemaWithSchemas<Readonly<Record<string, SchemaType<S>>>> { | ||
readonly title: string; | ||
@@ -32,2 +33,3 @@ readonly description: string; | ||
constructor({ title, description, placeholder, value, required, items, min, max, }: MapOptions<S, R>); | ||
schema(): S; | ||
private coerce; | ||
@@ -34,0 +36,0 @@ validate(unsafeValue?: unknown): Readonly<Record<string, SchemaType<S>>> | Invalid; |
@@ -25,2 +25,6 @@ "use strict"; | ||
} | ||
// Implement SchemasSchema | ||
schema() { | ||
return this.items; | ||
} | ||
coerce(value) { | ||
@@ -27,0 +31,0 @@ if (!value) |
import { Schema, SchemaOptions, NullIfOptional } from "../types"; | ||
import { Invalid } from "../Invalid"; | ||
interface NumberOptions<T extends number = number, R extends boolean = false> extends SchemaOptions<R> { | ||
interface NumberOptions<T extends number = number, R extends boolean = false> extends SchemaOptions { | ||
readonly value?: T | null; | ||
readonly required?: R; | ||
readonly min?: number | null; | ||
@@ -16,3 +17,3 @@ readonly max?: number | null; | ||
*/ | ||
export declare class NumberSchema<T extends number = number, R extends boolean = false> implements Schema<T | NullIfOptional<R>, R> { | ||
export declare class NumberSchema<T extends number = number, R extends boolean = false> implements Schema<T | NullIfOptional<R>> { | ||
readonly title: string; | ||
@@ -19,0 +20,0 @@ readonly description: string; |
@@ -1,6 +0,6 @@ | ||
import { Schema, SchemaOptions, SchemaType, NullIfOptional } from "../types"; | ||
import { Schema, SchemaWithSchemas, SchemaOptions, SchemaType, NullIfOptional } from "../types"; | ||
import { Invalid } from "../Invalid"; | ||
interface ObjectOptions<S extends { | ||
[prop: string]: Schema; | ||
} = {}, R extends boolean = false> extends SchemaOptions<R> { | ||
} = {}, R extends boolean = false> extends SchemaOptions { | ||
readonly props: S; | ||
@@ -10,2 +10,3 @@ readonly value?: { | ||
} | NullIfOptional<R>; | ||
readonly required?: R; | ||
} | ||
@@ -20,5 +21,5 @@ /** | ||
[prop: string]: Schema; | ||
} = {}, R extends boolean = false> implements Schema<Readonly<{ | ||
} = {}, R extends boolean = false> implements SchemaWithSchemas<Readonly<{ | ||
[K in keyof S]: SchemaType<S[K]>; | ||
}> | NullIfOptional<R>, R> { | ||
}> | NullIfOptional<R>> { | ||
readonly title: string; | ||
@@ -41,8 +42,4 @@ readonly description: string; | ||
}> | NullIfOptional<R> | Invalid; | ||
schema<K extends keyof S & string>(key: K): S[K]; | ||
/** | ||
* Get the schema that will be used to validate a named prop in this object.. | ||
* Returns the schema named in `this.props` (if it exists), or `undefined` (if it doesn't). | ||
*/ | ||
getProp<K extends keyof S & string>(key: K): S[K]; | ||
/** | ||
* Validate an object's contents. | ||
@@ -49,0 +46,0 @@ * Only returns a new instance of the object if it has changed (for immutability). |
@@ -43,7 +43,4 @@ "use strict"; | ||
} | ||
/** | ||
* Get the schema that will be used to validate a named prop in this object.. | ||
* Returns the schema named in `this.props` (if it exists), or `undefined` (if it doesn't). | ||
*/ | ||
getProp(key) { | ||
// Implement SchemasSchema | ||
schema(key) { | ||
return this.props[key]; | ||
@@ -50,0 +47,0 @@ } |
import { Schema, SchemaOptions, NullIfOptional } from "../types"; | ||
import { Invalid } from "../Invalid"; | ||
interface PhoneOptions<R extends boolean = false> extends SchemaOptions<R> { | ||
value?: string | null; | ||
interface PhoneOptions<R extends boolean = false> extends SchemaOptions { | ||
readonly value?: string | null; | ||
readonly required?: R; | ||
} | ||
@@ -13,3 +14,3 @@ /** | ||
*/ | ||
export declare class PhoneSchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>, R> { | ||
export declare class PhoneSchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>> { | ||
readonly title: string; | ||
@@ -16,0 +17,0 @@ readonly description: string; |
import { Schema, SchemaOptions, EmptyIfOptional } from "../types"; | ||
import { Invalid } from "../Invalid"; | ||
interface StringOptions<T extends string = string, R extends boolean = false> extends SchemaOptions<R> { | ||
interface StringOptions<T extends string = string, R extends boolean = false> extends SchemaOptions { | ||
readonly value?: string | number | null; | ||
readonly required?: R; | ||
readonly min?: number; | ||
@@ -33,3 +34,3 @@ readonly max?: number | null; | ||
*/ | ||
export declare class StringSchema<T extends string = string, R extends boolean = false> implements Schema<T | EmptyIfOptional<R>, R> { | ||
export declare class StringSchema<T extends string = string, R extends boolean = false> implements Schema<T | EmptyIfOptional<R>> { | ||
readonly title: string; | ||
@@ -36,0 +37,0 @@ readonly description: string; |
import { Schema, SchemaOptions, NullIfOptional } from "../types"; | ||
import { Invalid } from "../Invalid"; | ||
interface UrlOptions<R extends boolean = false> extends SchemaOptions<R> { | ||
interface UrlOptions<R extends boolean = false> extends SchemaOptions { | ||
readonly value?: string | null; | ||
readonly required?: R; | ||
readonly schemes?: string[]; | ||
@@ -18,3 +19,3 @@ readonly hosts?: string[] | null; | ||
*/ | ||
export declare class UrlSchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>, R> { | ||
export declare class UrlSchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>> { | ||
readonly title: string; | ||
@@ -21,0 +22,0 @@ readonly description: string; |
@@ -6,8 +6,6 @@ import { Invalid } from "./Invalid"; | ||
*/ | ||
export interface Schema<T = unknown, R extends boolean = boolean> { | ||
export interface Schema<T = unknown> { | ||
readonly title: string; | ||
readonly description: string; | ||
readonly placeholder: string; | ||
readonly value: unknown; | ||
readonly required: R; | ||
/** | ||
@@ -20,2 +18,10 @@ * `validate()` method accepts an unsafe value and returns a valid value. | ||
/** | ||
* Schemas that validate the contents of objects also implement a `schema(name)` method. | ||
* This is used by both `ObjectSchema`, `MapSchema`, `ArraySchema`, since they all work on objects or arrays. | ||
*/ | ||
export interface SchemaWithSchemas<T extends unknown> extends Schema<T> { | ||
/** Get the `Schema` instance that would be used to validate a specific property or named item. */ | ||
schema<K extends keyof T & string>(prop: K): Schema; | ||
} | ||
/** | ||
* Helper types that extracts the type from a Schema type. | ||
@@ -26,18 +32,11 @@ * | ||
*/ | ||
export declare type SchemaType<X extends Schema | undefined, Y = never> = X extends Schema<infer T, boolean> ? T : Y; | ||
export declare type SchemaType<X extends Schema | undefined, Y = never> = X extends Schema<infer T> ? T : Y; | ||
/** | ||
* Helper types that extracts whether a schema is required (or not) from a Schema type. | ||
* @param X Schema instance to extract the type from. | ||
*/ | ||
export declare type SchemaRequired<X extends Schema | undefined> = X extends Schema<unknown, infer R> ? R : never; | ||
/** | ||
* SchemaOptions enforces types on the options bag that is passed into SchemaClass to create Schema. | ||
* Most schemas will allow additional options but these options are enforced. | ||
*/ | ||
export interface SchemaOptions<R extends boolean> { | ||
export interface SchemaOptions { | ||
readonly title?: string; | ||
readonly description?: string; | ||
readonly placeholder?: string; | ||
readonly value?: unknown; | ||
readonly required?: R; | ||
} | ||
@@ -44,0 +43,0 @@ /** |
{ | ||
"name": "schemaglobin", | ||
"description": "Validate user-entered data.", | ||
"version": "2.0.0", | ||
"version": "3.0.0", | ||
"repository": "https://github.com/dhoulb/schemaglobin", | ||
@@ -6,0 +6,0 @@ "author": "Dave Houlbrooke <dave@shax.com>", |
@@ -266,6 +266,6 @@ # Schemaglobin: Validate unknown user input against schemas | ||
Schemaglobin also provides the `SchemaType<Schema>` and `SchemaRequired<Schema>` helper type, which allow you to extract the type of a schema and whether or not it is required: | ||
Schemaglobin also provides the `SchemaType<Schema>` helper type, which allow you to extract the type of a schema: | ||
```ts | ||
import { string } from "schemaglobin"; | ||
import { string, SchemaType } from "schemaglobin"; | ||
@@ -293,4 +293,2 @@ // Make some schemas. | ||
- `options.value: any = any` - The default value of the schema which will be used if the value is `undefined` | ||
- `options.required: boolean = false` - If true, then `null` or empty values will return `Invalid("Required")` | ||
- `options.title: string = ""` - A title for the schema (for showing in a user-facing field). | ||
@@ -310,2 +308,7 @@ - `options.description: string = ""` - A description for the schema (for showing in a user-facing field). | ||
`boolean()` also allows the following options: | ||
- `options.value: boolean = false` - The default value which will be used if the value is `undefined` | ||
- `options.required: boolean = false` - If true, then false values will return `Invalid("Required")` | ||
### `string()` | ||
@@ -326,2 +329,4 @@ | ||
- `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. | ||
@@ -346,2 +351,4 @@ - `options.max: number = null` - The maximum number of characters allowed. | ||
- `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. | ||
@@ -368,2 +375,4 @@ - `options.max: number = null` - The maximum number allowed. | ||
- `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: string = null` - The minimum date allowed. | ||
@@ -382,2 +391,7 @@ - `options.max: string = null` - The maximum date allowed. | ||
`email()` 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")` | ||
### `url()` | ||
@@ -392,4 +406,6 @@ | ||
`date()` also allows the following options: | ||
`url()` 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. | ||
@@ -409,2 +425,7 @@ - `options.hosts: string[] = null` - List of allowed hostnames, e.g. `["google.com"]` | ||
`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")` | ||
### `key()` | ||
@@ -422,2 +443,4 @@ | ||
- `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. | ||
@@ -437,2 +460,4 @@ | ||
- `options.value: {} | 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.props: { [prop: string]: Schema }` (required) - An object explicitly specifying the type of each individual property. | ||
@@ -451,2 +476,4 @@ | ||
- `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. | ||
@@ -467,2 +494,4 @@ - `options.max: number = null` - The maximum number of items allowed. | ||
- `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. | ||
@@ -518,2 +547,2 @@ - `options.max: number = null` - The maximum number of items allowed. | ||
See [Releases](https://github.com/dhoulb/blork/releases) | ||
See [Releases](https://github.com/dhoulb/schemaglobin/releases) |
@@ -1,6 +0,6 @@ | ||
import { Schema, SchemaOptions, SchemaType } from "../types"; | ||
import { Schema, SchemaWithSchemas, SchemaOptions, SchemaType } from "../types"; | ||
import { Invalid } from "../Invalid"; | ||
// Options. | ||
interface ArrayOptions<S extends Schema = Schema, R extends boolean = false> extends SchemaOptions<R> { | ||
interface ArrayOptions<S extends Schema = Schema, R extends boolean = false> extends SchemaOptions { | ||
readonly items: S; | ||
@@ -10,2 +10,3 @@ readonly value?: ReadonlyArray<SchemaType<S>>; | ||
readonly max?: number | null; | ||
readonly required?: R; | ||
} | ||
@@ -41,3 +42,3 @@ | ||
export class ArraySchema<S extends Schema = Schema, R extends boolean = false> | ||
implements Schema<ReadonlyArray<SchemaType<S>>, R> { | ||
implements SchemaWithSchemas<ReadonlyArray<SchemaType<S>>> { | ||
readonly title: string; | ||
@@ -80,2 +81,7 @@ readonly description: string; | ||
// Implement SchemasSchema | ||
schema(): S { | ||
return this.items; | ||
} | ||
private coerce(value: unknown): unknown[] | Invalid { | ||
@@ -82,0 +88,0 @@ if (!value) return []; // Convert falsy to empty array. |
@@ -5,3 +5,6 @@ import { Schema, SchemaOptions, FalseIfOptional } from "../types"; | ||
// Options. | ||
type BooleanOptions<R extends boolean> = SchemaOptions<R>; | ||
interface BooleanOptions<R extends boolean> extends SchemaOptions { | ||
readonly value?: boolean; | ||
readonly required?: R; | ||
} | ||
@@ -11,7 +14,7 @@ /** | ||
*/ | ||
export class BooleanSchema<R extends boolean = false> implements Schema<true | FalseIfOptional<R>, R> { | ||
export class BooleanSchema<R extends boolean = false> implements Schema<true | FalseIfOptional<R>> { | ||
readonly title: string; | ||
readonly description: string; | ||
readonly placeholder: string; | ||
readonly value: unknown; | ||
readonly value: boolean; | ||
readonly required: R; | ||
@@ -18,0 +21,0 @@ |
@@ -21,3 +21,4 @@ import { Schema, SchemaOptions, NullIfOptional } from "../types"; | ||
export type DateInputs = Date | string | number | null | (() => DateInputs); | ||
export interface DateOptions<R extends boolean = false> extends SchemaOptions<R> { | ||
export interface DateOptions<R extends boolean = false> extends SchemaOptions { | ||
readonly required?: R; | ||
readonly value?: DateInputs; | ||
@@ -33,3 +34,3 @@ readonly min?: DateInputs; | ||
*/ | ||
export class DateSchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>, R> { | ||
export class DateSchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>> { | ||
readonly title: string; | ||
@@ -36,0 +37,0 @@ readonly description: string; |
@@ -8,4 +8,5 @@ import { Schema, SchemaOptions, NullIfOptional } from "../types"; | ||
// Options. | ||
interface EmailOptions<R extends boolean = false> extends SchemaOptions<R> { | ||
value?: string | null; | ||
interface EmailOptions<R extends boolean = false> extends SchemaOptions { | ||
readonly value?: string | null; | ||
readonly required?: R; | ||
} | ||
@@ -32,3 +33,3 @@ | ||
*/ | ||
export class EmailSchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>, R> { | ||
export class EmailSchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>> { | ||
readonly title: string; | ||
@@ -35,0 +36,0 @@ readonly description: string; |
@@ -8,4 +8,5 @@ import { Schema, SchemaOptions, NullIfOptional } from "../types"; | ||
// Options. | ||
interface KeyOptions<R extends boolean = false> extends SchemaOptions<R> { | ||
interface KeyOptions<R extends boolean = false> extends SchemaOptions { | ||
readonly value?: string | null; | ||
readonly required?: R; | ||
readonly match?: RegExp; | ||
@@ -21,3 +22,3 @@ } | ||
*/ | ||
export class KeySchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>, R> { | ||
export class KeySchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>> { | ||
readonly title: string; | ||
@@ -24,0 +25,0 @@ readonly description: string; |
@@ -1,8 +0,9 @@ | ||
import { Schema, SchemaOptions, SchemaType } from "../types"; | ||
import { Schema, SchemaWithSchemas, SchemaOptions, SchemaType } from "../types"; | ||
import { Invalid } from "../Invalid"; | ||
// Options. | ||
interface MapOptions<S extends Schema = Schema, R extends boolean = false> extends SchemaOptions<R> { | ||
interface MapOptions<S extends Schema = Schema, R extends boolean = false> extends SchemaOptions { | ||
readonly items: S; | ||
readonly value?: Record<string, SchemaType<S>> | null; | ||
readonly required?: R; | ||
readonly min?: number | null; | ||
@@ -17,3 +18,3 @@ readonly max?: number | null; | ||
export class MapSchema<S extends Schema = Schema, R extends boolean = false> | ||
implements Schema<Readonly<Record<string, SchemaType<S>>>, R> { | ||
implements SchemaWithSchemas<Readonly<Record<string, SchemaType<S>>>> { | ||
readonly title: string; | ||
@@ -58,2 +59,7 @@ readonly description: string; | ||
// Implement SchemasSchema | ||
schema(): S { | ||
return this.items; | ||
} | ||
private coerce(value: unknown): Record<string, unknown> | Invalid { | ||
@@ -60,0 +66,0 @@ if (!value) return {}; // Convert falsy to empty object. |
@@ -9,4 +9,5 @@ import { Schema, SchemaOptions, NullIfOptional } from "../types"; | ||
// Options. | ||
interface NumberOptions<T extends number = number, R extends boolean = false> extends SchemaOptions<R> { | ||
interface NumberOptions<T extends number = number, R extends boolean = false> extends SchemaOptions { | ||
readonly value?: T | null; | ||
readonly required?: R; | ||
readonly min?: number | null; | ||
@@ -23,3 +24,3 @@ readonly max?: number | null; | ||
export class NumberSchema<T extends number = number, R extends boolean = false> | ||
implements Schema<T | NullIfOptional<R>, R> { | ||
implements Schema<T | NullIfOptional<R>> { | ||
readonly title: string; | ||
@@ -26,0 +27,0 @@ readonly description: string; |
@@ -1,2 +0,2 @@ | ||
import { Schema, SchemaOptions, SchemaType, NullIfOptional } from "../types"; | ||
import { Schema, SchemaWithSchemas, SchemaOptions, SchemaType, NullIfOptional } from "../types"; | ||
import { Invalid } from "../Invalid"; | ||
@@ -8,5 +8,6 @@ | ||
// Options. | ||
interface ObjectOptions<S extends { [prop: string]: Schema } = {}, R extends boolean = false> extends SchemaOptions<R> { | ||
interface ObjectOptions<S extends { [prop: string]: Schema } = {}, R extends boolean = false> extends SchemaOptions { | ||
readonly props: S; | ||
readonly value?: { [K in keyof S]: SchemaType<S[K]> } | NullIfOptional<R>; | ||
readonly required?: R; | ||
} | ||
@@ -21,3 +22,3 @@ | ||
export class ObjectSchema<S extends { [prop: string]: Schema } = {}, R extends boolean = false> | ||
implements Schema<Readonly<{ [K in keyof S]: SchemaType<S[K]> }> | NullIfOptional<R>, R> { | ||
implements SchemaWithSchemas<Readonly<{ [K in keyof S]: SchemaType<S[K]> }> | NullIfOptional<R>> { | ||
readonly title: string; | ||
@@ -78,7 +79,4 @@ readonly description: string; | ||
/** | ||
* Get the schema that will be used to validate a named prop in this object.. | ||
* Returns the schema named in `this.props` (if it exists), or `undefined` (if it doesn't). | ||
*/ | ||
getProp<K extends keyof S & string>(key: K): S[K] { | ||
// Implement SchemasSchema | ||
schema<K extends keyof S & string>(key: K): S[K] { | ||
return this.props[key]; | ||
@@ -85,0 +83,0 @@ } |
@@ -21,4 +21,5 @@ import { Schema, SchemaOptions, NullIfOptional } from "../types"; | ||
// Options. | ||
interface PhoneOptions<R extends boolean = false> extends SchemaOptions<R> { | ||
value?: string | null; | ||
interface PhoneOptions<R extends boolean = false> extends SchemaOptions { | ||
readonly value?: string | null; | ||
readonly required?: R; | ||
} | ||
@@ -33,3 +34,3 @@ | ||
*/ | ||
export class PhoneSchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>, R> { | ||
export class PhoneSchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>> { | ||
readonly title: string; | ||
@@ -36,0 +37,0 @@ readonly description: string; |
@@ -11,4 +11,5 @@ /* eslint-disable no-control-regex */ | ||
// Options. | ||
interface StringOptions<T extends string = string, R extends boolean = false> extends SchemaOptions<R> { | ||
interface StringOptions<T extends string = string, R extends boolean = false> extends SchemaOptions { | ||
readonly value?: string | number | null; | ||
readonly required?: R; | ||
readonly min?: number; | ||
@@ -42,3 +43,3 @@ readonly max?: number | null; | ||
export class StringSchema<T extends string = string, R extends boolean = false> | ||
implements Schema<T | EmptyIfOptional<R>, R> { | ||
implements Schema<T | EmptyIfOptional<R>> { | ||
readonly title: string; | ||
@@ -45,0 +46,0 @@ readonly description: string; |
@@ -5,4 +5,5 @@ import { Schema, SchemaOptions, NullIfOptional } from "../types"; | ||
// Options. | ||
interface UrlOptions<R extends boolean = false> extends SchemaOptions<R> { | ||
interface UrlOptions<R extends boolean = false> extends SchemaOptions { | ||
readonly value?: string | null; | ||
readonly required?: R; | ||
readonly schemes?: string[]; | ||
@@ -22,3 +23,3 @@ readonly hosts?: string[] | null; | ||
*/ | ||
export class UrlSchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>, R> { | ||
export class UrlSchema<R extends boolean = false> implements Schema<string | NullIfOptional<R>> { | ||
readonly title: string; | ||
@@ -25,0 +26,0 @@ readonly description: string; |
@@ -7,8 +7,6 @@ import { Invalid } from "./Invalid"; | ||
*/ | ||
export interface Schema<T = unknown, R extends boolean = boolean> { | ||
export interface Schema<T = unknown> { | ||
readonly title: string; // Title, e.g. for showing in fields. | ||
readonly description: string; // Description, e.g. for showing in fields. | ||
readonly placeholder: string; // Placeholder, e.g. for showing in fields. | ||
readonly value: unknown; // Default value (unsafe but only returned through validate()). | ||
readonly required: R; // Whether value is required. | ||
@@ -23,2 +21,11 @@ /** | ||
/** | ||
* Schemas that validate the contents of objects also implement a `schema(name)` method. | ||
* This is used by both `ObjectSchema`, `MapSchema`, `ArraySchema`, since they all work on objects or arrays. | ||
*/ | ||
export interface SchemaWithSchemas<T extends unknown> extends Schema<T> { | ||
/** Get the `Schema` instance that would be used to validate a specific property or named item. */ | ||
schema<K extends keyof T & string>(prop: K): Schema; | ||
} | ||
/** | ||
* Helper types that extracts the type from a Schema type. | ||
@@ -29,15 +36,9 @@ * | ||
*/ | ||
export type SchemaType<X extends Schema | undefined, Y = never> = X extends Schema<infer T, boolean> ? T : Y; | ||
export type SchemaType<X extends Schema | undefined, Y = never> = X extends Schema<infer T> ? T : Y; | ||
/** | ||
* Helper types that extracts whether a schema is required (or not) from a Schema type. | ||
* @param X Schema instance to extract the type from. | ||
*/ | ||
export type SchemaRequired<X extends Schema | undefined> = X extends Schema<unknown, infer R> ? R : never; | ||
/** | ||
* SchemaOptions enforces types on the options bag that is passed into SchemaClass to create Schema. | ||
* Most schemas will allow additional options but these options are enforced. | ||
*/ | ||
export interface SchemaOptions<R extends boolean> { | ||
export interface SchemaOptions { | ||
// Title of the schema, e.g. for using as the title of a corresponding field. | ||
@@ -49,6 +50,2 @@ readonly title?: string; | ||
readonly placeholder?: string; | ||
// Default value. | ||
readonly value?: unknown; | ||
// Whether the schema is required or not. | ||
readonly required?: R; | ||
} | ||
@@ -55,0 +52,0 @@ |
@@ -20,3 +20,3 @@ import { | ||
const r1: { num: number | null } | null | Invalid = s1.validate(); | ||
const ss1a: NumberSchema<number, false> = s1.getProp("num"); | ||
const ss1a: NumberSchema<number, false> = s1.schema("num"); | ||
const sr1a: number | null | Invalid = ss1a.validate(); | ||
@@ -30,3 +30,3 @@ const ss1b: NumberSchema<number, false> = s1.props.num; | ||
const r2: { num: number } | Invalid = s2.validate(); | ||
const ss2a: NumberSchema<number, true> = s2.getProp("num"); | ||
const ss2a: NumberSchema<number, true> = s2.schema("num"); | ||
const sr2a: number | Invalid = ss2a.validate(); | ||
@@ -33,0 +33,0 @@ const ss2b: NumberSchema<number, true> = s2.props.num; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
211063
4503
535