diff --git a/dist/knockout.validation.d.ts b/dist/knockout.validation.d.ts new file mode 100644 index 0000000..f9efb4c --- /dev/null +++ b/dist/knockout.validation.d.ts @@ -0,0 +1,450 @@ +import * as ko from "knockout"; + +declare module "knockout" { + export namespace validation { + export type ValidationObservable = ko.Observable & ObservableValidationExtension; + export type ValidationComputed = ko.Computed & ObservableValidationExtension; + export type ValidationPureComputed = ko.PureComputed & ObservableValidationExtension; + + export interface ValidationConfiguration { + /** + * If true validation will insert either a element or the template specified by messageTemplate + * after any element (e.g. )that uses a KO value binding with a validated field. + */ + insertMessages?: boolean; + /** + * Indicates whether to assign an error class to the tag when your property is invalid. + * Note that this was previously called decorateElement, and this config option was renamed 2013-11-21. + */ + decorateInputElement?: boolean; + /** The CSS class assigned to validation error messages inserted when insertMessages is true. */ + errorMessageClass?: string; + /** The CSS class assigned to validation error elements, must have decorateInputElement set to true */ + errorElementClass?: string; + /** Shows tooltips using input ‘title’ attribute. False hides them. */ + errorsAsTitle?: boolean; + /** If defined, the CSS class assigned to both and validation message. */ + errorClass?: string; + /** Indicates whether to assign validation rules to your ViewModel using HTML5 validation attributes. */ + parseInputAttributes?: boolean; + /** Adds HTML5 input validation attributes to form elements that ko observable’s are bound to. */ + writeInputAttributes?: boolean; + /** Indicates whether validation messages are triggered only when properties are modified or at all times. */ + messagesOnModified?: boolean; + /** Indicates whether css error classes are added only when properties are modified or at all times. */ + decorateElementOnModified?: boolean; + /** The id of the that you want to use for all your validation messages. */ + messageTemplate?: string; + /** When using the group or validatedObservable functions. */ + grouping?: ValidationGroupingOptions; + /** Register custom validation rules defined via ko.validation.rules. */ + registerExtenders?: boolean; + } + + /** When using the group or validatedObservable functions. */ + export interface ValidationGroupingOptions { + /** Indicates whether to walk the ViewModel (or object) recursively, or only walk first-level properties. */ + deep?: boolean; + /** Indicates whether the returned errors object is a ko.computed or a simple function. */ + observable?: boolean; + /** Indicates whether changes to observableArrays inside the model should cause the validator to re-run. */ + live?: boolean; + } + + export interface ValidationRule { + /** The rule name. */ + rule: string; + /** The rule parameters. */ + params: any; + /** The rule message. */ + message?: string; + /** The rule condition. */ + condition?: () => boolean; + } + + export interface ValidationRuleExtenderParams { + /** The rule parameters. */ + params: T | ko.Subscribable; + /** The rule message. */ + message?: string; + /** The rule condition. */ + onlyIf?: () => boolean; + } + + export interface ObservableValidationExtension { + /** Holds the error message, we only need one since we stop processing validators when one is invalid. */ + error: ko.Observable; + /** Contains all rules applied to the observable. */ + rules: ko.ObservableArray; + /** Is the observable modified. */ + isModified: ko.Observable; + /** In case async validation is occurring. */ + isValidating: ko.Observable; + /** Indicates whether the observable is valid. */ + isValid: ko.Computed; + + /** Manually set error state. */ + setError(error: string): void; + + /** Manually clear error state. */ + clearError(): void; + + /** Dispose validation extension. */ + _disposeValidation(): void; + } + + export interface ValidationRuleDefinition { + /** The rule message. */ + message: string; + /** The rule validator. */ + validator(value: any, params: any): boolean; + /** The rule condition. */ + condition?: () => boolean; + /** The rule condition. */ + onlyIf?: () => boolean; + } + + export interface ValidationAsyncRuleDefinition { + /** Indicates that this rule is async. */ + async: true; + /** The rule message. */ + message: string; + /** The rule async validator. */ + validator(value: any, params: any, callback: ValidationAsyncCallback): void; + /** The rule condition. */ + condition?: () => boolean; + /** The rule condition. */ + onlyIf?: () => boolean; + } + + export interface ValidationGroup extends ValidationGroupFunctions { + (): string[]; + } + + export interface ValidationGroupComputed extends ko.Computed, ValidationGroupFunctions { } + + export interface ValidationGroupFunctions { + showAllMessages(show?: boolean): void; + isAnyMessageShown(): boolean; + filter(predicate: (obs: ko.Observable | ko.ObservableArray | ko.Computed) => boolean): Array | ko.ObservableArray | ko.Computed>; + find(predicate: (obs: ko.Observable | ko.ObservableArray | ko.Computed) => boolean): ko.Observable | ko.ObservableArray | ko.Computed; + forEach(predicate: (obs: ko.Observable | ko.ObservableArray | ko.Computed) => void): void; + map(predicate: (obs: ko.Observable | ko.ObservableArray | ko.Computed) => U): U[]; + } + + export type ObjectValidationRuleDefinitions = { + [P in keyof T]: + T[P] extends object ? ObjectValidationRuleDefinitions : + T[P] extends Array ? ObjectValidationRuleDefinitions : + { [key: string]: ValidationRuleExtenderParams | ValidationAnonymousRuleDefinition; } + } + + export type ValidationAsyncCallback = (result: boolean | { isValid: boolean; message: string; }) => void; + + export type ValidationAnonymousRuleDefinition = ValidationRuleDefinition | ValidationAsyncRuleDefinition; + + export type ValidationExtendType = T | ko.Subscribable | ValidationRuleExtenderParams; + + export type ValidationExtendAccessType = () => T | ValidationExtendType; + + export interface ValidationExtendOptions { + validation?: ValidationRule | ValidationRuleDefinition | ValidationAsyncRuleDefinition | Array; + validatable?: boolean | ExtenderValidatableOptions; + + required?: ValidationExtendType; + min?: ValidationExtendType; + max?: ValidationExtendType; + minLength?: ValidationExtendType; + maxLength?: ValidationExtendType; + pattern?: ValidationExtendType; + step?: ValidationExtendType; + email?: ValidationExtendType; + date?: ValidationExtendType; + dateISO?: ValidationExtendType; + number?: ValidationExtendType; + digit?: ValidationExtendType; + phoneUS?: ValidationExtendType; + equal?: ValidationExtendAccessType; + notEqual?: ValidationExtendAccessType; + unique?: ValidationExtendType; + } + + export interface ExtenderValidatableOptions { + enable?: boolean; + throttle?: number; + } + + export interface ExtenderUniqueOptions { + /** array or function returning (observable) array in which the value has to be unique. */ + collection?: ko.MaybeObservableArray | (() => ko.MaybeObservableArray); + /** Function that returns value from an object stored in collection. If it is null the value is compared directly. */ + valueAccessor?: (item: any) => any; + /** Set to true when object you are validating is automatically updating collection. */ + external?: boolean; + } + + /** Call this on startup. Any config can be overridden with the passed in options. */ + export function init(options?: ValidationConfiguration, force?: boolean): void; + + /** Resets the config back to its original state. */ + export function reset(): void; + + /** + * Recursively walks a viewModel and creates an object that provides validation information for the entire viewModel. + * + * @param obj The viewModel to walk. + * @param options The grouping options. + */ + export function group(obj: any, options?: ValidationGroupingOptions): ValidationGroup; + /** + * Recursively walks a viewModel and creates an object that provides validation information for the entire viewModel. + * + * @param obj The viewModel to walk. + * @param options The grouping options. + */ + export function group(obj: any, options?: ValidationGroupingOptions & { observable: true }): ValidationGroupComputed; + + /** + * + * @param message The message containing replacements. + * @param params The replacement parameters + */ + export function formatMessage(message: string | MessageFunction, params: ko.MaybeSubscribable, observable?: ko.Observable): string; + export type MessageFunction = (params: ko.MaybeSubscribable, observable?: ko.Observable) => string; + + /** + * This takes in a ko.observable and a Rule Context - which is just a rule name and params to supply to the validator. + * + * @example + * ko.validation.addRule(myObservable, { + * rule: "required", + * params: true + * }); + * + * @param observable The Observable to extend. + * @param rule The rule configuration. + */ + export function addRule(observable: ko.Observable | ko.Computed, rule: ValidationRule): typeof observable & ObservableValidationExtension; + + /** + * Anonymous Rules essentially have all the properties of a Rule, but are only specific for a certain property + * and developers typically are wanting to add them on the fly or not register a rule with the 'ko.validation.rules' object + * + * @example + * var test = ko.observable("something").extend({ + * validation: { + * validator: function (val, someOtherVal) { + * return true; + * }, + * message: "Something must be really wrong!", + * params: true + * } + * }); + * + * @param observable The Observable to extend. + * @param ruleObj The rule definition object. + */ + export function addAnonymousRule(observable: ko.Observable | ko.Computed, ruleObj: ValidationAnonymousRuleDefinition): void; + + /** + * Creates a knockout extender for the specified rule. + * + * @param ruleName The rule to create extender for. + */ + export function addExtender(ruleName: string): void; + + /** Loops through all ko.validation.rules and adds them as extenders to ko.extenders. */ + export function registerExtenders(): void; + + /** + * Creates a span next to the @element with the specified error class. + * + * @param element The HTML Element to insert message after. + */ + export function insertValidationMessage(element: Element): Element; + + /** + * If html-5 validation attributes have been specified, this parses the attributes on @element. + * + * @param element The HTML Element to parse attributes on. + * @param valueAccessor The valueAccesor containing the observable to validate. + */ + export function parseInputValidationAttributes(element: Element, valueAccessor: () => any): void; + + /** + * Writes html5 validation attributes on the element passed in. + * + * @param element The HTML Element to write attributes on. + * @param valueAccessor The valueAccessor containing the observable to validate. + */ + export function writeInputValidationAttributes(element: Element, valueAccessor: () => any): void; + + /** + * Take an existing binding handler and make it cause automatic validations. + * + * @param handlerName The binding handler to make validatable. + */ + export function makeBindingHandlerValidatable(handlerName: string): void; + + /** + * Visit an objects properties and apply validation rules from a definition. + * + * @param target The target object to set rules for. + * @param definitions The rules definitions object. + */ + export function setRules(target: T, definitions: ObjectValidationRuleDefinitions): void; + + /** Validates specified observable. */ + export function validateObservable(observable: ko.Observable | ko.Computed): boolean; + + /** + * Applies localization to messages. + * + * @param locale The locale to apply. + */ + export function locale(locale: string): void; + + /** + * Defines localization messages. + * + * @param locale The locale to define. + * @param values The messages values. + */ + export function defineLocale(locale: string, values: Object): void; + + /** + * Quick function to override rule messages. + * + * @param msgTranslations The messages translations to apply. + */ + export function localize(msgTranslations: any): void; + + export const rules: ValidationRules; + + export interface ValidationRules { + [name: string]: ValidationRuleDefinition | ValidationAsyncRuleDefinition; + + required: ValidationRuleDefinition; + min: ValidationRuleDefinition; + max: ValidationRuleDefinition; + minLength: ValidationRuleDefinition; + maxLength: ValidationRuleDefinition; + pattern: ValidationRuleDefinition; + step: ValidationRuleDefinition; + email: ValidationRuleDefinition; + date: ValidationRuleDefinition; + dateISO: ValidationRuleDefinition; + number: ValidationRuleDefinition; + digit: ValidationRuleDefinition; + phoneUS: ValidationRuleDefinition; + equal: ValidationRuleDefinition; + notEqual: ValidationRuleDefinition; + unique: ValidationRuleDefinition; + } + + export namespace utils { + export function isArray(o: any): o is Array; + export function isObject(o: any): o is object; + export function isNumber(o: any): o is number; + export function isObservableArray(instance: any): instance is ko.ObservableArray; + export function values(o: string): any[]; + export function getValue(o: T | (() => T)): T; + export function hasAttribute(node: Element, attr: string): boolean; + export function getAttribute(element: Element, attr: string): string; + export function setAttribute(element: Element, attr: string, value: any): void; + export function isValidatable(o: any): o is ObservableValidationExtension; + export function insertAfter(node: Node, newNode: Node): void; + export function newId(): number; + export function getConfigOptions(element: Element): ValidationConfiguration; + export function setDomData(node: Node, data: any): void; + export function getDomData(node: Node): T; + export function contextFor(node: Node): any; + export function isEmptyVal(val: any): val is undefined | null | ""; + export function getOriginalElementTitle(element: Element): string; + export function async(expr: () => void): void; + export function forEach(array: T[], callback: (item: T, index: number, list: typeof array) => void): void; + export function forEach(object: T, callback: (key: keyof T, value: any) => void): void; + } + } + + /** Creates a validation group observable. */ + export function validatedObservable(initialValue?: T, options?: validation.ValidationGroupingOptions & { observable: true }): ko.Observable & { errors: validation.ValidationGroupComputed, isValid: ko.Observable }; + /** Creates a validation group observable. */ + export function validatedObservable(initialValue?: T, options?: validation.ValidationGroupingOptions): ko.Observable & { errors: validation.ValidationGroup, isValid: ko.Observable }; + /** Creates a new empty Validated Observable. */ + export function validatedObservable(initialValue: T): validation.ValidationObservable; + + /** Apply Binding with specified validation options. */ + export function applyBindingsWithValidation(viewModel: any, options?: validation.ValidationConfiguration): void; + /** Apply Binding with specified validation options. */ + export function applyBindingsWithValidation(viewModel: any, rootNode?: any, options?: validation.ValidationConfiguration): void; + + export interface BindingHandlers { + validationCore: { + init(element: HTMLElement, valueAccessor: () => ko.MaybeSubscribable, allBindingsAccessor: ko.AllBindings, viewModel: any, bindingContext: ko.BindingContext): void; + }; + validationMessage: { + init(element: HTMLElement, valueAccessor: () => ko.MaybeSubscribable): void; + }; + validationCovalidationElementre: { + init(element: HTMLElement, valueAccessor: () => ko.MaybeSubscribable, allBindingsAccessor: ko.AllBindings): void; + }; + validationOptions: { + init(element: HTMLElement, valueAccessor: () => ko.MaybeSubscribable, allBindingsAccessor: ko.AllBindings, viewModel: any, bindingContext: ko.BindingContext): void; + }; + } + + export interface Extenders { + /** + * This is for creating custom validation logic on the fly. + * + * @example + * var test = ko.observable("something").extend({ + * validation: { + * validator: function (val, someOtherVal) { + * return true; + * }, + * message: "Something must be really wrong!", + * params: true + * } + * }); + */ + validation>(target: T, options: validation.ValidationRule | validation.ValidationRule[]): T & validation.ObservableValidationExtension; + /** + * This is the extender that makes a Knockout Observable also 'Validatable' + * + * @example + * // This will ensure that the Observable object is setup properly to respond to rules + * var test = ko.observable("something").extend({ validatable: true }); + * + * // This will remove the validation properties from the Observable object should you need to do that. + * test.extend({ validatable: false }); + */ + validatable>(target: T, options: boolean | validation.ExtenderValidatableOptions): T & validation.ObservableValidationExtension; + + required>(target: T, options: validation.ValidationExtendType): T & validation.ObservableValidationExtension; + min>(target: T, options: validation.ValidationExtendType): T & validation.ObservableValidationExtension; + max>(target: T, options: validation.ValidationExtendType): T & validation.ObservableValidationExtension; + minLength>(target: T, options: validation.ValidationExtendType): T & validation.ObservableValidationExtension; + maxLength>(target: T, options: validation.ValidationExtendType): T & validation.ObservableValidationExtension; + pattern>(target: T, options: validation.ValidationExtendType): T & validation.ObservableValidationExtension; + step>(target: T, options: validation.ValidationExtendType): T & validation.ObservableValidationExtension; + email>(target: T, options: validation.ValidationExtendType): T & validation.ObservableValidationExtension; + date>(target: T, options: validation.ValidationExtendType): T & validation.ObservableValidationExtension; + dateISO>(target: T, options: validation.ValidationExtendType): T & validation.ObservableValidationExtension; + number>(target: T, options: validation.ValidationExtendType): T & validation.ObservableValidationExtension; + digit>(target: T, options: validation.ValidationExtendType): T & validation.ObservableValidationExtension; + phoneUS>(target: T, options: validation.ValidationExtendType): T & validation.ObservableValidationExtension; + equal>(target: T, options: validation.ValidationExtendAccessType): T & validation.ObservableValidationExtension; + notEqual>(target: T, options: validation.ValidationExtendAccessType): T & validation.ObservableValidationExtension; + unique>(target: T, options: validation.ValidationExtendType): T & validation.ObservableValidationExtension; + } + + export interface SubscribableFunctions { + extend(requestedExtenders: validation.ValidationExtendOptions): this & validation.ObservableValidationExtension; + } + + export interface ObservableExtenderOptions extends validation.ValidationExtendOptions { } +} + +export = ko.validation; diff --git a/package.json b/package.json index 3408200..cbe40be 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "2.0.4", "description": "A KnockoutJS Plugin for model and property validation", "main": "dist/knockout.validation.js", + "types": "dist/knockout.validation.d.ts", "files": [ "dist", "localization",