diff --git a/decorum/decorum-tests.ts b/decorum/decorum-tests.ts
new file mode 100644
index 0000000000..dd1743b5e7
--- /dev/null
+++ b/decorum/decorum-tests.ts
@@ -0,0 +1,102 @@
+///
+
+import {Required} from 'decorum';
+import {Email} from 'decorum';
+import {MinLength} from 'decorum';
+import {MaxLength} from 'decorum';
+import {Length} from 'decorum';
+import {FieldName} from 'decorum';
+import {Validation} from 'decorum';
+import {Pattern} from 'decorum';
+import {Validator} from 'decorum';
+import {BaseValidator} from 'decorum';
+
+class MyModel {
+ @FieldName('User name')
+ @Required()
+ @MaxLength(50)
+ username = '';
+
+ @FieldName('Email address')
+ @Email()
+ @Required('Your email address will be used to send you a confirmation email. You must fill it out')
+ emailAddress = '';
+
+ @Required()
+ @MinLength(10)
+ @MaxLength(30)
+ password = '';
+
+ @FieldName('Confirm password')
+ @Validation(
+ 'The passwords do not match.',
+ (pwd, model) => model.password === pwd
+ )
+ confirmPassword = '';
+
+ @Pattern(/^[a-z0-9-]+$/i, 'Must be a valid slug tag')
+ slug = 'foo';
+
+ @Length(6, 'Alias must be 6 characters long')
+ alias: string;
+}
+
+// ES6-style
+class MyController {
+ model = new MyModel();
+ validator = Validator.new(this.model);
+
+ doStuff(): void {
+ var opts = this.validator.getValidationOptions('alias');
+ var fieldName = opts.getFieldName();
+ var errs = opts.validateValue('foo', this.model);
+ opts.setFieldName('Foo');
+ opts.addValidator(null);
+ var validators = opts.getValidators();
+ }
+
+ validate(): void {
+ var result = this.validator.validate();
+ if (!result.isValid) {
+ for(var i = 0; i < result.errors.length; i++) {
+ var current = result.errors[i];
+ console.error(current.fieldName, current.errors);
+ }
+ }
+ }
+}
+
+// ES5-style
+function MyOtherModel() {
+ this.foo = '';
+ this.bar = '';
+}
+
+Validator.decorate(MyOtherModel, {
+ foo: [
+ Required()
+ ],
+ bar: [
+ Pattern(/^[a-z][0-9]$/i)
+ ]
+});
+
+var otherValidator = Validator.new(new MyOtherModel());
+otherValidator.validateField('foo', '');
+
+// Custom validator
+class MyValidator extends BaseValidator {
+
+ validatesEmptyValue(): boolean {
+ return false;
+ }
+
+ getMessage(fieldName: string, fieldValue: any): string {
+ return 'No!';
+ }
+
+ isValid(value: any, model: any): boolean {
+ return false;
+ }
+
+}
diff --git a/decorum/decorum-tests.ts.tscparams b/decorum/decorum-tests.ts.tscparams
new file mode 100644
index 0000000000..5300ee7222
--- /dev/null
+++ b/decorum/decorum-tests.ts.tscparams
@@ -0,0 +1,2 @@
+--experimentalDecorators
+--target ES5
diff --git a/decorum/decorum.d.ts b/decorum/decorum.d.ts
new file mode 100644
index 0000000000..858b1e2dd5
--- /dev/null
+++ b/decorum/decorum.d.ts
@@ -0,0 +1,292 @@
+// Type definitions for Decorum JS v0.1.2
+// Project: https://github.com/dflor003/decorum
+// Definitions by: Danil Flores
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+declare module 'decorum' {
+ /**
+ * A generic custom validation. Takes a predicate that will receive the proposed value as the first parameter and the
+ * current model state as the second.
+ * @param message The message to display when the predicate fails.
+ * @param predicate A lambda expression/function that determines if the value is valid. If it returns a falsy value, the
+ * field will be considered invalid and will return the passed error message upon validation.
+ * @returns {function(Object, string): void} A field validation decorator.
+ */
+ export function Validation(message: string, predicate: (value: any, model: TModel) => boolean): PropertyDecorator;
+
+ /**
+ * Validate's that the field is a valid email address. The format used is the same as the webkit browser's internal
+ * email validation format. For looser or stricter formats, use your own validation based on the @Pattern decorator.
+ * @param message [Optional] Overrides the default validation error message.
+ * @returns {function(Object, string): void} A field validation decorator.
+ */
+ export function Email(message?: string): PropertyDecorator;
+
+ /**
+ * Sets the field's "friendly" name in validation error messages.
+ * @param name The field's friendly name
+ * @returns {function(Object, string): void} A field validation decorator.
+ */
+ export function FieldName(name: string): PropertyDecorator;
+
+ /**
+ * Validate's a field's EXACT length. Validation fails if the field is not EXACTLY the length passed.
+ * @param length The exact length the field must be.
+ * @param message [Optional] Overrides the default validation error message.
+ * @returns {function(Object, string): void} A field validation decorator.
+ */
+ export function Length(length: number, message?: string): PropertyDecorator;
+
+ /**
+ * Validates a field's maximum length.
+ * @param maxLength The field's maximum length. Must be a positive integer greater than 1.
+ * @param message [Optional] Overrides the default validation error message.
+ * @returns {function(Object, string): void} A field validation decorator.
+ */
+ export function MaxLength(maxLength: number, message?: string): PropertyDecorator;
+
+ /**
+ * Validates the field's minimum length.
+ * @param minLength The field's minimum length. Must be a positive integer greater than 0
+ * @param message [Optional] Overrides the default validation error message.
+ * @returns {function(Object, string): void} A field validation decorator.
+ */
+ export function MinLength(minLength: number, message?: string): PropertyDecorator;
+
+ /**
+ * Validates the field against a regular expression pattern.
+ * @param regex The regex to validate against. Should be a valid JavaScript {RegExp} instance.
+ * @param message [Optional] Overrides the default validation error message.
+ * @returns {function(Object, string): void} A field validation decorator.
+ */
+ export function Pattern(regex: RegExp, message?: string): PropertyDecorator;
+
+ /**
+ * Marks the field as required.
+ * @param message [Optional] Overrides the default validation error message.
+ * @returns {function(Object, string): void} A field validation decorator.
+ */
+ export function Required(message?: string): PropertyDecorator;
+
+ /**
+ * A map from field name to array of field validation decorators.
+ */
+ export type ValidationDefinitions = {
+ [field: string]: PropertyDecorator[];
+ };
+
+ /**
+ * Static container for convenience methods related to field validation.
+ */
+ export class Validator {
+ /**
+ * Creates a new model validator for the given model. Model should be a valid class that has a valid constructor
+ * and a prototype.
+ * @param model The model to create the validator for.
+ * @returns {ModelValidator} An instance of {ModelValidator}
+ */
+ static new(model: any): ModelValidator;
+
+ /**
+ * Decorates the passed class with model validations. Use this when you do not have access to ES7 decorators.
+ * The object passed should be a valid class (ES6 class or ES5 function constructor).
+ * @param objectType The class to decorate.
+ * @param definitions One or more field validation definitions of the form { "fieldName": [ decorators ] }.
+ */
+ static decorate(objectType: any, definitions: ValidationDefinitions): void;
+
+ /**
+ * Creates an anonymous validator, immediately validates the model, and returns any validation errors on the model
+ * as a result.
+ * @param model The model to validate.
+ */
+ static validate(model: any): IValidationResult;
+ }
+
+ /**
+ * Details about validation errors on a field.
+ */
+ export interface IFieldValidationError {
+ /**
+ * The property name of the field on the model.
+ */
+ field: string;
+
+ /**
+ * The "friendly" name of the field. If not set on the model via @FieldName(...), it will default to "Field".
+ */
+ fieldName: string;
+
+ /**
+ * One or more field validation errors. Empty if no errors.
+ */
+ errors: string[];
+ }
+
+ /**
+ * Result returned when a model is validated.
+ */
+ export interface IValidationResult {
+ /**
+ * Whether or not the model is valid.
+ */
+ isValid: boolean;
+
+ /**
+ * A map of field name to validation errors.
+ */
+ errors: IFieldValidationError[];
+ }
+
+ /**
+ * Wraps a model to allow the consuming class to call validation methods.
+ */
+ export class ModelValidator {
+ /**
+ * Creates a new model validator.
+ * @param model The model to validate. Should be a class that has a valid constructor function and prototype.
+ */
+ constructor(model: any);
+
+ /**
+ * Gets the validation options for the given field name.
+ * @param fieldKey The name of the field to get options for.
+ * @returns {FieldOptions} The field options associated with that field or null if no validations defined
+ * for the field.
+ */
+ getValidationOptions(fieldKey: string): FieldOptions;
+
+ /**
+ * Validates the given field on this {ModelValidator}'s model. If a proposed value is passed, validate
+ * against that passed value; otherwise, use the field's current value on the model.
+ * @param fieldKey The name of the field to validate.
+ * @param proposedValue [Optional] The proposed value to set on the field.
+ * @returns {string[]} An array of field validation error messages if the field is invalid; otherwise,
+ * an empty array.
+ */
+ validateField(fieldKey: string, proposedValue?: any): string[];
+
+ /**
+ * Validate the entire model and return a result that indicates whether the model is valid or not and any errors
+ * that have occurred in an object indexed by field name on the model.
+ * @returns {IValidationResult} An object that contains whether the model is valid or not and errors by field name.
+ */
+ validate(): IValidationResult;
+ }
+
+ /**
+ * Callback invoked when a validation needs to return an error. Parameters include field name,
+ * field value, and any other properties relating to the field validation itself.
+ */
+ export type MessageHandler = (fieldName: string, fieldValue: any, ...args: any[]) => string;
+
+ /**
+ * A map of validation "key" (unique name for a given type of validation) to message handler callback.
+ */
+ export interface IMessageHandlerMap {
+ [key: string]: MessageHandler;
+ }
+
+ /**
+ * Mechanism for overriding validation errors to provide for custom or localized error messages.
+ * @type {{IMessageHandlerMap}}
+ */
+ let MessageHandlers: IMessageHandlerMap;
+
+ /**
+ * Validation options for a given field including actual validators and meta data such as the field name.
+ */
+ export class FieldOptions {
+ /**
+ * Gets the "friendly" name of the field for use in validation error messages. Defaults to just "Field".
+ * @returns {string}
+ */
+ getFieldName(): string;
+
+ /**
+ * Sets the "friendly" name of the field for use in validation error messages. This name will be used in the text
+ * of validation errors.
+ * @param name The new name to set.
+ */
+ setFieldName(name: string): void;
+
+ /**
+ * Add a validator to the list of validators for this field.
+ * @param validator The validator to add. Should be a class that extends from {BaseValidator}.
+ */
+ addValidator(validator: BaseValidator): void;
+
+ /**
+ * Gets the validators assigned to this field.
+ * @returns {BaseValidator[]} The validators for this field.
+ */
+ getValidators(): BaseValidator[];
+
+ /**
+ * Runs through all of the validators for the field given a particular value and returns any validation errors that
+ * may have occurred.
+ * @param value The value to validate.
+ * @param model The rest of the model. Used in custom cross-field validations.
+ * @returns {string[]} Any validation errors that may have occurred or an empty array if the value passed is valid
+ * for the field.
+ */
+ validateValue(value: any, model: any): string[];
+ }
+
+ /**
+ * Base abstract class for all validators. Methods that must be overridden:
+ * getMessage(...) - Get error message to return when field is invalid.
+ * isValid(...) - Check validity of field given proposed value and the rest of the model.
+ */
+ abstract class BaseValidator {
+ /**
+ * Initializes the {BaseValidator}
+ * @param validatorKey A unique "key" by which to identify this field validator i.e. length, maxlength, required.
+ * Should be a valid JS property name.
+ * @param message A custom error message to return. Should be passed down from concrete class' constructors to enable
+ * customizing error messages.
+ */
+ constructor(validatorKey: string, message: string);
+
+ /**
+ * Returns true if the validator instance was passed a custom error message.
+ */
+ hasCustomMessage: boolean;
+
+ /**
+ * Check whether this validator should process an "empty" value (i.e. null, undefined, empty string). Override
+ * this in derived classes to skip validators if the field value hasn't been set. Things like email, min/max length,
+ * and pattern should return false for this to ensure they don't get fired when the model is initially empty
+ * before a user has had a chance to input a value. Things like required should override this to true so that
+ * they are fired for empty values. Base implementation defaults to false
+ * @returns {boolean}
+ */
+ validatesEmptyValue(): boolean;
+
+ /**
+ * Gets the custom error message set on this validator.
+ * @returns {string} The custom error message or null if none has been set.
+ */
+ getCustomMessage(): string;
+
+ /**
+ * Gets the unique name for this validator.
+ * @returns {string} The unique name for this validator.
+ */
+ getKey(): string;
+
+ /**
+ * [Abstract] Gets the error message to display when a field fails validation by this validator.
+ * @param fieldName The "friendly" name set for the field.
+ * @param fieldValue The field's current value.
+ */
+ abstract getMessage(fieldName: string, fieldValue: any): string;
+
+ /**
+ * [Abstract] Checks the passed value for validity.
+ * @param value The field's proposed value.
+ * @param model The rest of the model if cross-field validity checks are necessary.
+ */
+ abstract isValid(value: any, model: any): boolean;
+ }
+}