5.0.6 • Published 5 months ago

validata v5.0.6

Weekly downloads
508
License
MIT
Repository
github
Last release
5 months ago

Validata

Type safe data validation and sanitization.

See also

Getting started

npm i validata

Basic usage

import { asString, isObject, isString, maybeString } from 'validata';

interface Sample {
  maybeString: string | undefined;
  myString: string;
  numericString: string;
}

const sample = isObject<Sample>({
  maybeString: maybeString(), // will allow string data type or sanitize to undefined
  myString: isString(), // will allow only string data type
  numericString: asString(), // will allow string or attempt to convert to string
});

console.log(
  JSON.stringify(
    sample.process({
      maybeString: 123,
      myString: 123,
      numericString: 123,
    })
  )
);

/*
FAIL: Outputs:
{"issues":[{"path":["maybeString"],"value":123,"reason":"incorrect-type","info":{"expectedType":"string"}},{"path":["myString"],"value":123,"reason":"incorrect-type","info":{"expectedType":"string"}}]}
*/

console.log(
  JSON.stringify(
    sample.process({
      myString: '123',
      numericString: 123,
    })
  )
);

/*
SUCCESS: Outputs:
{"value":{"myString":"123","numericString":"123"}}
*/

API

Checks:

  • isAny
  • Array
    • isArray
    • maybeArray
    • asArray
    • maybeAsArray
  • Boolean
    • isBoolean
    • maybeBoolean
    • asBoolean
    • maybeAsBoolean
  • Date
    • isDate
    • maybeDate
    • asDate
    • maybeAsDate
  • Enum
    • isEnum
    • maybeEnum
    • asEnum
    • maybeAsEnum
  • Number
    • isNumber
    • maybeNumber
    • asNumber
    • maybeAsNumber
  • Object
    • isObject
    • maybeObject
    • asObject
    • maybeAsObject
  • Record
    • isRecord
    • maybeRecord
    • asRecord
    • maybeAsRecord
  • String
    • isString
    • maybeString
    • asString
    • maybeAsString
  • Tuple
    • isTuple
    • maybeTuple
  • Url
    • isUrl
    • maybeUrl
    • asUrl
    • maybeAsUrl
  • isNullable
  • asNullable

Types

  • TypeOf

Work is done by a typed ValueProcessor, as returned byisObject<T>() or asNumber().

interface ValueProcessor<T> {
  process(value: unknown): Result<T>;
}

The process() method returns a Result<T>.The Result is either a list of issues (meaning validation failures) or the accepted value (it may be coerced/altered from the original).

type Result<T> = ValueResult<T> | IssueResult;

interface ValueResult<T> {
  value: T;
}

interface IssueResult {
  issues: Issue[];
}

Naming conventions

is... e.g. isNumber

  • if the value is of the type it will be accepted
  • null or undefined cause an issue
  • otherwise it will cause an issue

maybe... e.g. maybeNumber

  • if the value is of the type it will be accepted
  • null or undefined it will sanitized to undefined
  • otherwise it will cause an issue

as... e.g. asNumber

  • if the value is of the type it will be accepted
  • null or undefined converted to default, if provided, or cause an issue
  • if the value can be converted to the type, it will be converted and used
  • if the value is cannot be converted the default will be used if provided
  • otherwise it will cause an issue

maybeAs... e.g. maybeAsNumber

  • if the value is of the type it will be accepted
  • null or undefined converted to default, if provided, or sanitized to undefined
  • if the value can be converted to the type it will be converted and used
  • if the value is cannot be converted the default will be used if provided
  • otherwise it will cause an issue // * otherwise it will be sanitized to undefined

Checks

isArray, maybeArray, asArray, maybeAsArray

Usage:

isArray(itemProcessor, options);
maybeArray(itemProcessor, options);
asArray(itemProcessor, options);
maybeAsArray(itemProcessor, options);

