diff --git a/joi/joi-tests.ts b/joi/joi-tests.ts index 26048a9dc7..fc1f8ef25a 100644 --- a/joi/joi-tests.ts +++ b/joi/joi-tests.ts @@ -56,6 +56,7 @@ validOpts = {allowUnknown: bool}; validOpts = {skipFunctions: bool}; validOpts = {stripUnknown: bool}; validOpts = {language: bool}; +validOpts = {presence: str}; validOpts = {context: obj}; // --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- @@ -65,6 +66,34 @@ var renOpts: Joi.RenameOptions = null; renOpts = {alias: bool}; renOpts = {multiple: bool}; renOpts = {override: bool}; +renOpts = {ignoreUndefined: bool}; + +// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- + +var emailOpts: Joi.EmailOptions = null; + +emailOpts = {errorLevel: num}; +emailOpts = {errorLevel: bool}; +emailOpts = {tldWhitelist: strArr}; +emailOpts = {tldWhitelist: obj}; +emailOpts = {minDomainAtoms: num}; + +// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- + +var ipOpts: Joi.IpOptions = null; + +ipOpts = {version: str}; +ipOpts = {version: strArr}; +ipOpts = {cidr: str}; + +// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- + +var uriOpts: Joi.UriOptions = null; + +uriOpts = {scheme: str}; +uriOpts = {scheme: exp}; +uriOpts = {scheme: strArr}; +uriOpts = {scheme: expArr}; // --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- @@ -144,15 +173,30 @@ module common { anySchema = anySchema.valid(x); anySchema = anySchema.valid(x, x); anySchema = anySchema.valid([x, x, x]); + anySchema = anySchema.only(x); + anySchema = anySchema.only(x, x); + anySchema = anySchema.only([x, x, x]); + anySchema = anySchema.equal(x); + anySchema = anySchema.equal(x, x); + anySchema = anySchema.equal([x, x, x]); anySchema = anySchema.invalid(x); anySchema = anySchema.invalid(x, x); anySchema = anySchema.invalid([x, x, x]); + anySchema = anySchema.disallow(x); + anySchema = anySchema.disallow(x, x); + anySchema = anySchema.disallow([x, x, x]); + anySchema = anySchema.not(x); + anySchema = anySchema.not(x, x); + anySchema = anySchema.not([x, x, x]); + anySchema = anySchema.default(); anySchema = anySchema.default(x); + anySchema = anySchema.default(x, str); anySchema = anySchema.required(); anySchema = anySchema.optional(); anySchema = anySchema.forbidden(); + anySchema = anySchema.strip(); anySchema = anySchema.description(str); anySchema = anySchema.notes(str); @@ -166,43 +210,65 @@ module common { anySchema = anySchema.options(validOpts); anySchema = anySchema.strict(); + anySchema = anySchema.strict(bool); anySchema = anySchema.concat(x); altSchema = anySchema.when(str, whenOpts); altSchema = anySchema.when(ref, whenOpts); + + anySchema = anySchema.label(str); + anySchema = anySchema.raw(); + anySchema = anySchema.raw(bool); + anySchema = anySchema.empty(); + anySchema = anySchema.empty(str); + anySchema = anySchema.empty(anySchema); } // --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- arrSchema = Joi.array(); +arrSchema = arrSchema.sparse(); +arrSchema = arrSchema.sparse(bool); +arrSchema = arrSchema.single(); +arrSchema = arrSchema.single(bool); arrSchema = arrSchema.min(num); arrSchema = arrSchema.max(num); arrSchema = arrSchema.length(num); +arrSchema = arrSchema.unique(); -arrSchema = arrSchema.includes(numSchema); -arrSchema = arrSchema.includes(numSchema, strSchema); -arrSchema = arrSchema.includes([numSchema, strSchema]); +arrSchema = arrSchema.items(numSchema); +arrSchema = arrSchema.items(numSchema, strSchema); +arrSchema = arrSchema.items([numSchema, strSchema]); -arrSchema = arrSchema.excludes(numSchema); -arrSchema = arrSchema.excludes(numSchema, strSchema); -arrSchema = arrSchema.excludes([numSchema, strSchema]); // - - - - - - - - module common_copy_paste { // use search & replace from any - anySchema = anySchema.allow(x); - anySchema = anySchema.allow(x, x); - anySchema = anySchema.allow([x, x, x]); - anySchema = anySchema.valid(x); - anySchema = anySchema.valid(x, x); - anySchema = anySchema.valid([x, x, x]); - anySchema = anySchema.invalid(x); - anySchema = anySchema.invalid(x, x); - anySchema = anySchema.invalid([x, x, x]); - - anySchema = anySchema.default(x); + arrSchema = arrSchema.allow(x); + arrSchema = arrSchema.allow(x, x); + arrSchema = arrSchema.allow([x, x, x]); + arrSchema = arrSchema.valid(x); + arrSchema = arrSchema.valid(x, x); + arrSchema = arrSchema.valid([x, x, x]); + arrSchema = arrSchema.only(x); + arrSchema = arrSchema.only(x, x); + arrSchema = arrSchema.only([x, x, x]); + arrSchema = arrSchema.equal(x); + arrSchema = arrSchema.equal(x, x); + arrSchema = arrSchema.equal([x, x, x]); + arrSchema = arrSchema.invalid(x); + arrSchema = arrSchema.invalid(x, x); + arrSchema = arrSchema.invalid([x, x, x]); + arrSchema = arrSchema.disallow(x); + arrSchema = arrSchema.disallow(x, x); + arrSchema = arrSchema.disallow([x, x, x]); + arrSchema = arrSchema.not(x); + arrSchema = arrSchema.not(x, x); + arrSchema = arrSchema.not([x, x, x]); + + arrSchema = arrSchema.default(x); arrSchema = arrSchema.required(); arrSchema = arrSchema.optional(); @@ -238,10 +304,22 @@ module common_copy_paste { boolSchema = boolSchema.valid(x); boolSchema = boolSchema.valid(x, x); boolSchema = boolSchema.valid([x, x, x]); + boolSchema = boolSchema.only(x); + boolSchema = boolSchema.only(x, x); + boolSchema = boolSchema.only([x, x, x]); + boolSchema = boolSchema.equal(x); + boolSchema = boolSchema.equal(x, x); + boolSchema = boolSchema.equal([x, x, x]); boolSchema = boolSchema.invalid(x); boolSchema = boolSchema.invalid(x, x); boolSchema = boolSchema.invalid([x, x, x]); - + boolSchema = boolSchema.disallow(x); + boolSchema = boolSchema.disallow(x, x); + boolSchema = boolSchema.disallow([x, x, x]); + boolSchema = boolSchema.not(x); + boolSchema = boolSchema.not(x, x); + boolSchema = boolSchema.not([x, x, x]); + boolSchema = boolSchema.default(x); boolSchema = boolSchema.required(); @@ -270,6 +348,7 @@ module common_copy_paste { binSchema = Joi.binary(); +binSchema = binSchema.encoding(str); binSchema = binSchema.min(num); binSchema = binSchema.max(num); binSchema = binSchema.length(num); @@ -281,10 +360,22 @@ module common { binSchema = binSchema.valid(x); binSchema = binSchema.valid(x, x); binSchema = binSchema.valid([x, x, x]); + binSchema = binSchema.only(x); + binSchema = binSchema.only(x, x); + binSchema = binSchema.only([x, x, x]); + binSchema = binSchema.equal(x); + binSchema = binSchema.equal(x, x); + binSchema = binSchema.equal([x, x, x]); binSchema = binSchema.invalid(x); binSchema = binSchema.invalid(x, x); binSchema = binSchema.invalid([x, x, x]); - + binSchema = binSchema.disallow(x); + binSchema = binSchema.disallow(x, x); + binSchema = binSchema.disallow([x, x, x]); + binSchema = binSchema.not(x); + binSchema = binSchema.not(x, x); + binSchema = binSchema.not([x, x, x]); + binSchema = binSchema.default(x); binSchema = binSchema.required(); @@ -322,6 +413,14 @@ dateSchema = dateSchema.max(str); dateSchema = dateSchema.min(num); dateSchema = dateSchema.max(num); +dateSchema = dateSchema.min(ref); +dateSchema = dateSchema.max(ref); + +dateSchema = dateSchema.format(str); +dateSchema = dateSchema.format(strArr); + +dateSchema = dateSchema.iso(); + module common { dateSchema = dateSchema.allow(x); dateSchema = dateSchema.allow(x, x); @@ -329,10 +428,22 @@ module common { dateSchema = dateSchema.valid(x); dateSchema = dateSchema.valid(x, x); dateSchema = dateSchema.valid([x, x, x]); + dateSchema = dateSchema.only(x); + dateSchema = dateSchema.only(x, x); + dateSchema = dateSchema.only([x, x, x]); + dateSchema = dateSchema.equal(x); + dateSchema = dateSchema.equal(x, x); + dateSchema = dateSchema.equal([x, x, x]); dateSchema = dateSchema.invalid(x); dateSchema = dateSchema.invalid(x, x); dateSchema = dateSchema.invalid([x, x, x]); - + dateSchema = dateSchema.disallow(x); + dateSchema = dateSchema.disallow(x, x); + dateSchema = dateSchema.disallow([x, x, x]); + dateSchema = dateSchema.not(x); + dateSchema = dateSchema.not(x, x); + dateSchema = dateSchema.not([x, x, x]); + dateSchema = dateSchema.default(x); dateSchema = dateSchema.required(); @@ -366,8 +477,18 @@ funcSchema = Joi.func(); numSchema = Joi.number(); numSchema = numSchema.min(num); +numSchema = numSchema.min(ref); numSchema = numSchema.max(num); +numSchema = numSchema.max(ref); +numSchema = numSchema.greater(num); +numSchema = numSchema.greater(ref); +numSchema = numSchema.less(num); +numSchema = numSchema.less(ref); numSchema = numSchema.integer(); +numSchema = numSchema.precision(num); +numSchema = numSchema.multiple(num); +numSchema = numSchema.positive(); +numSchema = numSchema.negative(); module common { numSchema = numSchema.allow(x); @@ -376,10 +497,22 @@ module common { numSchema = numSchema.valid(x); numSchema = numSchema.valid(x, x); numSchema = numSchema.valid([x, x, x]); + numSchema = numSchema.only(x); + numSchema = numSchema.only(x, x); + numSchema = numSchema.only([x, x, x]); + numSchema = numSchema.equal(x); + numSchema = numSchema.equal(x, x); + numSchema = numSchema.equal([x, x, x]); numSchema = numSchema.invalid(x); numSchema = numSchema.invalid(x, x); numSchema = numSchema.invalid([x, x, x]); - + numSchema = numSchema.disallow(x); + numSchema = numSchema.disallow(x, x); + numSchema = numSchema.disallow([x, x, x]); + numSchema = numSchema.not(x); + numSchema = numSchema.not(x, x); + numSchema = numSchema.not([x, x, x]); + numSchema = numSchema.default(x); numSchema = numSchema.required(); @@ -418,12 +551,23 @@ objSchema = objSchema.length(num); objSchema = objSchema.pattern(exp, schema); +objSchema = objSchema.and(str); +objSchema = objSchema.and(str, str); objSchema = objSchema.and(str, str, str); objSchema = objSchema.and(strArr); +objSchema = objSchema.nand(str); +objSchema = objSchema.nand(str, str); +objSchema = objSchema.nand(str, str, str); +objSchema = objSchema.nand(strArr); + +objSchema = objSchema.or(str); +objSchema = objSchema.or(str, str); objSchema = objSchema.or(str, str, str); objSchema = objSchema.or(strArr); +objSchema = objSchema.xor(str); +objSchema = objSchema.xor(str, str); objSchema = objSchema.xor(str, str, str); objSchema = objSchema.xor(strArr); @@ -442,6 +586,17 @@ objSchema = objSchema.assert(ref, schema, str); objSchema = objSchema.unknown(); objSchema = objSchema.unknown(bool); +objSchema = objSchema.type(func); +objSchema = objSchema.type(func, str); + +objSchema = objSchema.requiredKeys(str); +objSchema = objSchema.requiredKeys(str, str); +objSchema = objSchema.requiredKeys(strArr); + +objSchema = objSchema.optionalKeys(str); +objSchema = objSchema.optionalKeys(str, str); +objSchema = objSchema.optionalKeys(strArr); + module common { objSchema = objSchema.allow(x); objSchema = objSchema.allow(x, x); @@ -449,10 +604,22 @@ module common { objSchema = objSchema.valid(x); objSchema = objSchema.valid(x, x); objSchema = objSchema.valid([x, x, x]); + objSchema = objSchema.only(x); + objSchema = objSchema.only(x, x); + objSchema = objSchema.only([x, x, x]); + objSchema = objSchema.equal(x); + objSchema = objSchema.equal(x, x); + objSchema = objSchema.equal([x, x, x]); objSchema = objSchema.invalid(x); objSchema = objSchema.invalid(x, x); objSchema = objSchema.invalid([x, x, x]); - + objSchema = objSchema.disallow(x); + objSchema = objSchema.disallow(x, x); + objSchema = objSchema.disallow([x, x, x]); + objSchema = objSchema.not(x); + objSchema = objSchema.not(x, x); + objSchema = objSchema.not([x, x, x]); + objSchema = objSchema.default(x); objSchema = objSchema.required(); @@ -483,13 +650,33 @@ strSchema = Joi.string(); strSchema = strSchema.insensitive(); strSchema = strSchema.min(num); +strSchema = strSchema.min(num, str); +strSchema = strSchema.min(ref); +strSchema = strSchema.min(ref, str); strSchema = strSchema.max(num); +strSchema = strSchema.max(num, str); +strSchema = strSchema.max(ref); +strSchema = strSchema.max(ref, str); +strSchema = strSchema.creditCard(); strSchema = strSchema.length(num); +strSchema = strSchema.length(num, str); +strSchema = strSchema.length(ref); +strSchema = strSchema.length(ref, str); strSchema = strSchema.regex(exp); +strSchema = strSchema.regex(exp, str); +strSchema = strSchema.replace(exp, str); +strSchema = strSchema.replace(str, str); strSchema = strSchema.alphanum(); strSchema = strSchema.token(); strSchema = strSchema.email(); +strSchema = strSchema.email(emailOpts); +strSchema = strSchema.ip(); +strSchema = strSchema.ip(ipOpts); +strSchema = strSchema.uri(); +strSchema = strSchema.uri(uriOpts); strSchema = strSchema.guid(); +strSchema = strSchema.hex(); +strSchema = strSchema.hostname(); strSchema = strSchema.isoDate(); strSchema = strSchema.lowercase(); strSchema = strSchema.uppercase(); @@ -502,10 +689,22 @@ module common { strSchema = strSchema.valid(x); strSchema = strSchema.valid(x, x); strSchema = strSchema.valid([x, x, x]); + strSchema = strSchema.only(x); + strSchema = strSchema.only(x, x); + strSchema = strSchema.only([x, x, x]); + strSchema = strSchema.equal(x); + strSchema = strSchema.equal(x, x); + strSchema = strSchema.equal([x, x, x]); strSchema = strSchema.invalid(x); strSchema = strSchema.invalid(x, x); strSchema = strSchema.invalid([x, x, x]); - + strSchema = strSchema.disallow(x); + strSchema = strSchema.disallow(x, x); + strSchema = strSchema.disallow([x, x, x]); + strSchema = strSchema.not(x); + strSchema = strSchema.not(x, x); + strSchema = strSchema.not([x, x, x]); + strSchema = strSchema.default(x); strSchema = strSchema.required(); @@ -537,6 +736,7 @@ schema = Joi.alternatives(schema, anySchema, boolSchema); // --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- +Joi.validate(value, obj); Joi.validate(value, schema); Joi.validate(value, schema, validOpts); Joi.validate(value, schema, validOpts, (err, value) => { @@ -566,6 +766,8 @@ Joi.validate(value, {}); schema = Joi.compile(obj); Joi.assert(obj, schema); +Joi.assert(obj, schema, str); +Joi.assert(obj, schema, err); ref = Joi.ref(str, refOpts); ref = Joi.ref(str); diff --git a/joi/joi.d.ts b/joi/joi.d.ts index 3df8ada9e0..b784ad23d5 100644 --- a/joi/joi.d.ts +++ b/joi/joi.d.ts @@ -1,6 +1,6 @@ // Type definitions for joi v4.6.0 // Project: https://github.com/spumko/joi -// Definitions by: Bart van der Schoor +// Definitions by: Bart van der Schoor , Laurence Dougal Myers // Definitions: https://github.com/borisyankov/DefinitelyTyped // TODO express type of Schema in a type-parameter (.default, .valid, .example etc) @@ -19,7 +19,9 @@ declare module 'joi' { // when true, unknown keys are deleted (only when value is an object). Defaults to false. stripUnknown?: boolean; // overrides individual error messages. Defaults to no override ({}). - language?: Object + language?: Object; + // sets the default presence requirements. Supported modes: 'optional', 'required', and 'forbidden'. Defaults to 'optional'. + presence?: string; // provides an external data set to be used in references context?: Object; } @@ -33,6 +35,28 @@ declare module 'joi' { override?: boolean; } + export interface EmailOptions { + // Numerical threshold at which an email address is considered invalid + errorLevel?: number | boolean; + // Specifies a list of acceptable TLDs. + tldWhitelist?: string[] | Object; + // Number of atoms required for the domain. Be careful since some domains, such as io, directly allow email. + minDomainAtoms?: number; + } + + export interface IpOptions { + // One or more IP address versions to validate against. Valid values: ipv4, ipv6, ipvfuture + version ?: string | string[]; + // Used to determine if a CIDR is allowed or not. Valid values: optional, required, forbidden + cidr?: string; + } + + export interface UriOptions { + // Specifies one or more acceptable Schemes, should only include the scheme name. + // Can be an Array or String (strings are automatically escaped for use in a Regular Expression). + scheme ?: string | RegExp | Array; + } + export interface WhenOptions { // the required condition joi type. is: Schema; @@ -95,12 +119,20 @@ declare module 'joi' { */ valid(value: any, ...values: any[]): T; valid(values: any[]): T; + only(value: any, ...values : any[]): T; + only(values: any[]): T; + equal(value: any, ...values : any[]): T; + equal(values: any[]): T; /** * Blacklists a value */ invalid(value: any, ...values: any[]): T; invalid(values: any[]): T; + disallow(value: any, ...values : any[]): T; + disallow(values: any[]): T; + not(value: any, ...values : any[]): T; + not(values: any[]): T; /** * Marks a key as required which will not allow undefined as value. All keys are optional by default. @@ -117,6 +149,11 @@ declare module 'joi' { */ forbidden(): T; + /** + * Marks a key to be removed from a resulting object or array after validation. Used to sanitize output. + */ + strip(): T; + /** * Annotates the key */ @@ -157,12 +194,28 @@ declare module 'joi' { /** * Sets the options.convert options to false which prevent type casting for the current key and any child keys. */ - strict(): T; + strict(isStrict?: boolean): T; /** * Sets a default value if the original value is undefined. + * @param value - the value. + * value supports references. + * value may also be a function which returns the default value. + * If value is specified as a function that accepts a single parameter, that parameter will be a context + * object that can be used to derive the resulting value. This clones the object however, which incurs some + * overhead so if you don't need access to the context define your method so that it does not accept any + * parameters. + * Without any value, default has no effect, except for object that will then create nested defaults + * (applying inner defaults of that object). + * + * Note that if value is an object, any changes to the object after default() is called will change the + * reference and any future assignment. + * + * Additionally, when specifying a method you must either have a description property on your method or the + * second parameter is required. */ - default(value: any): T; + default(value: any, description?: string): T; + default(): T; /** * Returns a new type that is the result of adding the rules of one type to another. @@ -174,6 +227,22 @@ declare module 'joi' { */ when(ref: string, options: WhenOptions): AlternativesSchema; when(ref: Reference, options: WhenOptions): AlternativesSchema; + + /** + * Overrides the key name in error messages. + */ + label(name: string): T; + + /** + * Outputs the original untouched value instead of the casted value. + */ + raw(isRaw?: boolean): T; + + /** + * Considers anything that matches the schema to be empty (undefined). + * @param schema - any object or joi schema to match. An undefined schema unsets that rule. + */ + empty(schema?: any) : T; } export interface BooleanSchema extends AnySchema { @@ -183,18 +252,57 @@ declare module 'joi' { export interface NumberSchema extends AnySchema { /** * Specifies the minimum value. + * It can also be a reference to another field. */ min(limit: number): NumberSchema; + min(limit: Reference): NumberSchema; /** * Specifies the maximum value. + * It can also be a reference to another field. */ max(limit: number): NumberSchema; + max(limit: Reference): NumberSchema; + + /** + * Specifies that the value must be greater than limit. + * It can also be a reference to another field. + */ + greater(limit: number): NumberSchema; + greater(limit: Reference): NumberSchema; + + /** + * Specifies that the value must be less than limit. + * It can also be a reference to another field. + */ + less(limit: number): NumberSchema; + less(limit: Reference): NumberSchema; /** * Requires the number to be an integer (no floating point). */ integer(): NumberSchema; + + /** + * Specifies the maximum number of decimal places where: + * limit - the maximum number of decimal places allowed. + */ + precision(limit: number): NumberSchema; + + /** + * Specifies that the value must be a multiple of base. + */ + multiple(base: number): NumberSchema; + + /** + * Requires the number to be positive. + */ + positive(): NumberSchema; + + /** + * Requires the number to be negative. + */ + negative(): NumberSchema; } export interface StringSchema extends AnySchema { @@ -205,23 +313,47 @@ declare module 'joi' { /** * Specifies the minimum number string characters. + * @param limit - the minimum number of string characters required. It can also be a reference to another field. + * @param encoding - if specified, the string length is calculated in bytes using the provided encoding. */ - min(limit: number): StringSchema; + min(limit: number, encoding?: string): StringSchema; + min(limit: Reference, encoding?: string): StringSchema; /** * Specifies the maximum number of string characters. + * @param limit - the maximum number of string characters allowed. It can also be a reference to another field. + * @param encoding - if specified, the string length is calculated in bytes using the provided encoding. */ - max(limit: number): StringSchema; + max(limit: number, encoding?: string): StringSchema; + max(limit: Reference, encoding?: string): StringSchema; + + /** + * Requires the number to be a credit card number (Using Lunh Algorithm). + */ + creditCard(): StringSchema; /** * Specifies the exact string length required + * @param limit - the required string length. It can also be a reference to another field. + * @param encoding - if specified, the string length is calculated in bytes using the provided encoding. */ - length(limit: number): StringSchema; + length(limit: number, encoding?: string): StringSchema; + length(limit: Reference, encoding?: string): StringSchema; /** * Defines a regular expression rule. + * @param pattern - a regular expression object the string value must match against. + * @param name - optional name for patterns (useful with multiple patterns). Defaults to 'required'. */ - regex(pattern: RegExp): StringSchema; + regex(pattern: RegExp, name?: string): StringSchema; + + /** + * Replace characters matching the given pattern with the specified replacement string where: + * @param pattern - a regular expression object to match against, or a string of which all occurrences will be replaced. + * @param replacement - the string that will replace the pattern. + */ + replace(pattern: RegExp, replacement: string): StringSchema; + replace(pattern: string, replacement: string): StringSchema; /** * Requires the string value to only contain a-z, A-Z, and 0-9. @@ -236,13 +368,33 @@ declare module 'joi' { /** * Requires the string value to be a valid email address. */ - email(): StringSchema; + email(options?: EmailOptions): StringSchema; + + /** + * Requires the string value to be a valid ip address. + */ + ip(options?: IpOptions): StringSchema; + + /** + * Requires the string value to be a valid RFC 3986 URI. + */ + uri(options?: UriOptions): StringSchema; /** * Requires the string value to be a valid GUID. */ guid(): StringSchema; + /** + * Requires the string value to be a valid hexadecimal string. + */ + hex(): StringSchema; + + /** + * Requires the string value to be a valid hostname as per RFC1123. + */ + hostname(): StringSchema; + /** * Requires the string value to be in valid ISO 8601 date format. */ @@ -262,35 +414,34 @@ declare module 'joi' { * Requires the string value to contain no whitespace before or after. If the validation convert option is on (enabled by default), the string will be trimmed. */ trim(): StringSchema; - - /** - * Requires the string value be a valid hostname. - */ - hostname(): StringSchema; - - /** - * Requires the string value to be a valid IP address. - */ - ip(options: IPOptions): StringSchema; - - /** - * Requires the string value to be a valid uri with the passed scheme. - */ - uri(options?: { scheme?: string }): StringSchema; } export interface ArraySchema extends AnySchema { /** - * List the types allowed for the array value + * Allow this array to be sparse. + * enabled can be used with a falsy value to go back to the default behavior. */ - includes(type: Schema, ...types: Schema[]): ArraySchema; - includes(types: Schema[]): ArraySchema; + sparse(enabled?: any): ArraySchema; /** - * List the types forbidden for the array values. + * Allow single values to be checked against rules as if it were provided as an array. + * enabled can be used with a falsy value to go back to the default behavior. */ - excludes(type: Schema, ...types: Schema[]): ArraySchema; - excludes(types: Schema[]): ArraySchema; + single(enabled?: any): ArraySchema; + + /** + * List the types allowed for the array values. + * type can be an array of values, or multiple values can be passed as individual arguments. + * If a given type is .required() then there must be a matching item in the array. + * If a type is .forbidden() then it cannot appear in the array. + * Required items can be added multiple times to signify that multiple items must be found. + * Errors will contain the number of items that didn't match. + * Any unmatched item having a label will be mentioned explicitly. + * + * @param type - a joi schema object to validate each array item against. + */ + items(type: Schema, ...types: Schema[]): ArraySchema; + items(types: Schema[]): ArraySchema; /** * Specifies the minimum number of items in the array. @@ -307,6 +458,12 @@ declare module 'joi' { */ length(limit: number): ArraySchema; + /** + * Requires the array values to be unique. + * Be aware that a deep equality is performed on elements of the array having a type of object, + * a performance penalty is to be expected for this kind of operation. + */ + unique(): ArraySchema; } export interface ObjectSchema extends AnySchema { @@ -337,20 +494,30 @@ declare module 'joi' { /** * Defines an all-or-nothing relationship between keys where if one of the peers is present, all of them are required as well. + * @param peers - the key names of which if one present, all are required. peers can be a single string value, + * an array of string values, or each peer provided as an argument. */ - and(peer1: string, peer2: string, ...peers: string[]): ObjectSchema; + and(peer1: string, ...peers: string[]): ObjectSchema; and(peers: string[]): ObjectSchema; + /** + * Defines a relationship between keys where not all peers can be present at the same time. + * @param peers - the key names of which if one present, the others may not all be present. + * peers can be a single string value, an array of string values, or each peer provided as an argument. + */ + nand(peer1: string, ...peers: string[]): ObjectSchema; + nand(peers: string[]): ObjectSchema; + /** * Defines a relationship between keys where one of the peers is required (and more than one is allowed). */ - or(peer1: string, peer2: string, ...peers: string[]): ObjectSchema; + or(peer1: string, ...peers: string[]): ObjectSchema; or(peers: string[]): ObjectSchema; /** * Defines an exclusive relationship between a set of keys. one of them is required but not at the same time where: */ - xor(peer1: string, peer2: string, ...peers: string[]): ObjectSchema; + xor(peer1: string, ...peers: string[]): ObjectSchema; xor(peers: string[]): ObjectSchema; /** @@ -380,9 +547,47 @@ declare module 'joi' { * Overrides the handling of unknown keys for the scope of the current object only (does not apply to children). */ unknown(allow?: boolean): ObjectSchema; + + /** + * Requires the object to be an instance of a given constructor. + * + * @param constructor - the constructor function that the object must be an instance of. + * @param name - an alternate name to use in validation errors. This is useful when the constructor function does not have a name. + */ + type(constructor: Function, name?: string): ObjectSchema; + + /** + * Sets the specified children to required. + * + * @param children - can be a single string value, an array of string values, or each child provided as an argument. + * + * var schema = Joi.object().keys({ a: { b: Joi.number() }, c: { d: Joi.string() } }); + * var requiredSchema = schema.requiredKeys('', 'a.b', 'c', 'c.d'); + * + * Note that in this example '' means the current object, a is not required but b is, as well as c and d. + */ + requiredKeys(children: string): ObjectSchema; + requiredKeys(children: string[]): ObjectSchema; + requiredKeys(child:string, ...children: string[]): ObjectSchema; + + /** + * Sets the specified children to optional. + * + * @param children - can be a single string value, an array of string values, or each child provided as an argument. + * + * The behavior is exactly the same as requiredKeys. + */ + optionalKeys(children: string): ObjectSchema; + optionalKeys(children: string[]): ObjectSchema; + optionalKeys(child:string, ...children: string[]): ObjectSchema; } export interface BinarySchema extends AnySchema { + /** + * Sets the string encoding format if a string input is converted to a buffer. + */ + encoding(encoding: string): BinarySchema; + /** * Specifies the minimum length of the buffer. */ @@ -403,17 +608,37 @@ declare module 'joi' { /** * Specifies the oldest date allowed. + * Notes: 'now' can be passed in lieu of date so as to always compare relatively to the current date, + * allowing to explicitly ensure a date is either in the past or in the future. + * It can also be a reference to another field. */ min(date: Date): DateSchema; min(date: number): DateSchema; min(date: string): DateSchema; + min(date: Reference): DateSchema; /** * Specifies the latest date allowed. + * Notes: 'now' can be passed in lieu of date so as to always compare relatively to the current date, + * allowing to explicitly ensure a date is either in the past or in the future. + * It can also be a reference to another field. */ max(date: Date): DateSchema; max(date: number): DateSchema; max(date: string): DateSchema; + max(date: Reference): DateSchema; + + /** + * Specifies the allowed date format: + * @param format - string or array of strings that follow the moment.js format. + */ + format(format: string): DateSchema; + format(format: string[]): DateSchema; + + /** + * Requires the string value to be in valid ISO 8601 date format. + */ + iso(): DateSchema; } export interface FunctionSchema extends AnySchema { @@ -495,8 +720,12 @@ declare module 'joi' { /** * Validates a value against a schema and throws if validation fails. + * + * @param value - the value to validate. + * @param schema - the schema object. + * @param message - optional message string prefix added in front of the error message. may also be an Error object. */ - export function assert(value: any, schema: Schema): void; + export function assert(value: any, schema: Schema, message?: string | Error): void; /** * Generates a reference to the value of the named key.