Options:

  • converter?: (value: unknown, options?: any) => T | undefined - custom converter function, if not defined or undefined is returned then built in conversions will be run
  • convertOptions - options to pass to the converter
  • coerceMaxLength? number - if there are more items than this, some will be removed
  • maxLength?: number - if there are more items than this, it's an error max-length
  • minLength?: number - if there are less items than this, it's an error min-length
  • validator?: (value: T, options?: any) => boolean - custom validation function; if false is returned it's an error
  • validatorOptions?: any - options to pass to the validator

Example:

isArray<number>(isNumber({ max: 20, min: 10 }), { coerceMaxLength: 7 });

isBoolean, maybeBoolean, asBoolean, maybeAsBoolean

Usage:

isBoolean(options);
maybeBoolean(options);
asBoolean(options);
maybeAsBoolean(options);

Options:

  • converter?: (value: unknown, options?: any) => T | undefined - custom converter function, if not defined or undefined is returned then built in conversions will be run
  • convertOptions - options to pass to the converter
  • validator?: (value: T, options?: any) => boolean - custom validation function; if false is returned it's an error
  • validatorOptions?: any - options to pass to the validator

isDate, maybeDate, asDate, maybeAsDate

Usage:

isDate(options);
maybeDate(options);
asDate(options);
maybeAsDate(options);

Options:

  • converter?: (value: unknown, options?: any) => T | undefined - custom converter function, if not defined or undefined is returned then built in conversions will be run
  • convertOptions - options to pass to the converter
  • format - custom date format used in conversion from string to Date see Luxon formatting
  • maxFuture?: Duration - if the value is after this duration into the future, it's an error max-future
  • maxPast?: Duration - if the value is before this duration into the past, it's an error max-past
  • validator?: (value: T, options?: any) => boolean - custom validation function; if false is returned it's an error
  • validatorOptions?: any - options to pass to the validator

isEnum, maybeEnum, asEnum, maybeAsEnum

Usage:

isEnum(Enum);
maybeNumber(Enum);
asNumber(Enum);
maybeAsNumber(Enum);

Example:

// String based Enum
enum EnumOne {
  A = 'A',
  B = 'B',
  C = 'C',
}
isEnum(EnumOne); // Allows "A", "B", "C"

// Number based Enum
enum EnumTwo {
  A,
  B,
  C,
}
isEnum(EnumTwo); // Allows 0, 1, 2

// Converting to an Enum using it's key or value
asEnum(EnumTwo); // Allows 1, 2, 3, "A", "B", "C"
asEnum(EnumTwo).process('A'));       // { value: 0 }
asEnum(EnumTwo).process(0));         // { value: 0 }
asEnum(EnumTwo).process(EnumOne.A)); // { value: 0 }

isNumber, maybeNumber, asNumber, maybeAsNumber

Usage:

isNumber(options);
maybeNumber(options);
asNumber(options);
maybeAsNumber(options);

Options:

  • converter?: (value: unknown, options?: any) => T | undefined - custom converter function, if not defined or undefined is returned then built in conversions will be run
  • convertOptions - options to pass to the converter
  • coerceMin?: number - if the value is less than this, it will be set to this value
  • coerceMax?: number - if the value is more than this, it will be set to this value
  • max?: number - if the value is than this, it's an error max
  • min?: number - if the value is than this, it's an error min
  • validator?: (value: T, options?: any) => boolean - custom validation function; if false is returned it's an error
  • validatorOptions?: any - options to pass to the validator

isObject, maybeObject, asObject, maybeAsObject

Usage:

isObject(contract, options);
maybeObject(contract, options);
asObject(contract, options); // will parse string JSON as object
maybeAsObject(contract, options); // will parse string JSON as object
// where `contract` is Record<string, ValueProcessor>

Options:

  • converter?: (value: unknown, options?: any) => T | undefined - custom converter function, if not defined or undefined is returned then built in conversions will be run
  • convertOptions - options to pass to the converter
  • validator?: (value: T, options?: any) => boolean - custom validation function; if false is returned it's an error
  • validatorOptions?: any - options to pass to the validator

Example:

interface Sample {
  myString: string;
  maybeString: string | undefined;
  numericString: string;
}

const check = isObject<Sample>({
  maybeString: maybeString(), // if these don't match the interface TypeScript will error
  myString: isString(),
  numericString: asString(),
});

isRecord, maybeRecord, asRecord, maybeAsRecord

Usage:

isRecord<V>(check, options);
maybeRecord<V>(check, options);
asRecord<V>(check, options);
maybeAsRecord<V>(check, options);
// where `check` is ValueProcessor<V>, and Record<string, V> is the type to be processed

Options:

  • keyRegex?: RegExp - regular expression to check each key name, or it's an error key-regex
  • maxKeys?: number - if the number of keys in the object is more than this, it's an error max-keys
  • minKeys?: number - if the number of keys in the object is more than this, it's an error max-keys
  • validator?: (value: Record<string, V>, options?: any) => boolean - custom validation function; if false is returned it's an error
  • validatorOptions?: any - options to pass to the validator

Example:

const check = isRecord(isString());
check.process({ foo: 'bar' });

isString, maybeString, asString, maybeAsString

Usage:

isString(options);
maybeString(options);
asString(options);
maybeAsString(options);

Options:

  • converter?: (value: unknown, options?: any) => T | undefined - custom converter function, if not defined or undefined is returned then built in conversions will be run
  • convertOptions - options to pass to the converter
  • limitLength?: number - if the length of the string is more than this, it will be truncated to this length
  • padStart?: StringPadding - pad the start of the string up to given value
  • padEnd?: StringPadding - pad the end of the string up to given value
  • trim?: 'start' | 'end' | 'both' | 'none' - removes the leading and/or trailing white space and line terminator characters from the string
  • regex?: RegExp - regular expression that must be matched, or it's an error regex
  • maxLength?: number - if the length of the string is more than this, it's an error max-length
  • minLength?: number - if the length of the string is less than this, it's an error min-length
  • format:? StringFormatCheck - extension point for string format checking, if check fails it's an issue format with info.expectedFormat set
  • validator?: (value: T, options?: any) => boolean - custom validation function; if false is returned it's an error
  • validatorOptions?: any - options to pass to the validator

StringPadding:

  • length: number - will pad up until this length
  • padWith: string - the value to pad with

StringFormat:

Example:

const check = isString({
  limitLength: 6,
  padStart: { length: 6, padWith: '-' },
});
const check = isString({
  format: StringFormat.ULID(),
});
const check = isString({
  format: StringFormat.password({
    minLength: 10, // default=8
    numberChars: 2, // default=1
    lowerCaseChars: 2, // default=1
    upperCaseChars: 2, // default=1
    specialChars: 0, // default=1
  }),
});
// change case
import { pascalCase } from 'change-case';

const check = isString({
  transform: pascalCase,
});
const check = isString({
  maxLength: 10,
  minLength: 8,
  regex: /^[A-Z]+$/,
});
import validator from 'validator';

const check = isString({
  validator: validator.isEmail,
  validatorOptions: { allow_display_name: true },
});

isTuple, maybeTuple

Usage:

isTuple(options);
maybeTuple(options);

Options:

  • validator?: (value: T, options?: any) => boolean - custom validation function; if false is returned it's an error
  • validatorOptions?: any - options to pass to the validator

Example:

type MyTuple = [number, string];
const check = isTuple([isNumber({ max: 9, min: 3 }), isString({ regex: /^\w+$/ })]);

isUrl, maybeUrl, asUrl, maybeAsUrl

Working with Node's URL object

Usage:

isUrl(options);
maybeUrl(options);
asUrl(options);
maybeAsUrl(options);

Options:

  • converter?: (value: unknown, options?: any) => T | undefined - custom converter function, if not defined or undefined is returned then built in conversions will be run
  • convertOptions - options to pass to the converter
  • setProtocol?: string - will coerce the protocol to the given value, if present
  • protocol?: string - given URL must have this protocol, or it's an error invalid-protocol
  • validator?: (value: URL, options?: any) => boolean - custom validation function; if false is returned it's an error
  • validatorOptions?: any - options to pass to the validator

Example:

const check = asUrl({
  protocol: 'https',
});

isNullable

Any other check can be wrapped into isNullable to accept null.

Example:

const check = isNullable(isString({ min: 3 }));

asNullable

Any other check can be wrapped into asNullable to accept null.

Options:

  • default - can be null or return type or a function with return type of the wrapped check

Example:

const check = asNullable(isString({ min: 3 }));
const check = asNullable(isString({ min: 3 }), { default: null });
const check = asNullable(isString({ min: 3 }), { default: 'text' });
const check = asNullable(isString({ min: 3 }), { default: () => 'text' });

Types

Types can be extracted from a ValueProcessor or a Contract-like pure object.

const sampleContract = {
  maybeString: maybeString(),
  myString: isString(),
  numericString: asString(),
};
const sample = isObject(sampleContract);

// both are same as
export type SampleContract = TypeOf<typeof sample>;
export type Sample = TypeOf<typeof sample>;
// interface Sample {
//   myString: string;
//   maybeString: string | undefined;
//   numericString: string;
// }
5.0.6

5 months ago

5.0.5

11 months ago

5.0.4

1 year ago

5.0.3

1 year ago

5.0.2

1 year ago

5.0.1

2 years ago

4.0.18

2 years ago

4.0.16

2 years ago

4.0.15

2 years ago

4.0.17

2 years ago

4.0.14

3 years ago

4.0.10

3 years ago

4.0.11

3 years ago

4.0.13

3 years ago

4.0.9

3 years ago

4.0.7

3 years ago

4.0.8

3 years ago

4.0.6

3 years ago

4.0.5

3 years ago

4.0.4

3 years ago

4.0.1

3 years ago

4.0.3

3 years ago

4.0.2

3 years ago

3.0.7

3 years ago

3.0.6

3 years ago

3.0.5

3 years ago

3.0.4

3 years ago

3.0.3

3 years ago

3.0.2

3 years ago

3.0.1

3 years ago

2.1.32

3 years ago

2.1.31

3 years ago

2.1.30

3 years ago

2.1.29

3 years ago

2.1.28

3 years ago

2.1.27

3 years ago

2.1.26

3 years ago

2.1.25

3 years ago

2.1.23

3 years ago

2.1.24

3 years ago

2.1.22

4 years ago

2.1.21

4 years ago

2.1.20

4 years ago

2.1.19

4 years ago

2.1.18

4 years ago

2.1.17

4 years ago

2.1.16

4 years ago

2.1.15

4 years ago

2.1.14

4 years ago

2.1.13

4 years ago

2.1.12

4 years ago

2.1.11

4 years ago

2.1.10

4 years ago

2.1.9

4 years ago

2.1.8

4 years ago

2.1.7

4 years ago

2.1.6

4 years ago

2.1.5

4 years ago

2.1.4

4 years ago

2.1.3

4 years ago

2.1.2

4 years ago

2.1.1

4 years ago

2.0.10

4 years ago

2.0.5

4 years ago

2.0.7

4 years ago

2.0.6

4 years ago

2.0.9

4 years ago

2.0.8

4 years ago

2.0.3

4 years ago

2.0.2

4 years ago

0.1.8

5 years ago

0.1.7

10 years ago

0.1.6

10 years ago

0.1.5

10 years ago

0.1.4

10 years ago

0.1.3

10 years ago

0.1.2

10 years ago

0.1.1

10 years ago

0.1.0

10 years ago