From 075b0a5afe3aa1a611c011ec4f6ba0c34d475300 Mon Sep 17 00:00:00 2001 From: Jeremy Danyow Date: Fri, 28 Sep 2018 21:29:38 -0700 Subject: [PATCH] build --- dist/amd/aurelia-validation.js | 1863 +++++++++++++++- dist/amd/controller-validate-result.d.ts | 19 - dist/amd/controller-validate-result.js | 4 - dist/amd/get-target-dom-element.d.ts | 7 - dist/amd/get-target-dom-element.js | 31 - .../implementation/expression-visitor.d.ts | 33 - dist/amd/implementation/expression-visitor.js | 79 - dist/amd/implementation/rule.d.ts | 28 - dist/amd/implementation/rule.js | 4 - dist/amd/implementation/rules.d.ts | 22 - dist/amd/implementation/rules.js | 41 - .../implementation/standard-validator.d.ts | 40 - dist/amd/implementation/standard-validator.js | 139 -- .../validation-message-parser.js | 69 - .../implementation/validation-messages.d.ts | 29 - .../amd/implementation/validation-messages.js | 61 - dist/amd/implementation/validation-rules.d.ts | 262 --- dist/amd/implementation/validation-rules.js | 443 ---- dist/amd/property-accessor-parser.js | 36 - dist/amd/property-info.d.ts | 10 - dist/amd/property-info.js | 45 - dist/amd/util.js | 12 - dist/amd/validate-binding-behavior-base.js | 79 - dist/amd/validate-binding-behavior.d.ts | 48 - dist/amd/validate-binding-behavior.js | 98 - dist/amd/validate-event.d.ts | 62 - dist/amd/validate-event.js | 43 - dist/amd/validate-instruction.d.ts | 17 - dist/amd/validate-instruction.js | 4 - dist/amd/validate-result.js | 30 - dist/amd/validate-trigger.js | 28 - dist/amd/validation-controller-factory.d.ts | 20 - dist/amd/validation-controller-factory.js | 37 - dist/amd/validation-controller.js | 411 ---- .../validation-errors-custom-attribute.d.ts | 25 - .../amd/validation-errors-custom-attribute.js | 81 - .../validation-renderer-custom-attribute.d.ts | 9 - .../validation-renderer-custom-attribute.js | 23 - dist/amd/validation-renderer.d.ts | 42 - dist/amd/validation-renderer.js | 4 - dist/amd/validator.d.ts | 27 - dist/amd/validator.js | 13 - dist/commonjs/aurelia-validation.d.ts | 46 - dist/commonjs/aurelia-validation.js | 1868 +++++++++++++++- dist/commonjs/controller-validate-result.d.ts | 19 - dist/commonjs/controller-validate-result.js | 2 - dist/commonjs/get-target-dom-element.d.ts | 7 - dist/commonjs/get-target-dom-element.js | 30 - .../implementation/expression-visitor.js | 77 - dist/commonjs/implementation/rule.d.ts | 28 - dist/commonjs/implementation/rule.js | 2 - dist/commonjs/implementation/rules.d.ts | 22 - dist/commonjs/implementation/rules.js | 39 - .../implementation/standard-validator.d.ts | 40 - .../implementation/standard-validator.js | 142 -- .../validation-message-parser.d.ts | 20 - .../validation-message-parser.js | 71 - .../implementation/validation-messages.js | 60 - .../implementation/validation-rules.js | 444 ---- dist/commonjs/property-accessor-parser.d.ts | 9 - dist/commonjs/property-accessor-parser.js | 36 - dist/commonjs/property-info.d.ts | 10 - dist/commonjs/property-info.js | 44 - dist/commonjs/util.d.ts | 2 - dist/commonjs/util.js | 10 - .../validate-binding-behavior-base.d.ts | 13 - .../validate-binding-behavior-base.js | 81 - dist/commonjs/validate-binding-behavior.d.ts | 48 - dist/commonjs/validate-binding-behavior.js | 99 - dist/commonjs/validate-event.d.ts | 62 - dist/commonjs/validate-event.js | 41 - dist/commonjs/validate-instruction.js | 2 - dist/commonjs/validate-result.d.ts | 23 - dist/commonjs/validate-result.js | 28 - dist/commonjs/validate-trigger.d.ts | 23 - dist/commonjs/validate-trigger.js | 26 - .../validation-controller-factory.d.ts | 20 - .../commonjs/validation-controller-factory.js | 38 - dist/commonjs/validation-controller.d.ts | 131 -- dist/commonjs/validation-controller.js | 415 ---- .../validation-errors-custom-attribute.js | 84 - .../validation-renderer-custom-attribute.js | 22 - dist/commonjs/validation-renderer.d.ts | 42 - dist/commonjs/validation-renderer.js | 2 - dist/commonjs/validator.d.ts | 27 - dist/commonjs/validator.js | 11 - dist/es2015/aurelia-validation.d.ts | 46 - dist/es2015/aurelia-validation.js | 1709 ++++++++++++++- dist/es2015/controller-validate-result.js | 0 dist/es2015/get-target-dom-element.js | 27 - .../implementation/expression-visitor.d.ts | 33 - .../implementation/expression-visitor.js | 71 - dist/es2015/implementation/rule.js | 0 dist/es2015/implementation/rules.js | 33 - .../implementation/standard-validator.js | 122 -- .../validation-message-parser.d.ts | 20 - .../validation-message-parser.js | 53 - .../implementation/validation-messages.d.ts | 29 - .../implementation/validation-messages.js | 56 - .../implementation/validation-rules.d.ts | 262 --- .../es2015/implementation/validation-rules.js | 412 ---- dist/es2015/property-accessor-parser.d.ts | 9 - dist/es2015/property-accessor-parser.js | 31 - dist/es2015/property-info.js | 41 - dist/es2015/util.d.ts | 2 - dist/es2015/util.js | 6 - .../validate-binding-behavior-base.d.ts | 13 - dist/es2015/validate-binding-behavior-base.js | 76 - dist/es2015/validate-binding-behavior.js | 57 - dist/es2015/validate-event.js | 37 - dist/es2015/validate-instruction.d.ts | 17 - dist/es2015/validate-instruction.js | 0 dist/es2015/validate-result.d.ts | 23 - dist/es2015/validate-result.js | 23 - dist/es2015/validate-trigger.d.ts | 23 - dist/es2015/validate-trigger.js | 24 - dist/es2015/validation-controller-factory.js | 34 - dist/es2015/validation-controller.d.ts | 131 -- dist/es2015/validation-controller.js | 392 ---- .../validation-errors-custom-attribute.d.ts | 25 - .../validation-errors-custom-attribute.js | 74 - .../validation-renderer-custom-attribute.d.ts | 9 - .../validation-renderer-custom-attribute.js | 16 - dist/es2015/validation-renderer.js | 0 dist/es2015/validator.js | 5 - dist/es2017/aurelia-validation.d.ts | 46 - dist/es2017/aurelia-validation.js | 1709 ++++++++++++++- dist/es2017/controller-validate-result.d.ts | 19 - dist/es2017/controller-validate-result.js | 0 dist/es2017/get-target-dom-element.d.ts | 7 - dist/es2017/get-target-dom-element.js | 27 - .../implementation/expression-visitor.d.ts | 33 - .../implementation/expression-visitor.js | 71 - dist/es2017/implementation/rule.d.ts | 28 - dist/es2017/implementation/rule.js | 0 dist/es2017/implementation/rules.d.ts | 22 - dist/es2017/implementation/rules.js | 33 - .../implementation/standard-validator.d.ts | 40 - .../implementation/standard-validator.js | 122 -- .../validation-message-parser.d.ts | 20 - .../validation-message-parser.js | 53 - .../implementation/validation-messages.d.ts | 29 - .../implementation/validation-messages.js | 56 - .../implementation/validation-rules.d.ts | 262 --- .../es2017/implementation/validation-rules.js | 412 ---- dist/es2017/property-accessor-parser.d.ts | 9 - dist/es2017/property-accessor-parser.js | 31 - dist/es2017/property-info.d.ts | 10 - dist/es2017/property-info.js | 41 - dist/es2017/util.d.ts | 2 - dist/es2017/util.js | 6 - .../validate-binding-behavior-base.d.ts | 13 - dist/es2017/validate-binding-behavior-base.js | 76 - dist/es2017/validate-binding-behavior.d.ts | 48 - dist/es2017/validate-binding-behavior.js | 57 - dist/es2017/validate-event.d.ts | 62 - dist/es2017/validate-event.js | 37 - dist/es2017/validate-instruction.d.ts | 17 - dist/es2017/validate-instruction.js | 0 dist/es2017/validate-result.d.ts | 23 - dist/es2017/validate-result.js | 23 - dist/es2017/validate-trigger.d.ts | 23 - dist/es2017/validate-trigger.js | 24 - .../es2017/validation-controller-factory.d.ts | 20 - dist/es2017/validation-controller-factory.js | 34 - dist/es2017/validation-controller.d.ts | 131 -- dist/es2017/validation-controller.js | 392 ---- .../validation-errors-custom-attribute.d.ts | 25 - .../validation-errors-custom-attribute.js | 74 - .../validation-renderer-custom-attribute.d.ts | 9 - .../validation-renderer-custom-attribute.js | 16 - dist/es2017/validation-renderer.d.ts | 42 - dist/es2017/validation-renderer.js | 0 dist/es2017/validator.d.ts | 27 - dist/es2017/validator.js | 5 - dist/native-modules/aurelia-validation.d.ts | 46 - dist/native-modules/aurelia-validation.js | 1836 +++++++++++++++- .../controller-validate-result.d.ts | 19 - .../controller-validate-result.js | 0 .../get-target-dom-element.d.ts | 7 - dist/native-modules/get-target-dom-element.js | 27 - .../implementation/expression-visitor.d.ts | 33 - .../implementation/expression-visitor.js | 75 - dist/native-modules/implementation/rule.d.ts | 28 - dist/native-modules/implementation/rule.js | 0 dist/native-modules/implementation/rules.d.ts | 22 - dist/native-modules/implementation/rules.js | 37 - .../implementation/standard-validator.d.ts | 40 - .../implementation/standard-validator.js | 140 -- .../validation-message-parser.d.ts | 20 - .../validation-message-parser.js | 69 - .../implementation/validation-messages.d.ts | 29 - .../implementation/validation-messages.js | 58 - .../implementation/validation-rules.d.ts | 262 --- .../implementation/validation-rules.js | 442 ---- .../property-accessor-parser.d.ts | 9 - .../property-accessor-parser.js | 33 - dist/native-modules/property-info.d.ts | 10 - dist/native-modules/property-info.js | 41 - dist/native-modules/util.d.ts | 2 - dist/native-modules/util.js | 6 - .../validate-binding-behavior-base.d.ts | 13 - .../validate-binding-behavior-base.js | 79 - .../validate-binding-behavior.d.ts | 48 - .../validate-binding-behavior.js | 97 - dist/native-modules/validate-event.d.ts | 62 - dist/native-modules/validate-event.js | 39 - dist/native-modules/validate-instruction.d.ts | 17 - dist/native-modules/validate-instruction.js | 0 dist/native-modules/validate-result.d.ts | 23 - dist/native-modules/validate-result.js | 26 - dist/native-modules/validate-trigger.d.ts | 23 - dist/native-modules/validate-trigger.js | 24 - .../validation-controller-factory.d.ts | 20 - .../validation-controller-factory.js | 36 - .../native-modules/validation-controller.d.ts | 131 -- dist/native-modules/validation-controller.js | 413 ---- .../validation-errors-custom-attribute.d.ts | 25 - .../validation-errors-custom-attribute.js | 82 - .../validation-renderer-custom-attribute.d.ts | 9 - .../validation-renderer-custom-attribute.js | 20 - dist/native-modules/validation-renderer.d.ts | 42 - dist/native-modules/validation-renderer.js | 0 dist/native-modules/validator.d.ts | 27 - dist/native-modules/validator.js | 9 - dist/system/aurelia-validation.d.ts | 46 - dist/system/aurelia-validation.js | 1933 +++++++++++++++-- dist/system/controller-validate-result.d.ts | 19 - dist/system/controller-validate-result.js | 9 - dist/system/get-target-dom-element.d.ts | 7 - dist/system/get-target-dom-element.js | 41 - .../implementation/expression-visitor.d.ts | 33 - .../implementation/expression-visitor.js | 85 - dist/system/implementation/rule.d.ts | 28 - dist/system/implementation/rule.js | 9 - dist/system/implementation/rules.d.ts | 22 - dist/system/implementation/rules.js | 47 - .../implementation/standard-validator.d.ts | 40 - .../implementation/standard-validator.js | 157 -- .../validation-message-parser.d.ts | 20 - .../validation-message-parser.js | 88 - .../implementation/validation-messages.d.ts | 29 - .../implementation/validation-messages.js | 68 - .../implementation/validation-rules.d.ts | 262 --- .../system/implementation/validation-rules.js | 456 ---- dist/system/property-accessor-parser.d.ts | 9 - dist/system/property-accessor-parser.js | 49 - dist/system/property-info.d.ts | 10 - dist/system/property-info.js | 55 - dist/system/util.d.ts | 2 - dist/system/util.js | 17 - .../validate-binding-behavior-base.d.ts | 13 - dist/system/validate-binding-behavior-base.js | 98 - dist/system/validate-binding-behavior.d.ts | 48 - dist/system/validate-binding-behavior.js | 114 - dist/system/validate-event.d.ts | 62 - dist/system/validate-event.js | 49 - dist/system/validate-instruction.d.ts | 17 - dist/system/validate-instruction.js | 9 - dist/system/validate-result.d.ts | 23 - dist/system/validate-result.js | 33 - dist/system/validate-trigger.d.ts | 23 - dist/system/validate-trigger.js | 34 - .../system/validation-controller-factory.d.ts | 20 - dist/system/validation-controller-factory.js | 53 - dist/system/validation-controller.d.ts | 131 -- dist/system/validation-controller.js | 431 ---- .../validation-errors-custom-attribute.d.ts | 25 - .../validation-errors-custom-attribute.js | 103 - .../validation-renderer-custom-attribute.d.ts | 9 - .../validation-renderer-custom-attribute.js | 33 - dist/system/validation-renderer.d.ts | 42 - dist/system/validation-renderer.js | 9 - dist/system/validator.d.ts | 27 - dist/system/validator.js | 19 - dist/{amd => types}/aurelia-validation.d.ts | 92 +- .../controller-validate-result.d.ts | 38 +- .../get-target-dom-element.d.ts | 14 +- .../implementation/expression-visitor.d.ts | 66 +- .../implementation/rule.d.ts | 56 +- .../implementation/rules.d.ts | 44 +- .../implementation/standard-validator.d.ts | 80 +- .../validation-message-parser.d.ts | 40 +- .../implementation/validation-messages.d.ts | 58 +- .../implementation/validation-rules.d.ts | 524 ++--- .../property-accessor-parser.d.ts | 18 +- dist/{es2015 => types}/property-info.d.ts | 20 +- dist/{amd => types}/util.d.ts | 4 +- .../validate-binding-behavior-base.d.ts | 26 +- .../validate-binding-behavior.d.ts | 96 +- dist/{es2015 => types}/validate-event.d.ts | 124 +- .../validate-instruction.d.ts | 34 +- dist/{amd => types}/validate-result.d.ts | 46 +- dist/{amd => types}/validate-trigger.d.ts | 46 +- .../validation-controller-factory.d.ts | 40 +- .../{amd => types}/validation-controller.d.ts | 262 +-- .../validation-errors-custom-attribute.d.ts | 50 +- .../validation-renderer-custom-attribute.d.ts | 18 +- .../validation-renderer.d.ts | 84 +- dist/{es2015 => types}/validator.d.ts | 54 +- doc/api.json | 2 +- 301 files changed, 11430 insertions(+), 16879 deletions(-) delete mode 100644 dist/amd/controller-validate-result.d.ts delete mode 100644 dist/amd/controller-validate-result.js delete mode 100644 dist/amd/get-target-dom-element.d.ts delete mode 100644 dist/amd/get-target-dom-element.js delete mode 100644 dist/amd/implementation/expression-visitor.d.ts delete mode 100644 dist/amd/implementation/expression-visitor.js delete mode 100644 dist/amd/implementation/rule.d.ts delete mode 100644 dist/amd/implementation/rule.js delete mode 100644 dist/amd/implementation/rules.d.ts delete mode 100644 dist/amd/implementation/rules.js delete mode 100644 dist/amd/implementation/standard-validator.d.ts delete mode 100644 dist/amd/implementation/standard-validator.js delete mode 100644 dist/amd/implementation/validation-message-parser.js delete mode 100644 dist/amd/implementation/validation-messages.d.ts delete mode 100644 dist/amd/implementation/validation-messages.js delete mode 100644 dist/amd/implementation/validation-rules.d.ts delete mode 100644 dist/amd/implementation/validation-rules.js delete mode 100644 dist/amd/property-accessor-parser.js delete mode 100644 dist/amd/property-info.d.ts delete mode 100644 dist/amd/property-info.js delete mode 100644 dist/amd/util.js delete mode 100644 dist/amd/validate-binding-behavior-base.js delete mode 100644 dist/amd/validate-binding-behavior.d.ts delete mode 100644 dist/amd/validate-binding-behavior.js delete mode 100644 dist/amd/validate-event.d.ts delete mode 100644 dist/amd/validate-event.js delete mode 100644 dist/amd/validate-instruction.d.ts delete mode 100644 dist/amd/validate-instruction.js delete mode 100644 dist/amd/validate-result.js delete mode 100644 dist/amd/validate-trigger.js delete mode 100644 dist/amd/validation-controller-factory.d.ts delete mode 100644 dist/amd/validation-controller-factory.js delete mode 100644 dist/amd/validation-controller.js delete mode 100644 dist/amd/validation-errors-custom-attribute.d.ts delete mode 100644 dist/amd/validation-errors-custom-attribute.js delete mode 100644 dist/amd/validation-renderer-custom-attribute.d.ts delete mode 100644 dist/amd/validation-renderer-custom-attribute.js delete mode 100644 dist/amd/validation-renderer.d.ts delete mode 100644 dist/amd/validation-renderer.js delete mode 100644 dist/amd/validator.d.ts delete mode 100644 dist/amd/validator.js delete mode 100644 dist/commonjs/aurelia-validation.d.ts delete mode 100644 dist/commonjs/controller-validate-result.d.ts delete mode 100644 dist/commonjs/controller-validate-result.js delete mode 100644 dist/commonjs/get-target-dom-element.d.ts delete mode 100644 dist/commonjs/get-target-dom-element.js delete mode 100644 dist/commonjs/implementation/expression-visitor.js delete mode 100644 dist/commonjs/implementation/rule.d.ts delete mode 100644 dist/commonjs/implementation/rule.js delete mode 100644 dist/commonjs/implementation/rules.d.ts delete mode 100644 dist/commonjs/implementation/rules.js delete mode 100644 dist/commonjs/implementation/standard-validator.d.ts delete mode 100644 dist/commonjs/implementation/standard-validator.js delete mode 100644 dist/commonjs/implementation/validation-message-parser.d.ts delete mode 100644 dist/commonjs/implementation/validation-message-parser.js delete mode 100644 dist/commonjs/implementation/validation-messages.js delete mode 100644 dist/commonjs/implementation/validation-rules.js delete mode 100644 dist/commonjs/property-accessor-parser.d.ts delete mode 100644 dist/commonjs/property-accessor-parser.js delete mode 100644 dist/commonjs/property-info.d.ts delete mode 100644 dist/commonjs/property-info.js delete mode 100644 dist/commonjs/util.d.ts delete mode 100644 dist/commonjs/util.js delete mode 100644 dist/commonjs/validate-binding-behavior-base.d.ts delete mode 100644 dist/commonjs/validate-binding-behavior-base.js delete mode 100644 dist/commonjs/validate-binding-behavior.d.ts delete mode 100644 dist/commonjs/validate-binding-behavior.js delete mode 100644 dist/commonjs/validate-event.d.ts delete mode 100644 dist/commonjs/validate-event.js delete mode 100644 dist/commonjs/validate-instruction.js delete mode 100644 dist/commonjs/validate-result.d.ts delete mode 100644 dist/commonjs/validate-result.js delete mode 100644 dist/commonjs/validate-trigger.d.ts delete mode 100644 dist/commonjs/validate-trigger.js delete mode 100644 dist/commonjs/validation-controller-factory.d.ts delete mode 100644 dist/commonjs/validation-controller-factory.js delete mode 100644 dist/commonjs/validation-controller.d.ts delete mode 100644 dist/commonjs/validation-controller.js delete mode 100644 dist/commonjs/validation-errors-custom-attribute.js delete mode 100644 dist/commonjs/validation-renderer-custom-attribute.js delete mode 100644 dist/commonjs/validation-renderer.d.ts delete mode 100644 dist/commonjs/validation-renderer.js delete mode 100644 dist/commonjs/validator.d.ts delete mode 100644 dist/commonjs/validator.js delete mode 100644 dist/es2015/aurelia-validation.d.ts delete mode 100644 dist/es2015/controller-validate-result.js delete mode 100644 dist/es2015/get-target-dom-element.js delete mode 100644 dist/es2015/implementation/expression-visitor.d.ts delete mode 100644 dist/es2015/implementation/expression-visitor.js delete mode 100644 dist/es2015/implementation/rule.js delete mode 100644 dist/es2015/implementation/rules.js delete mode 100644 dist/es2015/implementation/standard-validator.js delete mode 100644 dist/es2015/implementation/validation-message-parser.d.ts delete mode 100644 dist/es2015/implementation/validation-message-parser.js delete mode 100644 dist/es2015/implementation/validation-messages.d.ts delete mode 100644 dist/es2015/implementation/validation-messages.js delete mode 100644 dist/es2015/implementation/validation-rules.d.ts delete mode 100644 dist/es2015/implementation/validation-rules.js delete mode 100644 dist/es2015/property-accessor-parser.d.ts delete mode 100644 dist/es2015/property-accessor-parser.js delete mode 100644 dist/es2015/property-info.js delete mode 100644 dist/es2015/util.d.ts delete mode 100644 dist/es2015/util.js delete mode 100644 dist/es2015/validate-binding-behavior-base.d.ts delete mode 100644 dist/es2015/validate-binding-behavior-base.js delete mode 100644 dist/es2015/validate-binding-behavior.js delete mode 100644 dist/es2015/validate-event.js delete mode 100644 dist/es2015/validate-instruction.d.ts delete mode 100644 dist/es2015/validate-instruction.js delete mode 100644 dist/es2015/validate-result.d.ts delete mode 100644 dist/es2015/validate-result.js delete mode 100644 dist/es2015/validate-trigger.d.ts delete mode 100644 dist/es2015/validate-trigger.js delete mode 100644 dist/es2015/validation-controller-factory.js delete mode 100644 dist/es2015/validation-controller.d.ts delete mode 100644 dist/es2015/validation-controller.js delete mode 100644 dist/es2015/validation-errors-custom-attribute.d.ts delete mode 100644 dist/es2015/validation-errors-custom-attribute.js delete mode 100644 dist/es2015/validation-renderer-custom-attribute.d.ts delete mode 100644 dist/es2015/validation-renderer-custom-attribute.js delete mode 100644 dist/es2015/validation-renderer.js delete mode 100644 dist/es2015/validator.js delete mode 100644 dist/es2017/aurelia-validation.d.ts delete mode 100644 dist/es2017/controller-validate-result.d.ts delete mode 100644 dist/es2017/controller-validate-result.js delete mode 100644 dist/es2017/get-target-dom-element.d.ts delete mode 100644 dist/es2017/get-target-dom-element.js delete mode 100644 dist/es2017/implementation/expression-visitor.d.ts delete mode 100644 dist/es2017/implementation/expression-visitor.js delete mode 100644 dist/es2017/implementation/rule.d.ts delete mode 100644 dist/es2017/implementation/rule.js delete mode 100644 dist/es2017/implementation/rules.d.ts delete mode 100644 dist/es2017/implementation/rules.js delete mode 100644 dist/es2017/implementation/standard-validator.d.ts delete mode 100644 dist/es2017/implementation/standard-validator.js delete mode 100644 dist/es2017/implementation/validation-message-parser.d.ts delete mode 100644 dist/es2017/implementation/validation-message-parser.js delete mode 100644 dist/es2017/implementation/validation-messages.d.ts delete mode 100644 dist/es2017/implementation/validation-messages.js delete mode 100644 dist/es2017/implementation/validation-rules.d.ts delete mode 100644 dist/es2017/implementation/validation-rules.js delete mode 100644 dist/es2017/property-accessor-parser.d.ts delete mode 100644 dist/es2017/property-accessor-parser.js delete mode 100644 dist/es2017/property-info.d.ts delete mode 100644 dist/es2017/property-info.js delete mode 100644 dist/es2017/util.d.ts delete mode 100644 dist/es2017/util.js delete mode 100644 dist/es2017/validate-binding-behavior-base.d.ts delete mode 100644 dist/es2017/validate-binding-behavior-base.js delete mode 100644 dist/es2017/validate-binding-behavior.d.ts delete mode 100644 dist/es2017/validate-binding-behavior.js delete mode 100644 dist/es2017/validate-event.d.ts delete mode 100644 dist/es2017/validate-event.js delete mode 100644 dist/es2017/validate-instruction.d.ts delete mode 100644 dist/es2017/validate-instruction.js delete mode 100644 dist/es2017/validate-result.d.ts delete mode 100644 dist/es2017/validate-result.js delete mode 100644 dist/es2017/validate-trigger.d.ts delete mode 100644 dist/es2017/validate-trigger.js delete mode 100644 dist/es2017/validation-controller-factory.d.ts delete mode 100644 dist/es2017/validation-controller-factory.js delete mode 100644 dist/es2017/validation-controller.d.ts delete mode 100644 dist/es2017/validation-controller.js delete mode 100644 dist/es2017/validation-errors-custom-attribute.d.ts delete mode 100644 dist/es2017/validation-errors-custom-attribute.js delete mode 100644 dist/es2017/validation-renderer-custom-attribute.d.ts delete mode 100644 dist/es2017/validation-renderer-custom-attribute.js delete mode 100644 dist/es2017/validation-renderer.d.ts delete mode 100644 dist/es2017/validation-renderer.js delete mode 100644 dist/es2017/validator.d.ts delete mode 100644 dist/es2017/validator.js delete mode 100644 dist/native-modules/aurelia-validation.d.ts delete mode 100644 dist/native-modules/controller-validate-result.d.ts delete mode 100644 dist/native-modules/controller-validate-result.js delete mode 100644 dist/native-modules/get-target-dom-element.d.ts delete mode 100644 dist/native-modules/get-target-dom-element.js delete mode 100644 dist/native-modules/implementation/expression-visitor.d.ts delete mode 100644 dist/native-modules/implementation/expression-visitor.js delete mode 100644 dist/native-modules/implementation/rule.d.ts delete mode 100644 dist/native-modules/implementation/rule.js delete mode 100644 dist/native-modules/implementation/rules.d.ts delete mode 100644 dist/native-modules/implementation/rules.js delete mode 100644 dist/native-modules/implementation/standard-validator.d.ts delete mode 100644 dist/native-modules/implementation/standard-validator.js delete mode 100644 dist/native-modules/implementation/validation-message-parser.d.ts delete mode 100644 dist/native-modules/implementation/validation-message-parser.js delete mode 100644 dist/native-modules/implementation/validation-messages.d.ts delete mode 100644 dist/native-modules/implementation/validation-messages.js delete mode 100644 dist/native-modules/implementation/validation-rules.d.ts delete mode 100644 dist/native-modules/implementation/validation-rules.js delete mode 100644 dist/native-modules/property-accessor-parser.d.ts delete mode 100644 dist/native-modules/property-accessor-parser.js delete mode 100644 dist/native-modules/property-info.d.ts delete mode 100644 dist/native-modules/property-info.js delete mode 100644 dist/native-modules/util.d.ts delete mode 100644 dist/native-modules/util.js delete mode 100644 dist/native-modules/validate-binding-behavior-base.d.ts delete mode 100644 dist/native-modules/validate-binding-behavior-base.js delete mode 100644 dist/native-modules/validate-binding-behavior.d.ts delete mode 100644 dist/native-modules/validate-binding-behavior.js delete mode 100644 dist/native-modules/validate-event.d.ts delete mode 100644 dist/native-modules/validate-event.js delete mode 100644 dist/native-modules/validate-instruction.d.ts delete mode 100644 dist/native-modules/validate-instruction.js delete mode 100644 dist/native-modules/validate-result.d.ts delete mode 100644 dist/native-modules/validate-result.js delete mode 100644 dist/native-modules/validate-trigger.d.ts delete mode 100644 dist/native-modules/validate-trigger.js delete mode 100644 dist/native-modules/validation-controller-factory.d.ts delete mode 100644 dist/native-modules/validation-controller-factory.js delete mode 100644 dist/native-modules/validation-controller.d.ts delete mode 100644 dist/native-modules/validation-controller.js delete mode 100644 dist/native-modules/validation-errors-custom-attribute.d.ts delete mode 100644 dist/native-modules/validation-errors-custom-attribute.js delete mode 100644 dist/native-modules/validation-renderer-custom-attribute.d.ts delete mode 100644 dist/native-modules/validation-renderer-custom-attribute.js delete mode 100644 dist/native-modules/validation-renderer.d.ts delete mode 100644 dist/native-modules/validation-renderer.js delete mode 100644 dist/native-modules/validator.d.ts delete mode 100644 dist/native-modules/validator.js delete mode 100644 dist/system/aurelia-validation.d.ts delete mode 100644 dist/system/controller-validate-result.d.ts delete mode 100644 dist/system/controller-validate-result.js delete mode 100644 dist/system/get-target-dom-element.d.ts delete mode 100644 dist/system/get-target-dom-element.js delete mode 100644 dist/system/implementation/expression-visitor.d.ts delete mode 100644 dist/system/implementation/expression-visitor.js delete mode 100644 dist/system/implementation/rule.d.ts delete mode 100644 dist/system/implementation/rule.js delete mode 100644 dist/system/implementation/rules.d.ts delete mode 100644 dist/system/implementation/rules.js delete mode 100644 dist/system/implementation/standard-validator.d.ts delete mode 100644 dist/system/implementation/standard-validator.js delete mode 100644 dist/system/implementation/validation-message-parser.d.ts delete mode 100644 dist/system/implementation/validation-message-parser.js delete mode 100644 dist/system/implementation/validation-messages.d.ts delete mode 100644 dist/system/implementation/validation-messages.js delete mode 100644 dist/system/implementation/validation-rules.d.ts delete mode 100644 dist/system/implementation/validation-rules.js delete mode 100644 dist/system/property-accessor-parser.d.ts delete mode 100644 dist/system/property-accessor-parser.js delete mode 100644 dist/system/property-info.d.ts delete mode 100644 dist/system/property-info.js delete mode 100644 dist/system/util.d.ts delete mode 100644 dist/system/util.js delete mode 100644 dist/system/validate-binding-behavior-base.d.ts delete mode 100644 dist/system/validate-binding-behavior-base.js delete mode 100644 dist/system/validate-binding-behavior.d.ts delete mode 100644 dist/system/validate-binding-behavior.js delete mode 100644 dist/system/validate-event.d.ts delete mode 100644 dist/system/validate-event.js delete mode 100644 dist/system/validate-instruction.d.ts delete mode 100644 dist/system/validate-instruction.js delete mode 100644 dist/system/validate-result.d.ts delete mode 100644 dist/system/validate-result.js delete mode 100644 dist/system/validate-trigger.d.ts delete mode 100644 dist/system/validate-trigger.js delete mode 100644 dist/system/validation-controller-factory.d.ts delete mode 100644 dist/system/validation-controller-factory.js delete mode 100644 dist/system/validation-controller.d.ts delete mode 100644 dist/system/validation-controller.js delete mode 100644 dist/system/validation-errors-custom-attribute.d.ts delete mode 100644 dist/system/validation-errors-custom-attribute.js delete mode 100644 dist/system/validation-renderer-custom-attribute.d.ts delete mode 100644 dist/system/validation-renderer-custom-attribute.js delete mode 100644 dist/system/validation-renderer.d.ts delete mode 100644 dist/system/validation-renderer.js delete mode 100644 dist/system/validator.d.ts delete mode 100644 dist/system/validator.js rename dist/{amd => types}/aurelia-validation.d.ts (93%) rename dist/{es2015 => types}/controller-validate-result.d.ts (96%) rename dist/{es2015 => types}/get-target-dom-element.d.ts (98%) rename dist/{commonjs => types}/implementation/expression-visitor.d.ts (96%) rename dist/{es2015 => types}/implementation/rule.d.ts (96%) rename dist/{es2015 => types}/implementation/rules.d.ts (96%) rename dist/{es2015 => types}/implementation/standard-validator.d.ts (85%) rename dist/{amd => types}/implementation/validation-message-parser.d.ts (94%) rename dist/{commonjs => types}/implementation/validation-messages.d.ts (97%) rename dist/{commonjs => types}/implementation/validation-rules.d.ts (97%) rename dist/{amd => types}/property-accessor-parser.d.ts (98%) rename dist/{es2015 => types}/property-info.d.ts (97%) rename dist/{amd => types}/util.d.ts (98%) rename dist/{amd => types}/validate-binding-behavior-base.d.ts (97%) rename dist/{es2015 => types}/validate-binding-behavior.d.ts (97%) rename dist/{es2015 => types}/validate-event.d.ts (52%) rename dist/{commonjs => types}/validate-instruction.d.ts (95%) rename dist/{amd => types}/validate-result.d.ts (97%) rename dist/{amd => types}/validate-trigger.d.ts (93%) rename dist/{es2015 => types}/validation-controller-factory.d.ts (97%) rename dist/{amd => types}/validation-controller.d.ts (93%) rename dist/{commonjs => types}/validation-errors-custom-attribute.d.ts (97%) rename dist/{commonjs => types}/validation-renderer-custom-attribute.d.ts (95%) rename dist/{es2015 => types}/validation-renderer.d.ts (96%) rename dist/{es2015 => types}/validator.d.ts (97%) diff --git a/dist/amd/aurelia-validation.js b/dist/amd/aurelia-validation.js index fd141afa..17409663 100644 --- a/dist/amd/aurelia-validation.js +++ b/dist/amd/aurelia-validation.js @@ -1,69 +1,1796 @@ -// Exports -define(["require", "exports", "./get-target-dom-element", "./property-info", "./property-accessor-parser", "./validate-binding-behavior", "./validate-event", "./validate-result", "./validate-trigger", "./validation-controller", "./validation-controller-factory", "./validation-errors-custom-attribute", "./validation-renderer-custom-attribute", "./validator", "./implementation/rules", "./implementation/standard-validator", "./implementation/validation-messages", "./implementation/validation-message-parser", "./implementation/validation-rules", "aurelia-pal", "./validator", "./implementation/standard-validator", "./implementation/validation-message-parser", "./property-accessor-parser", "./implementation/validation-rules"], function (require, exports, get_target_dom_element_1, property_info_1, property_accessor_parser_1, validate_binding_behavior_1, validate_event_1, validate_result_1, validate_trigger_1, validation_controller_1, validation_controller_factory_1, validation_errors_custom_attribute_1, validation_renderer_custom_attribute_1, validator_1, rules_1, standard_validator_1, validation_messages_1, validation_message_parser_1, validation_rules_1, aurelia_pal_1, validator_2, standard_validator_2, validation_message_parser_2, property_accessor_parser_2, validation_rules_2) { - "use strict"; - function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; - } - Object.defineProperty(exports, "__esModule", { value: true }); - __export(get_target_dom_element_1); - __export(property_info_1); - __export(property_accessor_parser_1); - __export(validate_binding_behavior_1); - __export(validate_event_1); - __export(validate_result_1); - __export(validate_trigger_1); - __export(validation_controller_1); - __export(validation_controller_factory_1); - __export(validation_errors_custom_attribute_1); - __export(validation_renderer_custom_attribute_1); - __export(validator_1); - __export(rules_1); - __export(standard_validator_1); - __export(validation_messages_1); - __export(validation_message_parser_1); - __export(validation_rules_1); - /** - * Aurelia Validation Configuration API - */ - var AureliaValidationConfiguration = /** @class */ (function () { - function AureliaValidationConfiguration() { - this.validatorType = standard_validator_2.StandardValidator; - } - /** - * Use a custom Validator implementation. - */ - AureliaValidationConfiguration.prototype.customValidator = function (type) { - this.validatorType = type; - }; - /** - * Applies the configuration. - */ - AureliaValidationConfiguration.prototype.apply = function (container) { - var validator = container.get(this.validatorType); - container.registerInstance(validator_2.Validator, validator); - }; - return AureliaValidationConfiguration; - }()); - exports.AureliaValidationConfiguration = AureliaValidationConfiguration; - /** - * Configures the plugin. - */ - function configure(frameworkConfig, callback) { - // the fluent rule definition API needs the parser to translate messages - // to interpolation expressions. - var messageParser = frameworkConfig.container.get(validation_message_parser_2.ValidationMessageParser); - var propertyParser = frameworkConfig.container.get(property_accessor_parser_2.PropertyAccessorParser); - validation_rules_2.ValidationRules.initialize(messageParser, propertyParser); - // configure... - var config = new AureliaValidationConfiguration(); - if (callback instanceof Function) { - callback(config); - } - config.apply(frameworkConfig.container); - // globalize the behaviors. - if (frameworkConfig.globalResources) { - frameworkConfig.globalResources(aurelia_pal_1.PLATFORM.moduleName('./validate-binding-behavior'), aurelia_pal_1.PLATFORM.moduleName('./validation-errors-custom-attribute'), aurelia_pal_1.PLATFORM.moduleName('./validation-renderer-custom-attribute')); - } - } - exports.configure = configure; +define('aurelia-validation', ['exports', 'aurelia-pal', 'aurelia-binding', 'aurelia-dependency-injection', 'aurelia-task-queue', 'aurelia-templating', 'aurelia-framework', 'aurelia-logging'], function (exports, aureliaPal, aureliaBinding, aureliaDependencyInjection, aureliaTaskQueue, aureliaTemplating, aureliaFramework, LogManager) { 'use strict'; + + /** + * Gets the DOM element associated with the data-binding. Most of the time it's + * the binding.target but sometimes binding.target is an aurelia custom element, + * or custom attribute which is a javascript "class" instance, so we need to use + * the controller's container to retrieve the actual DOM element. + */ + function getTargetDOMElement(binding, view) { + var target = binding.target; + // DOM element + if (target instanceof Element) { + return target; + } + // custom element or custom attribute + // tslint:disable-next-line:prefer-const + for (var i = 0, ii = view.controllers.length; i < ii; i++) { + var controller = view.controllers[i]; + if (controller.viewModel === target) { + var element = controller.container.get(aureliaPal.DOM.Element); + if (element) { + return element; + } + throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\"."); + } + } + throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\"."); + } + + function getObject(expression, objectExpression, source) { + var value = objectExpression.evaluate(source, null); + if (value === null || value === undefined || value instanceof Object) { + return value; + } + // tslint:disable-next-line:max-line-length + throw new Error("The '" + objectExpression + "' part of '" + expression + "' evaluates to " + value + " instead of an object, null or undefined."); + } + /** + * Retrieves the object and property name for the specified expression. + * @param expression The expression + * @param source The scope + */ + function getPropertyInfo(expression, source) { + var originalExpression = expression; + while (expression instanceof aureliaBinding.BindingBehavior || expression instanceof aureliaBinding.ValueConverter) { + expression = expression.expression; + } + var object; + var propertyName; + if (expression instanceof aureliaBinding.AccessScope) { + object = aureliaBinding.getContextFor(expression.name, source, expression.ancestor); + propertyName = expression.name; + } + else if (expression instanceof aureliaBinding.AccessMember) { + object = getObject(originalExpression, expression.object, source); + propertyName = expression.name; + } + else if (expression instanceof aureliaBinding.AccessKeyed) { + object = getObject(originalExpression, expression.object, source); + propertyName = expression.key.evaluate(source); + } + else { + throw new Error("Expression '" + originalExpression + "' is not compatible with the validate binding-behavior."); + } + if (object === null || object === undefined) { + return null; + } + return { object: object, propertyName: propertyName }; + } + + function isString(value) { + return Object.prototype.toString.call(value) === '[object String]'; + } + function isNumber(value) { + return Object.prototype.toString.call(value) === '[object Number]'; + } + + var PropertyAccessorParser = /** @class */ (function () { + function PropertyAccessorParser(parser) { + this.parser = parser; + } + PropertyAccessorParser.prototype.parse = function (property) { + if (isString(property) || isNumber(property)) { + return property; + } + var accessorText = getAccessorExpression(property.toString()); + var accessor = this.parser.parse(accessorText); + if (accessor instanceof aureliaBinding.AccessScope + || accessor instanceof aureliaBinding.AccessMember && accessor.object instanceof aureliaBinding.AccessScope) { + return accessor.name; + } + throw new Error("Invalid property expression: \"" + accessor + "\""); + }; + PropertyAccessorParser.inject = [aureliaBinding.Parser]; + return PropertyAccessorParser; + }()); + function getAccessorExpression(fn) { + /* tslint:disable:max-line-length */ + var classic = /^function\s*\([$_\w\d]+\)\s*\{(?:\s*"use strict";)?\s*(?:[$_\w\d.['"\]+;]+)?\s*return\s+[$_\w\d]+\.([$_\w\d]+)\s*;?\s*\}$/; + /* tslint:enable:max-line-length */ + var arrow = /^\(?[$_\w\d]+\)?\s*=>\s*[$_\w\d]+\.([$_\w\d]+)$/; + var match = classic.exec(fn) || arrow.exec(fn); + if (match === null) { + throw new Error("Unable to parse accessor function:\n" + fn); + } + return match[1]; + } + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. All rights reserved. + Licensed under the Apache License, Version 2.0 (the "License"); you may not use + this file except in compliance with the License. You may obtain a copy of the + License at http://www.apache.org/licenses/LICENSE-2.0 + + THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED + WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, + MERCHANTABLITY OR NON-INFRINGEMENT. + + See the Apache Version 2.0 License for specific language governing permissions + and limitations under the License. + ***************************************************************************** */ + /* global Reflect, Promise */ + + var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + + function __extends(d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + + function __decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + } + + /** + * Validation triggers. + */ + (function (validateTrigger) { + /** + * Manual validation. Use the controller's `validate()` and `reset()` methods + * to validate all bindings. + */ + validateTrigger[validateTrigger["manual"] = 0] = "manual"; + /** + * Validate the binding when the binding's target element fires a DOM "blur" event. + */ + validateTrigger[validateTrigger["blur"] = 1] = "blur"; + /** + * Validate the binding when it updates the model due to a change in the view. + */ + validateTrigger[validateTrigger["change"] = 2] = "change"; + /** + * Validate the binding when the binding's target element fires a DOM "blur" event and + * when it updates the model due to a change in the view. + */ + validateTrigger[validateTrigger["changeOrBlur"] = 3] = "changeOrBlur"; + })(exports.validateTrigger || (exports.validateTrigger = {})); + + /** + * Validates objects and properties. + */ + var Validator = /** @class */ (function () { + function Validator() { + } + return Validator; + }()); + + /** + * The result of validating an individual validation rule. + */ + var ValidateResult = /** @class */ (function () { + /** + * @param rule The rule associated with the result. Validator implementation specific. + * @param object The object that was validated. + * @param propertyName The name of the property that was validated. + * @param error The error, if the result is a validation error. + */ + function ValidateResult(rule, object, propertyName, valid, message) { + if (message === void 0) { message = null; } + this.rule = rule; + this.object = object; + this.propertyName = propertyName; + this.valid = valid; + this.message = message; + this.id = ValidateResult.nextId++; + } + ValidateResult.prototype.toString = function () { + return this.valid ? 'Valid.' : this.message; + }; + ValidateResult.nextId = 0; + return ValidateResult; + }()); + + var ValidateEvent = /** @class */ (function () { + function ValidateEvent( + /** + * The type of validate event. Either "validate" or "reset". + */ + type, + /** + * The controller's current array of errors. For an array containing both + * failed rules and passed rules, use the "results" property. + */ + errors, + /** + * The controller's current array of validate results. This + * includes both passed rules and failed rules. For an array of only failed rules, + * use the "errors" property. + */ + results, + /** + * The instruction passed to the "validate" or "reset" event. Will be null when + * the controller's validate/reset method was called with no instruction argument. + */ + instruction, + /** + * In events with type === "validate", this property will contain the result + * of validating the instruction (see "instruction" property). Use the controllerValidateResult + * to access the validate results specific to the call to "validate" + * (as opposed to using the "results" and "errors" properties to access the controller's entire + * set of results/errors). + */ + controllerValidateResult) { + this.type = type; + this.errors = errors; + this.results = results; + this.instruction = instruction; + this.controllerValidateResult = controllerValidateResult; + } + return ValidateEvent; + }()); + + /** + * Orchestrates validation. + * Manages a set of bindings, renderers and objects. + * Exposes the current list of validation results for binding purposes. + */ + var ValidationController = /** @class */ (function () { + function ValidationController(validator, propertyParser) { + this.validator = validator; + this.propertyParser = propertyParser; + // Registered bindings (via the validate binding behavior) + this.bindings = new Map(); + // Renderers that have been added to the controller instance. + this.renderers = []; + /** + * Validation results that have been rendered by the controller. + */ + this.results = []; + /** + * Validation errors that have been rendered by the controller. + */ + this.errors = []; + /** + * Whether the controller is currently validating. + */ + this.validating = false; + // Elements related to validation results that have been rendered. + this.elements = new Map(); + // Objects that have been added to the controller instance (entity-style validation). + this.objects = new Map(); + /** + * The trigger that will invoke automatic validation of a property used in a binding. + */ + this.validateTrigger = exports.validateTrigger.blur; + // Promise that resolves when validation has completed. + this.finishValidating = Promise.resolve(); + this.eventCallbacks = []; + } + /** + * Subscribe to controller validate and reset events. These events occur when the + * controller's "validate"" and "reset" methods are called. + * @param callback The callback to be invoked when the controller validates or resets. + */ + ValidationController.prototype.subscribe = function (callback) { + var _this = this; + this.eventCallbacks.push(callback); + return { + dispose: function () { + var index = _this.eventCallbacks.indexOf(callback); + if (index === -1) { + return; + } + _this.eventCallbacks.splice(index, 1); + } + }; + }; + /** + * Adds an object to the set of objects that should be validated when validate is called. + * @param object The object. + * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. + */ + ValidationController.prototype.addObject = function (object, rules) { + this.objects.set(object, rules); + }; + /** + * Removes an object from the set of objects that should be validated when validate is called. + * @param object The object. + */ + ValidationController.prototype.removeObject = function (object) { + this.objects.delete(object); + this.processResultDelta('reset', this.results.filter(function (result) { return result.object === object; }), []); + }; + /** + * Adds and renders an error. + */ + ValidationController.prototype.addError = function (message, object, propertyName) { + if (propertyName === void 0) { propertyName = null; } + var resolvedPropertyName; + if (propertyName === null) { + resolvedPropertyName = propertyName; + } + else { + resolvedPropertyName = this.propertyParser.parse(propertyName); + } + var result = new ValidateResult({ __manuallyAdded__: true }, object, resolvedPropertyName, false, message); + this.processResultDelta('validate', [], [result]); + return result; + }; + /** + * Removes and unrenders an error. + */ + ValidationController.prototype.removeError = function (result) { + if (this.results.indexOf(result) !== -1) { + this.processResultDelta('reset', [result], []); + } + }; + /** + * Adds a renderer. + * @param renderer The renderer. + */ + ValidationController.prototype.addRenderer = function (renderer) { + var _this = this; + this.renderers.push(renderer); + renderer.render({ + kind: 'validate', + render: this.results.map(function (result) { return ({ result: result, elements: _this.elements.get(result) }); }), + unrender: [] + }); + }; + /** + * Removes a renderer. + * @param renderer The renderer. + */ + ValidationController.prototype.removeRenderer = function (renderer) { + var _this = this; + this.renderers.splice(this.renderers.indexOf(renderer), 1); + renderer.render({ + kind: 'reset', + render: [], + unrender: this.results.map(function (result) { return ({ result: result, elements: _this.elements.get(result) }); }) + }); + }; + /** + * Registers a binding with the controller. + * @param binding The binding instance. + * @param target The DOM element. + * @param rules (optional) rules associated with the binding. Validator implementation specific. + */ + ValidationController.prototype.registerBinding = function (binding, target, rules) { + this.bindings.set(binding, { target: target, rules: rules, propertyInfo: null }); + }; + /** + * Unregisters a binding with the controller. + * @param binding The binding instance. + */ + ValidationController.prototype.unregisterBinding = function (binding) { + this.resetBinding(binding); + this.bindings.delete(binding); + }; + /** + * Interprets the instruction and returns a predicate that will identify + * relevant results in the list of rendered validation results. + */ + ValidationController.prototype.getInstructionPredicate = function (instruction) { + var _this = this; + if (instruction) { + var object_1 = instruction.object, propertyName_1 = instruction.propertyName, rules_1 = instruction.rules; + var predicate_1; + if (instruction.propertyName) { + predicate_1 = function (x) { return x.object === object_1 && x.propertyName === propertyName_1; }; + } + else { + predicate_1 = function (x) { return x.object === object_1; }; + } + if (rules_1) { + return function (x) { return predicate_1(x) && _this.validator.ruleExists(rules_1, x.rule); }; + } + return predicate_1; + } + else { + return function () { return true; }; + } + }; + /** + * Validates and renders results. + * @param instruction Optional. Instructions on what to validate. If undefined, all + * objects and bindings will be validated. + */ + ValidationController.prototype.validate = function (instruction) { + var _this = this; + // Get a function that will process the validation instruction. + var execute; + if (instruction) { + // tslint:disable-next-line:prefer-const + var object_2 = instruction.object, propertyName_2 = instruction.propertyName, rules_2 = instruction.rules; + // if rules were not specified, check the object map. + rules_2 = rules_2 || this.objects.get(object_2); + // property specified? + if (instruction.propertyName === undefined) { + // validate the specified object. + execute = function () { return _this.validator.validateObject(object_2, rules_2); }; + } + else { + // validate the specified property. + execute = function () { return _this.validator.validateProperty(object_2, propertyName_2, rules_2); }; + } + } + else { + // validate all objects and bindings. + execute = function () { + var promises = []; + for (var _i = 0, _a = Array.from(_this.objects); _i < _a.length; _i++) { + var _b = _a[_i], object = _b[0], rules = _b[1]; + promises.push(_this.validator.validateObject(object, rules)); + } + for (var _c = 0, _d = Array.from(_this.bindings); _c < _d.length; _c++) { + var _e = _d[_c], binding = _e[0], rules = _e[1].rules; + var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + if (!propertyInfo || _this.objects.has(propertyInfo.object)) { + continue; + } + promises.push(_this.validator.validateProperty(propertyInfo.object, propertyInfo.propertyName, rules)); + } + return Promise.all(promises).then(function (resultSets) { return resultSets.reduce(function (a, b) { return a.concat(b); }, []); }); + }; + } + // Wait for any existing validation to finish, execute the instruction, render the results. + this.validating = true; + var returnPromise = this.finishValidating + .then(execute) + .then(function (newResults) { + var predicate = _this.getInstructionPredicate(instruction); + var oldResults = _this.results.filter(predicate); + _this.processResultDelta('validate', oldResults, newResults); + if (returnPromise === _this.finishValidating) { + _this.validating = false; + } + var result = { + instruction: instruction, + valid: newResults.find(function (x) { return !x.valid; }) === undefined, + results: newResults + }; + _this.invokeCallbacks(instruction, result); + return result; + }) + .catch(function (exception) { + // recover, to enable subsequent calls to validate() + _this.validating = false; + _this.finishValidating = Promise.resolve(); + return Promise.reject(exception); + }); + this.finishValidating = returnPromise; + return returnPromise; + }; + /** + * Resets any rendered validation results (unrenders). + * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results + * will be unrendered. + */ + ValidationController.prototype.reset = function (instruction) { + var predicate = this.getInstructionPredicate(instruction); + var oldResults = this.results.filter(predicate); + this.processResultDelta('reset', oldResults, []); + this.invokeCallbacks(instruction, null); + }; + /** + * Gets the elements associated with an object and propertyName (if any). + */ + ValidationController.prototype.getAssociatedElements = function (_a) { + var object = _a.object, propertyName = _a.propertyName; + var elements = []; + for (var _i = 0, _b = Array.from(this.bindings); _i < _b.length; _i++) { + var _c = _b[_i], binding = _c[0], target = _c[1].target; + var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + if (propertyInfo && propertyInfo.object === object && propertyInfo.propertyName === propertyName) { + elements.push(target); + } + } + return elements; + }; + ValidationController.prototype.processResultDelta = function (kind, oldResults, newResults) { + // prepare the instruction. + var instruction = { + kind: kind, + render: [], + unrender: [] + }; + // create a shallow copy of newResults so we can mutate it without causing side-effects. + newResults = newResults.slice(0); + var _loop_1 = function (oldResult) { + // get the elements associated with the old result. + var elements = this_1.elements.get(oldResult); + // remove the old result from the element map. + this_1.elements.delete(oldResult); + // create the unrender instruction. + instruction.unrender.push({ result: oldResult, elements: elements }); + // determine if there's a corresponding new result for the old result we are unrendering. + var newResultIndex = newResults.findIndex(function (x) { return x.rule === oldResult.rule && x.object === oldResult.object && x.propertyName === oldResult.propertyName; }); + if (newResultIndex === -1) { + // no corresponding new result... simple remove. + this_1.results.splice(this_1.results.indexOf(oldResult), 1); + if (!oldResult.valid) { + this_1.errors.splice(this_1.errors.indexOf(oldResult), 1); + } + } + else { + // there is a corresponding new result... + var newResult = newResults.splice(newResultIndex, 1)[0]; + // get the elements that are associated with the new result. + var elements_1 = this_1.getAssociatedElements(newResult); + this_1.elements.set(newResult, elements_1); + // create a render instruction for the new result. + instruction.render.push({ result: newResult, elements: elements_1 }); + // do an in-place replacement of the old result with the new result. + // this ensures any repeats bound to this.results will not thrash. + this_1.results.splice(this_1.results.indexOf(oldResult), 1, newResult); + if (!oldResult.valid && newResult.valid) { + this_1.errors.splice(this_1.errors.indexOf(oldResult), 1); + } + else if (!oldResult.valid && !newResult.valid) { + this_1.errors.splice(this_1.errors.indexOf(oldResult), 1, newResult); + } + else if (!newResult.valid) { + this_1.errors.push(newResult); + } + } + }; + var this_1 = this; + // create unrender instructions from the old results. + for (var _i = 0, oldResults_1 = oldResults; _i < oldResults_1.length; _i++) { + var oldResult = oldResults_1[_i]; + _loop_1(oldResult); + } + // create render instructions from the remaining new results. + for (var _a = 0, newResults_1 = newResults; _a < newResults_1.length; _a++) { + var result = newResults_1[_a]; + var elements = this.getAssociatedElements(result); + instruction.render.push({ result: result, elements: elements }); + this.elements.set(result, elements); + this.results.push(result); + if (!result.valid) { + this.errors.push(result); + } + } + // render. + for (var _b = 0, _c = this.renderers; _b < _c.length; _b++) { + var renderer = _c[_b]; + renderer.render(instruction); + } + }; + /** + * Validates the property associated with a binding. + */ + ValidationController.prototype.validateBinding = function (binding) { + if (!binding.isBound) { + return; + } + var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + var rules; + var registeredBinding = this.bindings.get(binding); + if (registeredBinding) { + rules = registeredBinding.rules; + registeredBinding.propertyInfo = propertyInfo; + } + if (!propertyInfo) { + return; + } + var object = propertyInfo.object, propertyName = propertyInfo.propertyName; + this.validate({ object: object, propertyName: propertyName, rules: rules }); + }; + /** + * Resets the results for a property associated with a binding. + */ + ValidationController.prototype.resetBinding = function (binding) { + var registeredBinding = this.bindings.get(binding); + var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + if (!propertyInfo && registeredBinding) { + propertyInfo = registeredBinding.propertyInfo; + } + if (registeredBinding) { + registeredBinding.propertyInfo = null; + } + if (!propertyInfo) { + return; + } + var object = propertyInfo.object, propertyName = propertyInfo.propertyName; + this.reset({ object: object, propertyName: propertyName }); + }; + /** + * Changes the controller's validateTrigger. + * @param newTrigger The new validateTrigger + */ + ValidationController.prototype.changeTrigger = function (newTrigger) { + this.validateTrigger = newTrigger; + var bindings = Array.from(this.bindings.keys()); + for (var _i = 0, bindings_1 = bindings; _i < bindings_1.length; _i++) { + var binding = bindings_1[_i]; + var source = binding.source; + binding.unbind(); + binding.bind(source); + } + }; + /** + * Revalidates the controller's current set of errors. + */ + ValidationController.prototype.revalidateErrors = function () { + for (var _i = 0, _a = this.errors; _i < _a.length; _i++) { + var _b = _a[_i], object = _b.object, propertyName = _b.propertyName, rule = _b.rule; + if (rule.__manuallyAdded__) { + continue; + } + var rules = [[rule]]; + this.validate({ object: object, propertyName: propertyName, rules: rules }); + } + }; + ValidationController.prototype.invokeCallbacks = function (instruction, result) { + if (this.eventCallbacks.length === 0) { + return; + } + var event = new ValidateEvent(result ? 'validate' : 'reset', this.errors, this.results, instruction || null, result); + for (var i = 0; i < this.eventCallbacks.length; i++) { + this.eventCallbacks[i](event); + } + }; + ValidationController.inject = [Validator, PropertyAccessorParser]; + return ValidationController; + }()); + + /** + * Binding behavior. Indicates the bound property should be validated. + */ + var ValidateBindingBehaviorBase = /** @class */ (function () { + function ValidateBindingBehaviorBase(taskQueue) { + this.taskQueue = taskQueue; + } + ValidateBindingBehaviorBase.prototype.bind = function (binding, source, rulesOrController, rules) { + var _this = this; + // identify the target element. + var target = getTargetDOMElement(binding, source); + // locate the controller. + var controller; + if (rulesOrController instanceof ValidationController) { + controller = rulesOrController; + } + else { + controller = source.container.get(aureliaDependencyInjection.Optional.of(ValidationController)); + rules = rulesOrController; + } + if (controller === null) { + throw new Error("A ValidationController has not been registered."); + } + controller.registerBinding(binding, target, rules); + binding.validationController = controller; + var trigger = this.getValidateTrigger(controller); + // tslint:disable-next-line:no-bitwise + if (trigger & exports.validateTrigger.change) { + binding.vbbUpdateSource = binding.updateSource; + // tslint:disable-next-line:only-arrow-functions + // tslint:disable-next-line:space-before-function-paren + binding.updateSource = function (value) { + this.vbbUpdateSource(value); + this.validationController.validateBinding(this); + }; + } + // tslint:disable-next-line:no-bitwise + if (trigger & exports.validateTrigger.blur) { + binding.validateBlurHandler = function () { + _this.taskQueue.queueMicroTask(function () { return controller.validateBinding(binding); }); + }; + binding.validateTarget = target; + target.addEventListener('blur', binding.validateBlurHandler); + } + if (trigger !== exports.validateTrigger.manual) { + binding.standardUpdateTarget = binding.updateTarget; + // tslint:disable-next-line:only-arrow-functions + // tslint:disable-next-line:space-before-function-paren + binding.updateTarget = function (value) { + this.standardUpdateTarget(value); + this.validationController.resetBinding(this); + }; + } + }; + ValidateBindingBehaviorBase.prototype.unbind = function (binding) { + // reset the binding to it's original state. + if (binding.vbbUpdateSource) { + binding.updateSource = binding.vbbUpdateSource; + binding.vbbUpdateSource = null; + } + if (binding.standardUpdateTarget) { + binding.updateTarget = binding.standardUpdateTarget; + binding.standardUpdateTarget = null; + } + if (binding.validateBlurHandler) { + binding.validateTarget.removeEventListener('blur', binding.validateBlurHandler); + binding.validateBlurHandler = null; + binding.validateTarget = null; + } + binding.validationController.unregisterBinding(binding); + binding.validationController = null; + }; + return ValidateBindingBehaviorBase; + }()); + + /** + * Binding behavior. Indicates the bound property should be validated + * when the validate trigger specified by the associated controller's + * validateTrigger property occurs. + */ + var ValidateBindingBehavior = /** @class */ (function (_super) { + __extends(ValidateBindingBehavior, _super); + function ValidateBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateBindingBehavior.prototype.getValidateTrigger = function (controller) { + return controller.validateTrigger; + }; + ValidateBindingBehavior.inject = [aureliaTaskQueue.TaskQueue]; + return ValidateBindingBehavior; + }(ValidateBindingBehaviorBase)); + /** + * Binding behavior. Indicates the bound property will be validated + * manually, by calling controller.validate(). No automatic validation + * triggered by data-entry or blur will occur. + */ + var ValidateManuallyBindingBehavior = /** @class */ (function (_super) { + __extends(ValidateManuallyBindingBehavior, _super); + function ValidateManuallyBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateManuallyBindingBehavior.prototype.getValidateTrigger = function () { + return exports.validateTrigger.manual; + }; + ValidateManuallyBindingBehavior.inject = [aureliaTaskQueue.TaskQueue]; + return ValidateManuallyBindingBehavior; + }(ValidateBindingBehaviorBase)); + /** + * Binding behavior. Indicates the bound property should be validated + * when the associated element blurs. + */ + var ValidateOnBlurBindingBehavior = /** @class */ (function (_super) { + __extends(ValidateOnBlurBindingBehavior, _super); + function ValidateOnBlurBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateOnBlurBindingBehavior.prototype.getValidateTrigger = function () { + return exports.validateTrigger.blur; + }; + ValidateOnBlurBindingBehavior.inject = [aureliaTaskQueue.TaskQueue]; + return ValidateOnBlurBindingBehavior; + }(ValidateBindingBehaviorBase)); + /** + * Binding behavior. Indicates the bound property should be validated + * when the associated element is changed by the user, causing a change + * to the model. + */ + var ValidateOnChangeBindingBehavior = /** @class */ (function (_super) { + __extends(ValidateOnChangeBindingBehavior, _super); + function ValidateOnChangeBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateOnChangeBindingBehavior.prototype.getValidateTrigger = function () { + return exports.validateTrigger.change; + }; + ValidateOnChangeBindingBehavior.inject = [aureliaTaskQueue.TaskQueue]; + return ValidateOnChangeBindingBehavior; + }(ValidateBindingBehaviorBase)); + /** + * Binding behavior. Indicates the bound property should be validated + * when the associated element blurs or is changed by the user, causing + * a change to the model. + */ + var ValidateOnChangeOrBlurBindingBehavior = /** @class */ (function (_super) { + __extends(ValidateOnChangeOrBlurBindingBehavior, _super); + function ValidateOnChangeOrBlurBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateOnChangeOrBlurBindingBehavior.prototype.getValidateTrigger = function () { + return exports.validateTrigger.changeOrBlur; + }; + ValidateOnChangeOrBlurBindingBehavior.inject = [aureliaTaskQueue.TaskQueue]; + return ValidateOnChangeOrBlurBindingBehavior; + }(ValidateBindingBehaviorBase)); + + /** + * Creates ValidationController instances. + */ + var ValidationControllerFactory = /** @class */ (function () { + function ValidationControllerFactory(container) { + this.container = container; + } + ValidationControllerFactory.get = function (container) { + return new ValidationControllerFactory(container); + }; + /** + * Creates a new controller instance. + */ + ValidationControllerFactory.prototype.create = function (validator) { + if (!validator) { + validator = this.container.get(Validator); + } + var propertyParser = this.container.get(PropertyAccessorParser); + return new ValidationController(validator, propertyParser); + }; + /** + * Creates a new controller and registers it in the current element's container so that it's + * available to the validate binding behavior and renderers. + */ + ValidationControllerFactory.prototype.createForCurrentScope = function (validator) { + var controller = this.create(validator); + this.container.registerInstance(ValidationController, controller); + return controller; + }; + return ValidationControllerFactory; + }()); + ValidationControllerFactory['protocol:aurelia:resolver'] = true; + + var ValidationErrorsCustomAttribute = /** @class */ (function () { + function ValidationErrorsCustomAttribute(boundaryElement, controllerAccessor) { + this.boundaryElement = boundaryElement; + this.controllerAccessor = controllerAccessor; + this.controller = null; + this.errors = []; + this.errorsInternal = []; + } + ValidationErrorsCustomAttribute.inject = function () { + return [aureliaPal.DOM.Element, aureliaDependencyInjection.Lazy.of(ValidationController)]; + }; + ValidationErrorsCustomAttribute.prototype.sort = function () { + this.errorsInternal.sort(function (a, b) { + if (a.targets[0] === b.targets[0]) { + return 0; + } + // tslint:disable-next-line:no-bitwise + return a.targets[0].compareDocumentPosition(b.targets[0]) & 2 ? 1 : -1; + }); + }; + ValidationErrorsCustomAttribute.prototype.interestingElements = function (elements) { + var _this = this; + return elements.filter(function (e) { return _this.boundaryElement.contains(e); }); + }; + ValidationErrorsCustomAttribute.prototype.render = function (instruction) { + var _loop_1 = function (result) { + var index = this_1.errorsInternal.findIndex(function (x) { return x.error === result; }); + if (index !== -1) { + this_1.errorsInternal.splice(index, 1); + } + }; + var this_1 = this; + for (var _i = 0, _a = instruction.unrender; _i < _a.length; _i++) { + var result = _a[_i].result; + _loop_1(result); + } + for (var _b = 0, _c = instruction.render; _b < _c.length; _b++) { + var _d = _c[_b], result = _d.result, elements = _d.elements; + if (result.valid) { + continue; + } + var targets = this.interestingElements(elements); + if (targets.length) { + this.errorsInternal.push({ error: result, targets: targets }); + } + } + this.sort(); + this.errors = this.errorsInternal; + }; + ValidationErrorsCustomAttribute.prototype.bind = function () { + if (!this.controller) { + this.controller = this.controllerAccessor(); + } + // this will call render() with the side-effect of updating this.errors + this.controller.addRenderer(this); + }; + ValidationErrorsCustomAttribute.prototype.unbind = function () { + if (this.controller) { + this.controller.removeRenderer(this); + } + }; + __decorate([ + aureliaTemplating.bindable({ defaultBindingMode: aureliaBinding.bindingMode.oneWay }) + ], ValidationErrorsCustomAttribute.prototype, "controller", void 0); + __decorate([ + aureliaTemplating.bindable({ primaryProperty: true, defaultBindingMode: aureliaBinding.bindingMode.twoWay }) + ], ValidationErrorsCustomAttribute.prototype, "errors", void 0); + ValidationErrorsCustomAttribute = __decorate([ + aureliaTemplating.customAttribute('validation-errors') + ], ValidationErrorsCustomAttribute); + return ValidationErrorsCustomAttribute; + }()); + + var ValidationRendererCustomAttribute = /** @class */ (function () { + function ValidationRendererCustomAttribute() { + } + ValidationRendererCustomAttribute.prototype.created = function (view) { + this.container = view.container; + }; + ValidationRendererCustomAttribute.prototype.bind = function () { + this.controller = this.container.get(ValidationController); + this.renderer = this.container.get(this.value); + this.controller.addRenderer(this.renderer); + }; + ValidationRendererCustomAttribute.prototype.unbind = function () { + this.controller.removeRenderer(this.renderer); + this.controller = null; + this.renderer = null; + }; + ValidationRendererCustomAttribute = __decorate([ + aureliaFramework.customAttribute('validation-renderer') + ], ValidationRendererCustomAttribute); + return ValidationRendererCustomAttribute; + }()); + + /** + * Sets, unsets and retrieves rules on an object or constructor function. + */ + var Rules = /** @class */ (function () { + function Rules() { + } + /** + * Applies the rules to a target. + */ + Rules.set = function (target, rules) { + if (target instanceof Function) { + target = target.prototype; + } + Object.defineProperty(target, Rules.key, { enumerable: false, configurable: false, writable: true, value: rules }); + }; + /** + * Removes rules from a target. + */ + Rules.unset = function (target) { + if (target instanceof Function) { + target = target.prototype; + } + target[Rules.key] = null; + }; + /** + * Retrieves the target's rules. + */ + Rules.get = function (target) { + return target[Rules.key] || null; + }; + /** + * The name of the property that stores the rules. + */ + Rules.key = '__rules__'; + return Rules; + }()); + + // tslint:disable:no-empty + var ExpressionVisitor = /** @class */ (function () { + function ExpressionVisitor() { + } + ExpressionVisitor.prototype.visitChain = function (chain) { + this.visitArgs(chain.expressions); + }; + ExpressionVisitor.prototype.visitBindingBehavior = function (behavior) { + behavior.expression.accept(this); + this.visitArgs(behavior.args); + }; + ExpressionVisitor.prototype.visitValueConverter = function (converter) { + converter.expression.accept(this); + this.visitArgs(converter.args); + }; + ExpressionVisitor.prototype.visitAssign = function (assign) { + assign.target.accept(this); + assign.value.accept(this); + }; + ExpressionVisitor.prototype.visitConditional = function (conditional) { + conditional.condition.accept(this); + conditional.yes.accept(this); + conditional.no.accept(this); + }; + ExpressionVisitor.prototype.visitAccessThis = function (access) { + access.ancestor = access.ancestor; + }; + ExpressionVisitor.prototype.visitAccessScope = function (access) { + access.name = access.name; + }; + ExpressionVisitor.prototype.visitAccessMember = function (access) { + access.object.accept(this); + }; + ExpressionVisitor.prototype.visitAccessKeyed = function (access) { + access.object.accept(this); + access.key.accept(this); + }; + ExpressionVisitor.prototype.visitCallScope = function (call) { + this.visitArgs(call.args); + }; + ExpressionVisitor.prototype.visitCallFunction = function (call) { + call.func.accept(this); + this.visitArgs(call.args); + }; + ExpressionVisitor.prototype.visitCallMember = function (call) { + call.object.accept(this); + this.visitArgs(call.args); + }; + ExpressionVisitor.prototype.visitPrefix = function (prefix) { + prefix.expression.accept(this); + }; + ExpressionVisitor.prototype.visitBinary = function (binary) { + binary.left.accept(this); + binary.right.accept(this); + }; + ExpressionVisitor.prototype.visitLiteralPrimitive = function (literal) { + literal.value = literal.value; + }; + ExpressionVisitor.prototype.visitLiteralArray = function (literal) { + this.visitArgs(literal.elements); + }; + ExpressionVisitor.prototype.visitLiteralObject = function (literal) { + this.visitArgs(literal.values); + }; + ExpressionVisitor.prototype.visitLiteralString = function (literal) { + literal.value = literal.value; + }; + ExpressionVisitor.prototype.visitArgs = function (args) { + for (var i = 0; i < args.length; i++) { + args[i].accept(this); + } + }; + return ExpressionVisitor; + }()); + + var ValidationMessageParser = /** @class */ (function () { + function ValidationMessageParser(bindinqLanguage) { + this.bindinqLanguage = bindinqLanguage; + this.emptyStringExpression = new aureliaBinding.LiteralString(''); + this.nullExpression = new aureliaBinding.LiteralPrimitive(null); + this.undefinedExpression = new aureliaBinding.LiteralPrimitive(undefined); + this.cache = {}; + } + ValidationMessageParser.prototype.parse = function (message) { + if (this.cache[message] !== undefined) { + return this.cache[message]; + } + var parts = this.bindinqLanguage.parseInterpolation(null, message); + if (parts === null) { + return new aureliaBinding.LiteralString(message); + } + var expression = new aureliaBinding.LiteralString(parts[0]); + for (var i = 1; i < parts.length; i += 2) { + expression = new aureliaBinding.Binary('+', expression, new aureliaBinding.Binary('+', this.coalesce(parts[i]), new aureliaBinding.LiteralString(parts[i + 1]))); + } + MessageExpressionValidator.validate(expression, message); + this.cache[message] = expression; + return expression; + }; + ValidationMessageParser.prototype.coalesce = function (part) { + // part === null || part === undefined ? '' : part + return new aureliaBinding.Conditional(new aureliaBinding.Binary('||', new aureliaBinding.Binary('===', part, this.nullExpression), new aureliaBinding.Binary('===', part, this.undefinedExpression)), this.emptyStringExpression, new aureliaBinding.CallMember(part, 'toString', [])); + }; + ValidationMessageParser.inject = [aureliaTemplating.BindingLanguage]; + return ValidationMessageParser; + }()); + var MessageExpressionValidator = /** @class */ (function (_super) { + __extends(MessageExpressionValidator, _super); + function MessageExpressionValidator(originalMessage) { + var _this = _super.call(this) || this; + _this.originalMessage = originalMessage; + return _this; + } + MessageExpressionValidator.validate = function (expression, originalMessage) { + var visitor = new MessageExpressionValidator(originalMessage); + expression.accept(visitor); + }; + MessageExpressionValidator.prototype.visitAccessScope = function (access) { + if (access.ancestor !== 0) { + throw new Error('$parent is not permitted in validation message expressions.'); + } + if (['displayName', 'propertyName', 'value', 'object', 'config', 'getDisplayName'].indexOf(access.name) !== -1) { + LogManager.getLogger('aurelia-validation') + // tslint:disable-next-line:max-line-length + .warn("Did you mean to use \"$" + access.name + "\" instead of \"" + access.name + "\" in this validation message template: \"" + this.originalMessage + "\"?"); + } + }; + return MessageExpressionValidator; + }(ExpressionVisitor)); + + /** + * Dictionary of validation messages. [messageKey]: messageExpression + */ + var validationMessages = { + /** + * The default validation message. Used with rules that have no standard message. + */ + default: "${$displayName} is invalid.", + required: "${$displayName} is required.", + matches: "${$displayName} is not correctly formatted.", + email: "${$displayName} is not a valid email.", + minLength: "${$displayName} must be at least ${$config.length} character${$config.length === 1 ? '' : 's'}.", + maxLength: "${$displayName} cannot be longer than ${$config.length} character${$config.length === 1 ? '' : 's'}.", + minItems: "${$displayName} must contain at least ${$config.count} item${$config.count === 1 ? '' : 's'}.", + maxItems: "${$displayName} cannot contain more than ${$config.count} item${$config.count === 1 ? '' : 's'}.", + equals: "${$displayName} must be ${$config.expectedValue}.", + }; + /** + * Retrieves validation messages and property display names. + */ + var ValidationMessageProvider = /** @class */ (function () { + function ValidationMessageProvider(parser) { + this.parser = parser; + } + /** + * Returns a message binding expression that corresponds to the key. + * @param key The message key. + */ + ValidationMessageProvider.prototype.getMessage = function (key) { + var message; + if (key in validationMessages) { + message = validationMessages[key]; + } + else { + message = validationMessages['default']; + } + return this.parser.parse(message); + }; + /** + * Formulates a property display name using the property name and the configured + * displayName (if provided). + * Override this with your own custom logic. + * @param propertyName The property name. + */ + ValidationMessageProvider.prototype.getDisplayName = function (propertyName, displayName) { + if (displayName !== null && displayName !== undefined) { + return (displayName instanceof Function) ? displayName() : displayName; + } + // split on upper-case letters. + var words = propertyName.toString().split(/(?=[A-Z])/).join(' '); + // capitalize first letter. + return words.charAt(0).toUpperCase() + words.slice(1); + }; + ValidationMessageProvider.inject = [ValidationMessageParser]; + return ValidationMessageProvider; + }()); + + /** + * Validates. + * Responsible for validating objects and properties. + */ + var StandardValidator = /** @class */ (function (_super) { + __extends(StandardValidator, _super); + function StandardValidator(messageProvider, resources) { + var _this = _super.call(this) || this; + _this.messageProvider = messageProvider; + _this.lookupFunctions = resources.lookupFunctions; + _this.getDisplayName = messageProvider.getDisplayName.bind(messageProvider); + return _this; + } + /** + * Validates the specified property. + * @param object The object to validate. + * @param propertyName The name of the property to validate. + * @param rules Optional. If unspecified, the rules will be looked up using the metadata + * for the object created by ValidationRules....on(class/object) + */ + StandardValidator.prototype.validateProperty = function (object, propertyName, rules) { + return this.validate(object, propertyName, rules || null); + }; + /** + * Validates all rules for specified object and it's properties. + * @param object The object to validate. + * @param rules Optional. If unspecified, the rules will be looked up using the metadata + * for the object created by ValidationRules....on(class/object) + */ + StandardValidator.prototype.validateObject = function (object, rules) { + return this.validate(object, null, rules || null); + }; + /** + * Determines whether a rule exists in a set of rules. + * @param rules The rules to search. + * @parem rule The rule to find. + */ + StandardValidator.prototype.ruleExists = function (rules, rule) { + var i = rules.length; + while (i--) { + if (rules[i].indexOf(rule) !== -1) { + return true; + } + } + return false; + }; + StandardValidator.prototype.getMessage = function (rule, object, value) { + var expression = rule.message || this.messageProvider.getMessage(rule.messageKey); + // tslint:disable-next-line:prefer-const + var _a = rule.property, propertyName = _a.name, displayName = _a.displayName; + if (propertyName !== null) { + displayName = this.messageProvider.getDisplayName(propertyName, displayName); + } + var overrideContext = { + $displayName: displayName, + $propertyName: propertyName, + $value: value, + $object: object, + $config: rule.config, + // returns the name of a given property, given just the property name (irrespective of the property's displayName) + // split on capital letters, first letter ensured to be capitalized + $getDisplayName: this.getDisplayName + }; + return expression.evaluate({ bindingContext: object, overrideContext: overrideContext }, this.lookupFunctions); + }; + StandardValidator.prototype.validateRuleSequence = function (object, propertyName, ruleSequence, sequence, results) { + var _this = this; + // are we validating all properties or a single property? + var validateAllProperties = propertyName === null || propertyName === undefined; + var rules = ruleSequence[sequence]; + var allValid = true; + // validate each rule. + var promises = []; + var _loop_1 = function (i) { + var rule = rules[i]; + // is the rule related to the property we're validating. + // tslint:disable-next-line:triple-equals | Use loose equality for property keys + if (!validateAllProperties && rule.property.name != propertyName) { + return "continue"; + } + // is this a conditional rule? is the condition met? + if (rule.when && !rule.when(object)) { + return "continue"; + } + // validate. + var value = rule.property.name === null ? object : object[rule.property.name]; + var promiseOrBoolean = rule.condition(value, object); + if (!(promiseOrBoolean instanceof Promise)) { + promiseOrBoolean = Promise.resolve(promiseOrBoolean); + } + promises.push(promiseOrBoolean.then(function (valid) { + var message = valid ? null : _this.getMessage(rule, object, value); + results.push(new ValidateResult(rule, object, rule.property.name, valid, message)); + allValid = allValid && valid; + return valid; + })); + }; + for (var i = 0; i < rules.length; i++) { + _loop_1(i); + } + return Promise.all(promises) + .then(function () { + sequence++; + if (allValid && sequence < ruleSequence.length) { + return _this.validateRuleSequence(object, propertyName, ruleSequence, sequence, results); + } + return results; + }); + }; + StandardValidator.prototype.validate = function (object, propertyName, rules) { + // rules specified? + if (!rules) { + // no. attempt to locate the rules. + rules = Rules.get(object); + } + // any rules? + if (!rules || rules.length === 0) { + return Promise.resolve([]); + } + return this.validateRuleSequence(object, propertyName, rules, 0, []); + }; + StandardValidator.inject = [ValidationMessageProvider, aureliaTemplating.ViewResources]; + return StandardValidator; + }(Validator)); + + /** + * Part of the fluent rule API. Enables customizing property rules. + */ + var FluentRuleCustomizer = /** @class */ (function () { + function FluentRuleCustomizer(property, condition, config, fluentEnsure, fluentRules, parsers) { + if (config === void 0) { config = {}; } + this.fluentEnsure = fluentEnsure; + this.fluentRules = fluentRules; + this.parsers = parsers; + this.rule = { + property: property, + condition: condition, + config: config, + when: null, + messageKey: 'default', + message: null, + sequence: fluentRules.sequence + }; + this.fluentEnsure._addRule(this.rule); + } + /** + * Validate subsequent rules after previously declared rules have + * been validated successfully. Use to postpone validation of costly + * rules until less expensive rules pass validation. + */ + FluentRuleCustomizer.prototype.then = function () { + this.fluentRules.sequence++; + return this; + }; + /** + * Specifies the key to use when looking up the rule's validation message. + */ + FluentRuleCustomizer.prototype.withMessageKey = function (key) { + this.rule.messageKey = key; + this.rule.message = null; + return this; + }; + /** + * Specifies rule's validation message. + */ + FluentRuleCustomizer.prototype.withMessage = function (message) { + this.rule.messageKey = 'custom'; + this.rule.message = this.parsers.message.parse(message); + return this; + }; + /** + * Specifies a condition that must be met before attempting to validate the rule. + * @param condition A function that accepts the object as a parameter and returns true + * or false whether the rule should be evaluated. + */ + FluentRuleCustomizer.prototype.when = function (condition) { + this.rule.when = condition; + return this; + }; + /** + * Tags the rule instance, enabling the rule to be found easily + * using ValidationRules.taggedRules(rules, tag) + */ + FluentRuleCustomizer.prototype.tag = function (tag) { + this.rule.tag = tag; + return this; + }; + ///// FluentEnsure APIs ///// + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor function. + */ + FluentRuleCustomizer.prototype.ensure = function (subject) { + return this.fluentEnsure.ensure(subject); + }; + /** + * Targets an object with validation rules. + */ + FluentRuleCustomizer.prototype.ensureObject = function () { + return this.fluentEnsure.ensureObject(); + }; + Object.defineProperty(FluentRuleCustomizer.prototype, "rules", { + /** + * Rules that have been defined using the fluent API. + */ + get: function () { + return this.fluentEnsure.rules; + }, + enumerable: true, + configurable: true + }); + /** + * Applies the rules to a class or object, making them discoverable by the StandardValidator. + * @param target A class or object. + */ + FluentRuleCustomizer.prototype.on = function (target) { + return this.fluentEnsure.on(target); + }; + ///////// FluentRules APIs ///////// + /** + * Applies an ad-hoc rule function to the ensured property or object. + * @param condition The function to validate the rule. + * Will be called with two arguments, the property value and the object. + * Should return a boolean or a Promise that resolves to a boolean. + */ + FluentRuleCustomizer.prototype.satisfies = function (condition, config) { + return this.fluentRules.satisfies(condition, config); + }; + /** + * Applies a rule by name. + * @param name The name of the custom or standard rule. + * @param args The rule's arguments. + */ + FluentRuleCustomizer.prototype.satisfiesRule = function (name) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + var _a; + return (_a = this.fluentRules).satisfiesRule.apply(_a, [name].concat(args)); + }; + /** + * Applies the "required" rule to the property. + * The value cannot be null, undefined or whitespace. + */ + FluentRuleCustomizer.prototype.required = function () { + return this.fluentRules.required(); + }; + /** + * Applies the "matches" rule to the property. + * Value must match the specified regular expression. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.matches = function (regex) { + return this.fluentRules.matches(regex); + }; + /** + * Applies the "email" rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.email = function () { + return this.fluentRules.email(); + }; + /** + * Applies the "minLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.minLength = function (length) { + return this.fluentRules.minLength(length); + }; + /** + * Applies the "maxLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.maxLength = function (length) { + return this.fluentRules.maxLength(length); + }; + /** + * Applies the "minItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRuleCustomizer.prototype.minItems = function (count) { + return this.fluentRules.minItems(count); + }; + /** + * Applies the "maxItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRuleCustomizer.prototype.maxItems = function (count) { + return this.fluentRules.maxItems(count); + }; + /** + * Applies the "equals" validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.equals = function (expectedValue) { + return this.fluentRules.equals(expectedValue); + }; + return FluentRuleCustomizer; + }()); + /** + * Part of the fluent rule API. Enables applying rules to properties and objects. + */ + var FluentRules = /** @class */ (function () { + function FluentRules(fluentEnsure, parsers, property) { + this.fluentEnsure = fluentEnsure; + this.parsers = parsers; + this.property = property; + /** + * Current rule sequence number. Used to postpone evaluation of rules until rules + * with lower sequence number have successfully validated. The "then" fluent API method + * manages this property, there's usually no need to set it directly. + */ + this.sequence = 0; + } + /** + * Sets the display name of the ensured property. + */ + FluentRules.prototype.displayName = function (name) { + this.property.displayName = name; + return this; + }; + /** + * Applies an ad-hoc rule function to the ensured property or object. + * @param condition The function to validate the rule. + * Will be called with two arguments, the property value and the object. + * Should return a boolean or a Promise that resolves to a boolean. + */ + FluentRules.prototype.satisfies = function (condition, config) { + return new FluentRuleCustomizer(this.property, condition, config, this.fluentEnsure, this, this.parsers); + }; + /** + * Applies a rule by name. + * @param name The name of the custom or standard rule. + * @param args The rule's arguments. + */ + FluentRules.prototype.satisfiesRule = function (name) { + var _this = this; + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + var rule = FluentRules.customRules[name]; + if (!rule) { + // standard rule? + rule = this[name]; + if (rule instanceof Function) { + return rule.call.apply(rule, [this].concat(args)); + } + throw new Error("Rule with name \"" + name + "\" does not exist."); + } + var config = rule.argsToConfig ? rule.argsToConfig.apply(rule, args) : undefined; + return this.satisfies(function (value, obj) { + var _a; + return (_a = rule.condition).call.apply(_a, [_this, value, obj].concat(args)); + }, config) + .withMessageKey(name); + }; + /** + * Applies the "required" rule to the property. + * The value cannot be null, undefined or whitespace. + */ + FluentRules.prototype.required = function () { + return this.satisfies(function (value) { + return value !== null + && value !== undefined + && !(isString(value) && !/\S/.test(value)); + }).withMessageKey('required'); + }; + /** + * Applies the "matches" rule to the property. + * Value must match the specified regular expression. + * null, undefined and empty-string values are considered valid. + */ + FluentRules.prototype.matches = function (regex) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || regex.test(value); }) + .withMessageKey('matches'); + }; + /** + * Applies the "email" rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRules.prototype.email = function () { + // regex from https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address + /* tslint:disable:max-line-length */ + return this.matches(/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/) + /* tslint:enable:max-line-length */ + .withMessageKey('email'); + }; + /** + * Applies the "minLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRules.prototype.minLength = function (length) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || value.length >= length; }, { length: length }) + .withMessageKey('minLength'); + }; + /** + * Applies the "maxLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRules.prototype.maxLength = function (length) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || value.length <= length; }, { length: length }) + .withMessageKey('maxLength'); + }; + /** + * Applies the "minItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRules.prototype.minItems = function (count) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length >= count; }, { count: count }) + .withMessageKey('minItems'); + }; + /** + * Applies the "maxItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRules.prototype.maxItems = function (count) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length <= count; }, { count: count }) + .withMessageKey('maxItems'); + }; + /** + * Applies the "equals" validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRules.prototype.equals = function (expectedValue) { + return this.satisfies(function (value) { return value === null || value === undefined || value === '' || value === expectedValue; }, { expectedValue: expectedValue }) + .withMessageKey('equals'); + }; + FluentRules.customRules = {}; + return FluentRules; + }()); + /** + * Part of the fluent rule API. Enables targeting properties and objects with rules. + */ + var FluentEnsure = /** @class */ (function () { + function FluentEnsure(parsers) { + this.parsers = parsers; + /** + * Rules that have been defined using the fluent API. + */ + this.rules = []; + } + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor + * function. + */ + FluentEnsure.prototype.ensure = function (property) { + this.assertInitialized(); + var name = this.parsers.property.parse(property); + var fluentRules = new FluentRules(this, this.parsers, { name: name, displayName: null }); + return this.mergeRules(fluentRules, name); + }; + /** + * Targets an object with validation rules. + */ + FluentEnsure.prototype.ensureObject = function () { + this.assertInitialized(); + var fluentRules = new FluentRules(this, this.parsers, { name: null, displayName: null }); + return this.mergeRules(fluentRules, null); + }; + /** + * Applies the rules to a class or object, making them discoverable by the StandardValidator. + * @param target A class or object. + */ + FluentEnsure.prototype.on = function (target) { + Rules.set(target, this.rules); + return this; + }; + /** + * Adds a rule definition to the sequenced ruleset. + * @internal + */ + FluentEnsure.prototype._addRule = function (rule) { + while (this.rules.length < rule.sequence + 1) { + this.rules.push([]); + } + this.rules[rule.sequence].push(rule); + }; + FluentEnsure.prototype.assertInitialized = function () { + if (this.parsers) { + return; + } + throw new Error("Did you forget to add \".plugin('aurelia-validation')\" to your main.js?"); + }; + FluentEnsure.prototype.mergeRules = function (fluentRules, propertyName) { + // tslint:disable-next-line:triple-equals | Use loose equality for property keys + var existingRules = this.rules.find(function (r) { return r.length > 0 && r[0].property.name == propertyName; }); + if (existingRules) { + var rule = existingRules[existingRules.length - 1]; + fluentRules.sequence = rule.sequence; + if (rule.property.displayName !== null) { + fluentRules = fluentRules.displayName(rule.property.displayName); + } + } + return fluentRules; + }; + return FluentEnsure; + }()); + /** + * Fluent rule definition API. + */ + var ValidationRules = /** @class */ (function () { + function ValidationRules() { + } + ValidationRules.initialize = function (messageParser, propertyParser) { + this.parsers = { + message: messageParser, + property: propertyParser + }; + }; + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor function. + */ + ValidationRules.ensure = function (property) { + return new FluentEnsure(ValidationRules.parsers).ensure(property); + }; + /** + * Targets an object with validation rules. + */ + ValidationRules.ensureObject = function () { + return new FluentEnsure(ValidationRules.parsers).ensureObject(); + }; + /** + * Defines a custom rule. + * @param name The name of the custom rule. Also serves as the message key. + * @param condition The rule function. + * @param message The message expression + * @param argsToConfig A function that maps the rule's arguments to a "config" + * object that can be used when evaluating the message expression. + */ + ValidationRules.customRule = function (name, condition, message, argsToConfig) { + validationMessages[name] = message; + FluentRules.customRules[name] = { condition: condition, argsToConfig: argsToConfig }; + }; + /** + * Returns rules with the matching tag. + * @param rules The rules to search. + * @param tag The tag to search for. + */ + ValidationRules.taggedRules = function (rules, tag) { + return rules.map(function (x) { return x.filter(function (r) { return r.tag === tag; }); }); + }; + /** + * Returns rules that have no tag. + * @param rules The rules to search. + */ + ValidationRules.untaggedRules = function (rules) { + return rules.map(function (x) { return x.filter(function (r) { return r.tag === undefined; }); }); + }; + /** + * Removes the rules from a class or object. + * @param target A class or object. + */ + ValidationRules.off = function (target) { + Rules.unset(target); + }; + return ValidationRules; + }()); + + // Exports + /** + * Aurelia Validation Configuration API + */ + var AureliaValidationConfiguration = /** @class */ (function () { + function AureliaValidationConfiguration() { + this.validatorType = StandardValidator; + } + /** + * Use a custom Validator implementation. + */ + AureliaValidationConfiguration.prototype.customValidator = function (type) { + this.validatorType = type; + }; + /** + * Applies the configuration. + */ + AureliaValidationConfiguration.prototype.apply = function (container) { + var validator = container.get(this.validatorType); + container.registerInstance(Validator, validator); + }; + return AureliaValidationConfiguration; + }()); + /** + * Configures the plugin. + */ + function configure( + // tslint:disable-next-line:ban-types + frameworkConfig, callback) { + // the fluent rule definition API needs the parser to translate messages + // to interpolation expressions. + var messageParser = frameworkConfig.container.get(ValidationMessageParser); + var propertyParser = frameworkConfig.container.get(PropertyAccessorParser); + ValidationRules.initialize(messageParser, propertyParser); + // configure... + var config = new AureliaValidationConfiguration(); + if (callback instanceof Function) { + callback(config); + } + config.apply(frameworkConfig.container); + // globalize the behaviors. + if (frameworkConfig.globalResources) { + frameworkConfig.globalResources(ValidateBindingBehavior, ValidateManuallyBindingBehavior, ValidateOnBlurBindingBehavior, ValidateOnChangeBindingBehavior, ValidateOnChangeOrBlurBindingBehavior, ValidationErrorsCustomAttribute, ValidationRendererCustomAttribute); + } + } + + exports.AureliaValidationConfiguration = AureliaValidationConfiguration; + exports.configure = configure; + exports.getTargetDOMElement = getTargetDOMElement; + exports.getPropertyInfo = getPropertyInfo; + exports.PropertyAccessorParser = PropertyAccessorParser; + exports.getAccessorExpression = getAccessorExpression; + exports.ValidateBindingBehavior = ValidateBindingBehavior; + exports.ValidateManuallyBindingBehavior = ValidateManuallyBindingBehavior; + exports.ValidateOnBlurBindingBehavior = ValidateOnBlurBindingBehavior; + exports.ValidateOnChangeBindingBehavior = ValidateOnChangeBindingBehavior; + exports.ValidateOnChangeOrBlurBindingBehavior = ValidateOnChangeOrBlurBindingBehavior; + exports.ValidateEvent = ValidateEvent; + exports.ValidateResult = ValidateResult; + exports.ValidationController = ValidationController; + exports.ValidationControllerFactory = ValidationControllerFactory; + exports.ValidationErrorsCustomAttribute = ValidationErrorsCustomAttribute; + exports.ValidationRendererCustomAttribute = ValidationRendererCustomAttribute; + exports.Validator = Validator; + exports.Rules = Rules; + exports.StandardValidator = StandardValidator; + exports.validationMessages = validationMessages; + exports.ValidationMessageProvider = ValidationMessageProvider; + exports.ValidationMessageParser = ValidationMessageParser; + exports.MessageExpressionValidator = MessageExpressionValidator; + exports.FluentRuleCustomizer = FluentRuleCustomizer; + exports.FluentRules = FluentRules; + exports.FluentEnsure = FluentEnsure; + exports.ValidationRules = ValidationRules; + + Object.defineProperty(exports, '__esModule', { value: true }); + }); diff --git a/dist/amd/controller-validate-result.d.ts b/dist/amd/controller-validate-result.d.ts deleted file mode 100644 index 5f814ed0..00000000 --- a/dist/amd/controller-validate-result.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { ValidateResult } from './validate-result'; -import { ValidateInstruction } from './validate-instruction'; -/** - * The result of a call to the validation controller's validate method. - */ -export interface ControllerValidateResult { - /** - * Whether validation passed. - */ - valid: boolean; - /** - * The validation result of every rule that was evaluated. - */ - results: ValidateResult[]; - /** - * The instruction passed to the controller's validate method. - */ - instruction?: ValidateInstruction; -} diff --git a/dist/amd/controller-validate-result.js b/dist/amd/controller-validate-result.js deleted file mode 100644 index 2ae92b6a..00000000 --- a/dist/amd/controller-validate-result.js +++ /dev/null @@ -1,4 +0,0 @@ -define(["require", "exports"], function (require, exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); -}); diff --git a/dist/amd/get-target-dom-element.d.ts b/dist/amd/get-target-dom-element.d.ts deleted file mode 100644 index 314fc952..00000000 --- a/dist/amd/get-target-dom-element.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Gets the DOM element associated with the data-binding. Most of the time it's - * the binding.target but sometimes binding.target is an aurelia custom element, - * or custom attribute which is a javascript "class" instance, so we need to use - * the controller's container to retrieve the actual DOM element. - */ -export declare function getTargetDOMElement(binding: any, view: any): Element; diff --git a/dist/amd/get-target-dom-element.js b/dist/amd/get-target-dom-element.js deleted file mode 100644 index 7a17663b..00000000 --- a/dist/amd/get-target-dom-element.js +++ /dev/null @@ -1,31 +0,0 @@ -define(["require", "exports", "aurelia-pal"], function (require, exports, aurelia_pal_1) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - /** - * Gets the DOM element associated with the data-binding. Most of the time it's - * the binding.target but sometimes binding.target is an aurelia custom element, - * or custom attribute which is a javascript "class" instance, so we need to use - * the controller's container to retrieve the actual DOM element. - */ - function getTargetDOMElement(binding, view) { - var target = binding.target; - // DOM element - if (target instanceof Element) { - return target; - } - // custom element or custom attribute - // tslint:disable-next-line:prefer-const - for (var i = 0, ii = view.controllers.length; i < ii; i++) { - var controller = view.controllers[i]; - if (controller.viewModel === target) { - var element = controller.container.get(aurelia_pal_1.DOM.Element); - if (element) { - return element; - } - throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\"."); - } - } - throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\"."); - } - exports.getTargetDOMElement = getTargetDOMElement; -}); diff --git a/dist/amd/implementation/expression-visitor.d.ts b/dist/amd/implementation/expression-visitor.d.ts deleted file mode 100644 index 47769fae..00000000 --- a/dist/amd/implementation/expression-visitor.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { ValueConverter, Conditional, AccessMember, AccessKeyed, CallMember, BindingBehavior, Binary } from 'aurelia-binding'; -export declare type Chain = any; -export declare type Assign = any; -export declare type AccessThis = any; -export declare type AccessScope = any; -export declare type CallScope = any; -export declare type CallFunction = any; -export declare type PrefixNot = any; -export declare type LiteralPrimitive = any; -export declare type LiteralArray = any; -export declare type LiteralObject = any; -export declare type LiteralString = any; -export declare class ExpressionVisitor { - visitChain(chain: Chain): void; - visitBindingBehavior(behavior: BindingBehavior): void; - visitValueConverter(converter: ValueConverter): void; - visitAssign(assign: Assign): void; - visitConditional(conditional: Conditional): void; - visitAccessThis(access: AccessThis): void; - visitAccessScope(access: AccessScope): void; - visitAccessMember(access: AccessMember): void; - visitAccessKeyed(access: AccessKeyed): void; - visitCallScope(call: CallScope): void; - visitCallFunction(call: CallFunction): void; - visitCallMember(call: CallMember): void; - visitPrefix(prefix: PrefixNot): void; - visitBinary(binary: Binary): void; - visitLiteralPrimitive(literal: LiteralPrimitive): void; - visitLiteralArray(literal: LiteralArray): void; - visitLiteralObject(literal: LiteralObject): void; - visitLiteralString(literal: LiteralString): void; - private visitArgs(args); -} diff --git a/dist/amd/implementation/expression-visitor.js b/dist/amd/implementation/expression-visitor.js deleted file mode 100644 index 635e6b2d..00000000 --- a/dist/amd/implementation/expression-visitor.js +++ /dev/null @@ -1,79 +0,0 @@ -define(["require", "exports"], function (require, exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - // tslint:disable:no-empty - var ExpressionVisitor = /** @class */ (function () { - function ExpressionVisitor() { - } - ExpressionVisitor.prototype.visitChain = function (chain) { - this.visitArgs(chain.expressions); - }; - ExpressionVisitor.prototype.visitBindingBehavior = function (behavior) { - behavior.expression.accept(this); - this.visitArgs(behavior.args); - }; - ExpressionVisitor.prototype.visitValueConverter = function (converter) { - converter.expression.accept(this); - this.visitArgs(converter.args); - }; - ExpressionVisitor.prototype.visitAssign = function (assign) { - assign.target.accept(this); - assign.value.accept(this); - }; - ExpressionVisitor.prototype.visitConditional = function (conditional) { - conditional.condition.accept(this); - conditional.yes.accept(this); - conditional.no.accept(this); - }; - ExpressionVisitor.prototype.visitAccessThis = function (access) { - access.ancestor = access.ancestor; - }; - ExpressionVisitor.prototype.visitAccessScope = function (access) { - access.name = access.name; - }; - ExpressionVisitor.prototype.visitAccessMember = function (access) { - access.object.accept(this); - }; - ExpressionVisitor.prototype.visitAccessKeyed = function (access) { - access.object.accept(this); - access.key.accept(this); - }; - ExpressionVisitor.prototype.visitCallScope = function (call) { - this.visitArgs(call.args); - }; - ExpressionVisitor.prototype.visitCallFunction = function (call) { - call.func.accept(this); - this.visitArgs(call.args); - }; - ExpressionVisitor.prototype.visitCallMember = function (call) { - call.object.accept(this); - this.visitArgs(call.args); - }; - ExpressionVisitor.prototype.visitPrefix = function (prefix) { - prefix.expression.accept(this); - }; - ExpressionVisitor.prototype.visitBinary = function (binary) { - binary.left.accept(this); - binary.right.accept(this); - }; - ExpressionVisitor.prototype.visitLiteralPrimitive = function (literal) { - literal.value = literal.value; - }; - ExpressionVisitor.prototype.visitLiteralArray = function (literal) { - this.visitArgs(literal.elements); - }; - ExpressionVisitor.prototype.visitLiteralObject = function (literal) { - this.visitArgs(literal.values); - }; - ExpressionVisitor.prototype.visitLiteralString = function (literal) { - literal.value = literal.value; - }; - ExpressionVisitor.prototype.visitArgs = function (args) { - for (var i = 0; i < args.length; i++) { - args[i].accept(this); - } - }; - return ExpressionVisitor; - }()); - exports.ExpressionVisitor = ExpressionVisitor; -}); diff --git a/dist/amd/implementation/rule.d.ts b/dist/amd/implementation/rule.d.ts deleted file mode 100644 index ffbb7b21..00000000 --- a/dist/amd/implementation/rule.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Expression } from 'aurelia-binding'; -export declare type ValidationDisplayNameAccessor = () => string; -/** - * Information related to a property that is the subject of validation. - */ -export interface RuleProperty { - /** - * The property name. null indicates the rule targets the object itself. - */ - name: string | number | null; - /** - * The displayName of the property (or object). - */ - displayName: string | ValidationDisplayNameAccessor | null; -} -/** - * A rule definition. Associations a rule with a property or object. - */ -export interface Rule { - property: RuleProperty; - condition: (value: TValue, object?: TObject) => boolean | Promise; - config: object; - when: ((object: TObject) => boolean) | null; - messageKey: string; - message: Expression | null; - sequence: number; - tag?: string; -} diff --git a/dist/amd/implementation/rule.js b/dist/amd/implementation/rule.js deleted file mode 100644 index 2ae92b6a..00000000 --- a/dist/amd/implementation/rule.js +++ /dev/null @@ -1,4 +0,0 @@ -define(["require", "exports"], function (require, exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); -}); diff --git a/dist/amd/implementation/rules.d.ts b/dist/amd/implementation/rules.d.ts deleted file mode 100644 index 30947f6f..00000000 --- a/dist/amd/implementation/rules.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Rule } from './rule'; -/** - * Sets, unsets and retrieves rules on an object or constructor function. - */ -export declare class Rules { - /** - * The name of the property that stores the rules. - */ - private static key; - /** - * Applies the rules to a target. - */ - static set(target: any, rules: Rule[][]): void; - /** - * Removes rules from a target. - */ - static unset(target: any): void; - /** - * Retrieves the target's rules. - */ - static get(target: any): Rule[][] | null; -} diff --git a/dist/amd/implementation/rules.js b/dist/amd/implementation/rules.js deleted file mode 100644 index b09cf5fa..00000000 --- a/dist/amd/implementation/rules.js +++ /dev/null @@ -1,41 +0,0 @@ -define(["require", "exports"], function (require, exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - /** - * Sets, unsets and retrieves rules on an object or constructor function. - */ - var Rules = /** @class */ (function () { - function Rules() { - } - /** - * Applies the rules to a target. - */ - Rules.set = function (target, rules) { - if (target instanceof Function) { - target = target.prototype; - } - Object.defineProperty(target, Rules.key, { enumerable: false, configurable: false, writable: true, value: rules }); - }; - /** - * Removes rules from a target. - */ - Rules.unset = function (target) { - if (target instanceof Function) { - target = target.prototype; - } - target[Rules.key] = null; - }; - /** - * Retrieves the target's rules. - */ - Rules.get = function (target) { - return target[Rules.key] || null; - }; - /** - * The name of the property that stores the rules. - */ - Rules.key = '__rules__'; - return Rules; - }()); - exports.Rules = Rules; -}); diff --git a/dist/amd/implementation/standard-validator.d.ts b/dist/amd/implementation/standard-validator.d.ts deleted file mode 100644 index c47a7d2e..00000000 --- a/dist/amd/implementation/standard-validator.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { ViewResources } from 'aurelia-templating'; -import { Validator } from '../validator'; -import { ValidateResult } from '../validate-result'; -import { Rule } from './rule'; -import { ValidationMessageProvider } from './validation-messages'; -/** - * Validates. - * Responsible for validating objects and properties. - */ -export declare class StandardValidator extends Validator { - static inject: (typeof ViewResources | typeof ValidationMessageProvider)[]; - private messageProvider; - private lookupFunctions; - private getDisplayName; - constructor(messageProvider: ValidationMessageProvider, resources: ViewResources); - /** - * Validates the specified property. - * @param object The object to validate. - * @param propertyName The name of the property to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - validateProperty(object: any, propertyName: string | number, rules?: any): Promise; - /** - * Validates all rules for specified object and it's properties. - * @param object The object to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - validateObject(object: any, rules?: any): Promise; - /** - * Determines whether a rule exists in a set of rules. - * @param rules The rules to search. - * @parem rule The rule to find. - */ - ruleExists(rules: Rule[][], rule: Rule): boolean; - private getMessage(rule, object, value); - private validateRuleSequence(object, propertyName, ruleSequence, sequence, results); - private validate(object, propertyName, rules); -} diff --git a/dist/amd/implementation/standard-validator.js b/dist/amd/implementation/standard-validator.js deleted file mode 100644 index f2c219ab..00000000 --- a/dist/amd/implementation/standard-validator.js +++ /dev/null @@ -1,139 +0,0 @@ -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -define(["require", "exports", "aurelia-templating", "../validator", "../validate-result", "./rules", "./validation-messages"], function (require, exports, aurelia_templating_1, validator_1, validate_result_1, rules_1, validation_messages_1) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - /** - * Validates. - * Responsible for validating objects and properties. - */ - var StandardValidator = /** @class */ (function (_super) { - __extends(StandardValidator, _super); - function StandardValidator(messageProvider, resources) { - var _this = _super.call(this) || this; - _this.messageProvider = messageProvider; - _this.lookupFunctions = resources.lookupFunctions; - _this.getDisplayName = messageProvider.getDisplayName.bind(messageProvider); - return _this; - } - /** - * Validates the specified property. - * @param object The object to validate. - * @param propertyName The name of the property to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - StandardValidator.prototype.validateProperty = function (object, propertyName, rules) { - return this.validate(object, propertyName, rules || null); - }; - /** - * Validates all rules for specified object and it's properties. - * @param object The object to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - StandardValidator.prototype.validateObject = function (object, rules) { - return this.validate(object, null, rules || null); - }; - /** - * Determines whether a rule exists in a set of rules. - * @param rules The rules to search. - * @parem rule The rule to find. - */ - StandardValidator.prototype.ruleExists = function (rules, rule) { - var i = rules.length; - while (i--) { - if (rules[i].indexOf(rule) !== -1) { - return true; - } - } - return false; - }; - StandardValidator.prototype.getMessage = function (rule, object, value) { - var expression = rule.message || this.messageProvider.getMessage(rule.messageKey); - // tslint:disable-next-line:prefer-const - var _a = rule.property, propertyName = _a.name, displayName = _a.displayName; - if (propertyName !== null) { - displayName = this.messageProvider.getDisplayName(propertyName, displayName); - } - var overrideContext = { - $displayName: displayName, - $propertyName: propertyName, - $value: value, - $object: object, - $config: rule.config, - // returns the name of a given property, given just the property name (irrespective of the property's displayName) - // split on capital letters, first letter ensured to be capitalized - $getDisplayName: this.getDisplayName - }; - return expression.evaluate({ bindingContext: object, overrideContext: overrideContext }, this.lookupFunctions); - }; - StandardValidator.prototype.validateRuleSequence = function (object, propertyName, ruleSequence, sequence, results) { - var _this = this; - // are we validating all properties or a single property? - var validateAllProperties = propertyName === null || propertyName === undefined; - var rules = ruleSequence[sequence]; - var allValid = true; - // validate each rule. - var promises = []; - var _loop_1 = function (i) { - var rule = rules[i]; - // is the rule related to the property we're validating. - // tslint:disable-next-line:triple-equals | Use loose equality for property keys - if (!validateAllProperties && rule.property.name != propertyName) { - return "continue"; - } - // is this a conditional rule? is the condition met? - if (rule.when && !rule.when(object)) { - return "continue"; - } - // validate. - var value = rule.property.name === null ? object : object[rule.property.name]; - var promiseOrBoolean = rule.condition(value, object); - if (!(promiseOrBoolean instanceof Promise)) { - promiseOrBoolean = Promise.resolve(promiseOrBoolean); - } - promises.push(promiseOrBoolean.then(function (valid) { - var message = valid ? null : _this.getMessage(rule, object, value); - results.push(new validate_result_1.ValidateResult(rule, object, rule.property.name, valid, message)); - allValid = allValid && valid; - return valid; - })); - }; - for (var i = 0; i < rules.length; i++) { - _loop_1(i); - } - return Promise.all(promises) - .then(function () { - sequence++; - if (allValid && sequence < ruleSequence.length) { - return _this.validateRuleSequence(object, propertyName, ruleSequence, sequence, results); - } - return results; - }); - }; - StandardValidator.prototype.validate = function (object, propertyName, rules) { - // rules specified? - if (!rules) { - // no. attempt to locate the rules. - rules = rules_1.Rules.get(object); - } - // any rules? - if (!rules || rules.length === 0) { - return Promise.resolve([]); - } - return this.validateRuleSequence(object, propertyName, rules, 0, []); - }; - StandardValidator.inject = [validation_messages_1.ValidationMessageProvider, aurelia_templating_1.ViewResources]; - return StandardValidator; - }(validator_1.Validator)); - exports.StandardValidator = StandardValidator; -}); diff --git a/dist/amd/implementation/validation-message-parser.js b/dist/amd/implementation/validation-message-parser.js deleted file mode 100644 index 3600bc72..00000000 --- a/dist/amd/implementation/validation-message-parser.js +++ /dev/null @@ -1,69 +0,0 @@ -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -define(["require", "exports", "aurelia-binding", "aurelia-templating", "aurelia-logging", "./expression-visitor"], function (require, exports, aurelia_binding_1, aurelia_templating_1, LogManager, expression_visitor_1) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - var ValidationMessageParser = /** @class */ (function () { - function ValidationMessageParser(bindinqLanguage) { - this.bindinqLanguage = bindinqLanguage; - this.emptyStringExpression = new aurelia_binding_1.LiteralString(''); - this.nullExpression = new aurelia_binding_1.LiteralPrimitive(null); - this.undefinedExpression = new aurelia_binding_1.LiteralPrimitive(undefined); - this.cache = {}; - } - ValidationMessageParser.prototype.parse = function (message) { - if (this.cache[message] !== undefined) { - return this.cache[message]; - } - var parts = this.bindinqLanguage.parseInterpolation(null, message); - if (parts === null) { - return new aurelia_binding_1.LiteralString(message); - } - var expression = new aurelia_binding_1.LiteralString(parts[0]); - for (var i = 1; i < parts.length; i += 2) { - expression = new aurelia_binding_1.Binary('+', expression, new aurelia_binding_1.Binary('+', this.coalesce(parts[i]), new aurelia_binding_1.LiteralString(parts[i + 1]))); - } - MessageExpressionValidator.validate(expression, message); - this.cache[message] = expression; - return expression; - }; - ValidationMessageParser.prototype.coalesce = function (part) { - // part === null || part === undefined ? '' : part - return new aurelia_binding_1.Conditional(new aurelia_binding_1.Binary('||', new aurelia_binding_1.Binary('===', part, this.nullExpression), new aurelia_binding_1.Binary('===', part, this.undefinedExpression)), this.emptyStringExpression, new aurelia_binding_1.CallMember(part, 'toString', [])); - }; - ValidationMessageParser.inject = [aurelia_templating_1.BindingLanguage]; - return ValidationMessageParser; - }()); - exports.ValidationMessageParser = ValidationMessageParser; - var MessageExpressionValidator = /** @class */ (function (_super) { - __extends(MessageExpressionValidator, _super); - function MessageExpressionValidator(originalMessage) { - var _this = _super.call(this) || this; - _this.originalMessage = originalMessage; - return _this; - } - MessageExpressionValidator.validate = function (expression, originalMessage) { - var visitor = new MessageExpressionValidator(originalMessage); - expression.accept(visitor); - }; - MessageExpressionValidator.prototype.visitAccessScope = function (access) { - if (access.ancestor !== 0) { - throw new Error('$parent is not permitted in validation message expressions.'); - } - if (['displayName', 'propertyName', 'value', 'object', 'config', 'getDisplayName'].indexOf(access.name) !== -1) { - LogManager.getLogger('aurelia-validation') - .warn("Did you mean to use \"$" + access.name + "\" instead of \"" + access.name + "\" in this validation message template: \"" + this.originalMessage + "\"?"); - } - }; - return MessageExpressionValidator; - }(expression_visitor_1.ExpressionVisitor)); - exports.MessageExpressionValidator = MessageExpressionValidator; -}); diff --git a/dist/amd/implementation/validation-messages.d.ts b/dist/amd/implementation/validation-messages.d.ts deleted file mode 100644 index eb4cb9d4..00000000 --- a/dist/amd/implementation/validation-messages.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Expression } from 'aurelia-binding'; -import { ValidationMessageParser } from './validation-message-parser'; -export interface ValidationMessages { - [key: string]: string; -} -/** - * Dictionary of validation messages. [messageKey]: messageExpression - */ -export declare const validationMessages: ValidationMessages; -/** - * Retrieves validation messages and property display names. - */ -export declare class ValidationMessageProvider { - parser: ValidationMessageParser; - static inject: (typeof ValidationMessageParser)[]; - constructor(parser: ValidationMessageParser); - /** - * Returns a message binding expression that corresponds to the key. - * @param key The message key. - */ - getMessage(key: string): Expression; - /** - * Formulates a property display name using the property name and the configured - * displayName (if provided). - * Override this with your own custom logic. - * @param propertyName The property name. - */ - getDisplayName(propertyName: string | number, displayName?: string | null | (() => string)): string; -} diff --git a/dist/amd/implementation/validation-messages.js b/dist/amd/implementation/validation-messages.js deleted file mode 100644 index 92ca7d0e..00000000 --- a/dist/amd/implementation/validation-messages.js +++ /dev/null @@ -1,61 +0,0 @@ -define(["require", "exports", "./validation-message-parser"], function (require, exports, validation_message_parser_1) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - /** - * Dictionary of validation messages. [messageKey]: messageExpression - */ - exports.validationMessages = { - /** - * The default validation message. Used with rules that have no standard message. - */ - default: "${$displayName} is invalid.", - required: "${$displayName} is required.", - matches: "${$displayName} is not correctly formatted.", - email: "${$displayName} is not a valid email.", - minLength: "${$displayName} must be at least ${$config.length} character${$config.length === 1 ? '' : 's'}.", - maxLength: "${$displayName} cannot be longer than ${$config.length} character${$config.length === 1 ? '' : 's'}.", - minItems: "${$displayName} must contain at least ${$config.count} item${$config.count === 1 ? '' : 's'}.", - maxItems: "${$displayName} cannot contain more than ${$config.count} item${$config.count === 1 ? '' : 's'}.", - equals: "${$displayName} must be ${$config.expectedValue}.", - }; - /** - * Retrieves validation messages and property display names. - */ - var ValidationMessageProvider = /** @class */ (function () { - function ValidationMessageProvider(parser) { - this.parser = parser; - } - /** - * Returns a message binding expression that corresponds to the key. - * @param key The message key. - */ - ValidationMessageProvider.prototype.getMessage = function (key) { - var message; - if (key in exports.validationMessages) { - message = exports.validationMessages[key]; - } - else { - message = exports.validationMessages['default']; - } - return this.parser.parse(message); - }; - /** - * Formulates a property display name using the property name and the configured - * displayName (if provided). - * Override this with your own custom logic. - * @param propertyName The property name. - */ - ValidationMessageProvider.prototype.getDisplayName = function (propertyName, displayName) { - if (displayName !== null && displayName !== undefined) { - return (displayName instanceof Function) ? displayName() : displayName; - } - // split on upper-case letters. - var words = propertyName.toString().split(/(?=[A-Z])/).join(' '); - // capitalize first letter. - return words.charAt(0).toUpperCase() + words.slice(1); - }; - ValidationMessageProvider.inject = [validation_message_parser_1.ValidationMessageParser]; - return ValidationMessageProvider; - }()); - exports.ValidationMessageProvider = ValidationMessageProvider; -}); diff --git a/dist/amd/implementation/validation-rules.d.ts b/dist/amd/implementation/validation-rules.d.ts deleted file mode 100644 index 995b2a8a..00000000 --- a/dist/amd/implementation/validation-rules.d.ts +++ /dev/null @@ -1,262 +0,0 @@ -import { Rule, RuleProperty, ValidationDisplayNameAccessor } from './rule'; -import { ValidationMessageParser } from './validation-message-parser'; -import { PropertyAccessorParser, PropertyAccessor } from '../property-accessor-parser'; -/** - * Part of the fluent rule API. Enables customizing property rules. - */ -export declare class FluentRuleCustomizer { - private fluentEnsure; - private fluentRules; - private parsers; - private rule; - constructor(property: RuleProperty, condition: (value: TValue, object?: TObject) => boolean | Promise, config: object | undefined, fluentEnsure: FluentEnsure, fluentRules: FluentRules, parsers: Parsers); - /** - * Validate subsequent rules after previously declared rules have - * been validated successfully. Use to postpone validation of costly - * rules until less expensive rules pass validation. - */ - then(): this; - /** - * Specifies the key to use when looking up the rule's validation message. - */ - withMessageKey(key: string): this; - /** - * Specifies rule's validation message. - */ - withMessage(message: string): this; - /** - * Specifies a condition that must be met before attempting to validate the rule. - * @param condition A function that accepts the object as a parameter and returns true - * or false whether the rule should be evaluated. - */ - when(condition: (object: TObject) => boolean): this; - /** - * Tags the rule instance, enabling the rule to be found easily - * using ValidationRules.taggedRules(rules, tag) - */ - tag(tag: string): this; - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - ensure(subject: string | ((model: TObject) => TValue2)): FluentRules; - /** - * Targets an object with validation rules. - */ - ensureObject(): FluentRules; - /** - * Rules that have been defined using the fluent API. - */ - readonly rules: Rule[][]; - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - on(target: any): FluentEnsure; - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - satisfies(condition: (value: TValue, object: TObject) => boolean | Promise, config?: object): FluentRuleCustomizer; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - satisfiesRule(name: string, ...args: any[]): FluentRuleCustomizer; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - required(): FluentRuleCustomizer; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - matches(regex: RegExp): FluentRuleCustomizer; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - email(): FluentRuleCustomizer; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - minLength(length: number): FluentRuleCustomizer; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - maxLength(length: number): FluentRuleCustomizer; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - minItems(count: number): FluentRuleCustomizer; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - maxItems(count: number): FluentRuleCustomizer; - /** - * Applies the "equals" validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - equals(expectedValue: TValue): FluentRuleCustomizer; -} -/** - * Part of the fluent rule API. Enables applying rules to properties and objects. - */ -export declare class FluentRules { - private fluentEnsure; - private parsers; - private property; - static customRules: { - [name: string]: { - condition: (value: any, object?: any, ...fluentArgs: any[]) => boolean | Promise; - argsToConfig?: (...args: any[]) => any; - }; - }; - /** - * Current rule sequence number. Used to postpone evaluation of rules until rules - * with lower sequence number have successfully validated. The "then" fluent API method - * manages this property, there's usually no need to set it directly. - */ - sequence: number; - constructor(fluentEnsure: FluentEnsure, parsers: Parsers, property: RuleProperty); - /** - * Sets the display name of the ensured property. - */ - displayName(name: string | ValidationDisplayNameAccessor | null): this; - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - satisfies(condition: (value: TValue, object?: TObject) => boolean | Promise, config?: object): FluentRuleCustomizer; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - satisfiesRule(name: string, ...args: any[]): FluentRuleCustomizer; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - required(): FluentRuleCustomizer; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - matches(regex: RegExp): FluentRuleCustomizer; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - email(): FluentRuleCustomizer; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - minLength(length: number): FluentRuleCustomizer; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - maxLength(length: number): FluentRuleCustomizer; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - minItems(count: number): FluentRuleCustomizer; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - maxItems(count: number): FluentRuleCustomizer; - /** - * Applies the "equals" validation rule to the property. - * null and undefined values are considered valid. - */ - equals(expectedValue: TValue): FluentRuleCustomizer; -} -/** - * Part of the fluent rule API. Enables targeting properties and objects with rules. - */ -export declare class FluentEnsure { - private parsers; - /** - * Rules that have been defined using the fluent API. - */ - rules: Rule[][]; - constructor(parsers: Parsers); - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor - * function. - */ - ensure(property: string | number | PropertyAccessor): FluentRules; - /** - * Targets an object with validation rules. - */ - ensureObject(): FluentRules; - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - on(target: any): this; - private assertInitialized(); - private mergeRules(fluentRules, propertyName); -} -/** - * Fluent rule definition API. - */ -export declare class ValidationRules { - private static parsers; - static initialize(messageParser: ValidationMessageParser, propertyParser: PropertyAccessorParser): void; - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - static ensure(property: string | number | PropertyAccessor): FluentRules; - /** - * Targets an object with validation rules. - */ - static ensureObject(): FluentRules; - /** - * Defines a custom rule. - * @param name The name of the custom rule. Also serves as the message key. - * @param condition The rule function. - * @param message The message expression - * @param argsToConfig A function that maps the rule's arguments to a "config" - * object that can be used when evaluating the message expression. - */ - static customRule(name: string, condition: (value: any, object?: any, ...args: any[]) => boolean | Promise, message: string, argsToConfig?: (...args: any[]) => any): void; - /** - * Returns rules with the matching tag. - * @param rules The rules to search. - * @param tag The tag to search for. - */ - static taggedRules(rules: Rule[][], tag: string): Rule[][]; - /** - * Returns rules that have no tag. - * @param rules The rules to search. - */ - static untaggedRules(rules: Rule[][]): Rule[][]; - /** - * Removes the rules from a class or object. - * @param target A class or object. - */ - static off(target: any): void; -} -export interface Parsers { - message: ValidationMessageParser; - property: PropertyAccessorParser; -} diff --git a/dist/amd/implementation/validation-rules.js b/dist/amd/implementation/validation-rules.js deleted file mode 100644 index 2791d34f..00000000 --- a/dist/amd/implementation/validation-rules.js +++ /dev/null @@ -1,443 +0,0 @@ -define(["require", "exports", "./rules", "./validation-messages", "../util"], function (require, exports, rules_1, validation_messages_1, util_1) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - /** - * Part of the fluent rule API. Enables customizing property rules. - */ - var FluentRuleCustomizer = /** @class */ (function () { - function FluentRuleCustomizer(property, condition, config, fluentEnsure, fluentRules, parsers) { - if (config === void 0) { config = {}; } - this.fluentEnsure = fluentEnsure; - this.fluentRules = fluentRules; - this.parsers = parsers; - this.rule = { - property: property, - condition: condition, - config: config, - when: null, - messageKey: 'default', - message: null, - sequence: fluentRules.sequence - }; - this.fluentEnsure._addRule(this.rule); - } - /** - * Validate subsequent rules after previously declared rules have - * been validated successfully. Use to postpone validation of costly - * rules until less expensive rules pass validation. - */ - FluentRuleCustomizer.prototype.then = function () { - this.fluentRules.sequence++; - return this; - }; - /** - * Specifies the key to use when looking up the rule's validation message. - */ - FluentRuleCustomizer.prototype.withMessageKey = function (key) { - this.rule.messageKey = key; - this.rule.message = null; - return this; - }; - /** - * Specifies rule's validation message. - */ - FluentRuleCustomizer.prototype.withMessage = function (message) { - this.rule.messageKey = 'custom'; - this.rule.message = this.parsers.message.parse(message); - return this; - }; - /** - * Specifies a condition that must be met before attempting to validate the rule. - * @param condition A function that accepts the object as a parameter and returns true - * or false whether the rule should be evaluated. - */ - FluentRuleCustomizer.prototype.when = function (condition) { - this.rule.when = condition; - return this; - }; - /** - * Tags the rule instance, enabling the rule to be found easily - * using ValidationRules.taggedRules(rules, tag) - */ - FluentRuleCustomizer.prototype.tag = function (tag) { - this.rule.tag = tag; - return this; - }; - ///// FluentEnsure APIs ///// - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - FluentRuleCustomizer.prototype.ensure = function (subject) { - return this.fluentEnsure.ensure(subject); - }; - /** - * Targets an object with validation rules. - */ - FluentRuleCustomizer.prototype.ensureObject = function () { - return this.fluentEnsure.ensureObject(); - }; - Object.defineProperty(FluentRuleCustomizer.prototype, "rules", { - /** - * Rules that have been defined using the fluent API. - */ - get: function () { - return this.fluentEnsure.rules; - }, - enumerable: true, - configurable: true - }); - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - FluentRuleCustomizer.prototype.on = function (target) { - return this.fluentEnsure.on(target); - }; - ///////// FluentRules APIs ///////// - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - FluentRuleCustomizer.prototype.satisfies = function (condition, config) { - return this.fluentRules.satisfies(condition, config); - }; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - FluentRuleCustomizer.prototype.satisfiesRule = function (name) { - var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; - } - return (_a = this.fluentRules).satisfiesRule.apply(_a, [name].concat(args)); - var _a; - }; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - FluentRuleCustomizer.prototype.required = function () { - return this.fluentRules.required(); - }; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.matches = function (regex) { - return this.fluentRules.matches(regex); - }; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.email = function () { - return this.fluentRules.email(); - }; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.minLength = function (length) { - return this.fluentRules.minLength(length); - }; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.maxLength = function (length) { - return this.fluentRules.maxLength(length); - }; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRuleCustomizer.prototype.minItems = function (count) { - return this.fluentRules.minItems(count); - }; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRuleCustomizer.prototype.maxItems = function (count) { - return this.fluentRules.maxItems(count); - }; - /** - * Applies the "equals" validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.equals = function (expectedValue) { - return this.fluentRules.equals(expectedValue); - }; - return FluentRuleCustomizer; - }()); - exports.FluentRuleCustomizer = FluentRuleCustomizer; - /** - * Part of the fluent rule API. Enables applying rules to properties and objects. - */ - var FluentRules = /** @class */ (function () { - function FluentRules(fluentEnsure, parsers, property) { - this.fluentEnsure = fluentEnsure; - this.parsers = parsers; - this.property = property; - /** - * Current rule sequence number. Used to postpone evaluation of rules until rules - * with lower sequence number have successfully validated. The "then" fluent API method - * manages this property, there's usually no need to set it directly. - */ - this.sequence = 0; - } - /** - * Sets the display name of the ensured property. - */ - FluentRules.prototype.displayName = function (name) { - this.property.displayName = name; - return this; - }; - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - FluentRules.prototype.satisfies = function (condition, config) { - return new FluentRuleCustomizer(this.property, condition, config, this.fluentEnsure, this, this.parsers); - }; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - FluentRules.prototype.satisfiesRule = function (name) { - var _this = this; - var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; - } - var rule = FluentRules.customRules[name]; - if (!rule) { - // standard rule? - rule = this[name]; - if (rule instanceof Function) { - return rule.call.apply(rule, [this].concat(args)); - } - throw new Error("Rule with name \"" + name + "\" does not exist."); - } - var config = rule.argsToConfig ? rule.argsToConfig.apply(rule, args) : undefined; - return this.satisfies(function (value, obj) { - return (_a = rule.condition).call.apply(_a, [_this, value, obj].concat(args)); - var _a; - }, config) - .withMessageKey(name); - }; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - FluentRules.prototype.required = function () { - return this.satisfies(function (value) { - return value !== null - && value !== undefined - && !(util_1.isString(value) && !/\S/.test(value)); - }).withMessageKey('required'); - }; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - FluentRules.prototype.matches = function (regex) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || regex.test(value); }) - .withMessageKey('matches'); - }; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRules.prototype.email = function () { - // regex from https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address - /* tslint:disable:max-line-length */ - return this.matches(/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/) - .withMessageKey('email'); - }; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRules.prototype.minLength = function (length) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || value.length >= length; }, { length: length }) - .withMessageKey('minLength'); - }; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRules.prototype.maxLength = function (length) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || value.length <= length; }, { length: length }) - .withMessageKey('maxLength'); - }; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRules.prototype.minItems = function (count) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length >= count; }, { count: count }) - .withMessageKey('minItems'); - }; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRules.prototype.maxItems = function (count) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length <= count; }, { count: count }) - .withMessageKey('maxItems'); - }; - /** - * Applies the "equals" validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRules.prototype.equals = function (expectedValue) { - return this.satisfies(function (value) { return value === null || value === undefined || value === '' || value === expectedValue; }, { expectedValue: expectedValue }) - .withMessageKey('equals'); - }; - FluentRules.customRules = {}; - return FluentRules; - }()); - exports.FluentRules = FluentRules; - /** - * Part of the fluent rule API. Enables targeting properties and objects with rules. - */ - var FluentEnsure = /** @class */ (function () { - function FluentEnsure(parsers) { - this.parsers = parsers; - /** - * Rules that have been defined using the fluent API. - */ - this.rules = []; - } - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor - * function. - */ - FluentEnsure.prototype.ensure = function (property) { - this.assertInitialized(); - var name = this.parsers.property.parse(property); - var fluentRules = new FluentRules(this, this.parsers, { name: name, displayName: null }); - return this.mergeRules(fluentRules, name); - }; - /** - * Targets an object with validation rules. - */ - FluentEnsure.prototype.ensureObject = function () { - this.assertInitialized(); - var fluentRules = new FluentRules(this, this.parsers, { name: null, displayName: null }); - return this.mergeRules(fluentRules, null); - }; - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - FluentEnsure.prototype.on = function (target) { - rules_1.Rules.set(target, this.rules); - return this; - }; - /** - * Adds a rule definition to the sequenced ruleset. - * @internal - */ - FluentEnsure.prototype._addRule = function (rule) { - while (this.rules.length < rule.sequence + 1) { - this.rules.push([]); - } - this.rules[rule.sequence].push(rule); - }; - FluentEnsure.prototype.assertInitialized = function () { - if (this.parsers) { - return; - } - throw new Error("Did you forget to add \".plugin('aurelia-validation')\" to your main.js?"); - }; - FluentEnsure.prototype.mergeRules = function (fluentRules, propertyName) { - // tslint:disable-next-line:triple-equals | Use loose equality for property keys - var existingRules = this.rules.find(function (r) { return r.length > 0 && r[0].property.name == propertyName; }); - if (existingRules) { - var rule = existingRules[existingRules.length - 1]; - fluentRules.sequence = rule.sequence; - if (rule.property.displayName !== null) { - fluentRules = fluentRules.displayName(rule.property.displayName); - } - } - return fluentRules; - }; - return FluentEnsure; - }()); - exports.FluentEnsure = FluentEnsure; - /** - * Fluent rule definition API. - */ - var ValidationRules = /** @class */ (function () { - function ValidationRules() { - } - ValidationRules.initialize = function (messageParser, propertyParser) { - this.parsers = { - message: messageParser, - property: propertyParser - }; - }; - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - ValidationRules.ensure = function (property) { - return new FluentEnsure(ValidationRules.parsers).ensure(property); - }; - /** - * Targets an object with validation rules. - */ - ValidationRules.ensureObject = function () { - return new FluentEnsure(ValidationRules.parsers).ensureObject(); - }; - /** - * Defines a custom rule. - * @param name The name of the custom rule. Also serves as the message key. - * @param condition The rule function. - * @param message The message expression - * @param argsToConfig A function that maps the rule's arguments to a "config" - * object that can be used when evaluating the message expression. - */ - ValidationRules.customRule = function (name, condition, message, argsToConfig) { - validation_messages_1.validationMessages[name] = message; - FluentRules.customRules[name] = { condition: condition, argsToConfig: argsToConfig }; - }; - /** - * Returns rules with the matching tag. - * @param rules The rules to search. - * @param tag The tag to search for. - */ - ValidationRules.taggedRules = function (rules, tag) { - return rules.map(function (x) { return x.filter(function (r) { return r.tag === tag; }); }); - }; - /** - * Returns rules that have no tag. - * @param rules The rules to search. - */ - ValidationRules.untaggedRules = function (rules) { - return rules.map(function (x) { return x.filter(function (r) { return r.tag === undefined; }); }); - }; - /** - * Removes the rules from a class or object. - * @param target A class or object. - */ - ValidationRules.off = function (target) { - rules_1.Rules.unset(target); - }; - return ValidationRules; - }()); - exports.ValidationRules = ValidationRules; -}); diff --git a/dist/amd/property-accessor-parser.js b/dist/amd/property-accessor-parser.js deleted file mode 100644 index 93be6385..00000000 --- a/dist/amd/property-accessor-parser.js +++ /dev/null @@ -1,36 +0,0 @@ -define(["require", "exports", "aurelia-binding", "./util"], function (require, exports, aurelia_binding_1, util_1) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - var PropertyAccessorParser = /** @class */ (function () { - function PropertyAccessorParser(parser) { - this.parser = parser; - } - PropertyAccessorParser.prototype.parse = function (property) { - if (util_1.isString(property) || util_1.isNumber(property)) { - return property; - } - var accessorText = getAccessorExpression(property.toString()); - var accessor = this.parser.parse(accessorText); - if (accessor instanceof aurelia_binding_1.AccessScope - || accessor instanceof aurelia_binding_1.AccessMember && accessor.object instanceof aurelia_binding_1.AccessScope) { - return accessor.name; - } - throw new Error("Invalid property expression: \"" + accessor + "\""); - }; - PropertyAccessorParser.inject = [aurelia_binding_1.Parser]; - return PropertyAccessorParser; - }()); - exports.PropertyAccessorParser = PropertyAccessorParser; - function getAccessorExpression(fn) { - /* tslint:disable:max-line-length */ - var classic = /^function\s*\([$_\w\d]+\)\s*\{(?:\s*"use strict";)?\s*(?:[$_\w\d.['"\]+;]+)?\s*return\s+[$_\w\d]+\.([$_\w\d]+)\s*;?\s*\}$/; - /* tslint:enable:max-line-length */ - var arrow = /^\(?[$_\w\d]+\)?\s*=>\s*[$_\w\d]+\.([$_\w\d]+)$/; - var match = classic.exec(fn) || arrow.exec(fn); - if (match === null) { - throw new Error("Unable to parse accessor function:\n" + fn); - } - return match[1]; - } - exports.getAccessorExpression = getAccessorExpression; -}); diff --git a/dist/amd/property-info.d.ts b/dist/amd/property-info.d.ts deleted file mode 100644 index 35fef1d5..00000000 --- a/dist/amd/property-info.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Expression, Scope } from 'aurelia-binding'; -/** - * Retrieves the object and property name for the specified expression. - * @param expression The expression - * @param source The scope - */ -export declare function getPropertyInfo(expression: Expression, source: Scope): { - object: object; - propertyName: string; -} | null; diff --git a/dist/amd/property-info.js b/dist/amd/property-info.js deleted file mode 100644 index b2f92da9..00000000 --- a/dist/amd/property-info.js +++ /dev/null @@ -1,45 +0,0 @@ -define(["require", "exports", "aurelia-binding"], function (require, exports, aurelia_binding_1) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - function getObject(expression, objectExpression, source) { - var value = objectExpression.evaluate(source, null); - if (value === null || value === undefined || value instanceof Object) { - return value; - } - // tslint:disable-next-line:max-line-length - throw new Error("The '" + objectExpression + "' part of '" + expression + "' evaluates to " + value + " instead of an object, null or undefined."); - } - /** - * Retrieves the object and property name for the specified expression. - * @param expression The expression - * @param source The scope - */ - function getPropertyInfo(expression, source) { - var originalExpression = expression; - while (expression instanceof aurelia_binding_1.BindingBehavior || expression instanceof aurelia_binding_1.ValueConverter) { - expression = expression.expression; - } - var object; - var propertyName; - if (expression instanceof aurelia_binding_1.AccessScope) { - object = aurelia_binding_1.getContextFor(expression.name, source, expression.ancestor); - propertyName = expression.name; - } - else if (expression instanceof aurelia_binding_1.AccessMember) { - object = getObject(originalExpression, expression.object, source); - propertyName = expression.name; - } - else if (expression instanceof aurelia_binding_1.AccessKeyed) { - object = getObject(originalExpression, expression.object, source); - propertyName = expression.key.evaluate(source); - } - else { - throw new Error("Expression '" + originalExpression + "' is not compatible with the validate binding-behavior."); - } - if (object === null || object === undefined) { - return null; - } - return { object: object, propertyName: propertyName }; - } - exports.getPropertyInfo = getPropertyInfo; -}); diff --git a/dist/amd/util.js b/dist/amd/util.js deleted file mode 100644 index 946e02c5..00000000 --- a/dist/amd/util.js +++ /dev/null @@ -1,12 +0,0 @@ -define(["require", "exports"], function (require, exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - function isString(value) { - return Object.prototype.toString.call(value) === '[object String]'; - } - exports.isString = isString; - function isNumber(value) { - return Object.prototype.toString.call(value) === '[object Number]'; - } - exports.isNumber = isNumber; -}); diff --git a/dist/amd/validate-binding-behavior-base.js b/dist/amd/validate-binding-behavior-base.js deleted file mode 100644 index c97b7fee..00000000 --- a/dist/amd/validate-binding-behavior-base.js +++ /dev/null @@ -1,79 +0,0 @@ -define(["require", "exports", "aurelia-dependency-injection", "./validation-controller", "./validate-trigger", "./get-target-dom-element"], function (require, exports, aurelia_dependency_injection_1, validation_controller_1, validate_trigger_1, get_target_dom_element_1) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - /** - * Binding behavior. Indicates the bound property should be validated. - */ - var ValidateBindingBehaviorBase = /** @class */ (function () { - function ValidateBindingBehaviorBase(taskQueue) { - this.taskQueue = taskQueue; - } - ValidateBindingBehaviorBase.prototype.bind = function (binding, source, rulesOrController, rules) { - var _this = this; - // identify the target element. - var target = get_target_dom_element_1.getTargetDOMElement(binding, source); - // locate the controller. - var controller; - if (rulesOrController instanceof validation_controller_1.ValidationController) { - controller = rulesOrController; - } - else { - controller = source.container.get(aurelia_dependency_injection_1.Optional.of(validation_controller_1.ValidationController)); - rules = rulesOrController; - } - if (controller === null) { - throw new Error("A ValidationController has not been registered."); - } - controller.registerBinding(binding, target, rules); - binding.validationController = controller; - var trigger = this.getValidateTrigger(controller); - // tslint:disable-next-line:no-bitwise - if (trigger & validate_trigger_1.validateTrigger.change) { - binding.vbbUpdateSource = binding.updateSource; - // tslint:disable-next-line:only-arrow-functions - // tslint:disable-next-line:space-before-function-paren - binding.updateSource = function (value) { - this.vbbUpdateSource(value); - this.validationController.validateBinding(this); - }; - } - // tslint:disable-next-line:no-bitwise - if (trigger & validate_trigger_1.validateTrigger.blur) { - binding.validateBlurHandler = function () { - _this.taskQueue.queueMicroTask(function () { return controller.validateBinding(binding); }); - }; - binding.validateTarget = target; - target.addEventListener('blur', binding.validateBlurHandler); - } - if (trigger !== validate_trigger_1.validateTrigger.manual) { - binding.standardUpdateTarget = binding.updateTarget; - // tslint:disable-next-line:only-arrow-functions - // tslint:disable-next-line:space-before-function-paren - binding.updateTarget = function (value) { - this.standardUpdateTarget(value); - this.validationController.resetBinding(this); - }; - } - }; - ValidateBindingBehaviorBase.prototype.unbind = function (binding) { - // reset the binding to it's original state. - if (binding.vbbUpdateSource) { - binding.updateSource = binding.vbbUpdateSource; - binding.vbbUpdateSource = null; - } - if (binding.standardUpdateTarget) { - binding.updateTarget = binding.standardUpdateTarget; - binding.standardUpdateTarget = null; - } - if (binding.validateBlurHandler) { - binding.validateTarget.removeEventListener('blur', binding.validateBlurHandler); - binding.validateBlurHandler = null; - binding.validateTarget = null; - } - binding.validationController.unregisterBinding(binding); - binding.validationController = null; - }; - return ValidateBindingBehaviorBase; - }()); - exports.ValidateBindingBehaviorBase = ValidateBindingBehaviorBase; -}); diff --git a/dist/amd/validate-binding-behavior.d.ts b/dist/amd/validate-binding-behavior.d.ts deleted file mode 100644 index 08b5d9e0..00000000 --- a/dist/amd/validate-binding-behavior.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { TaskQueue } from 'aurelia-task-queue'; -import { ValidationController } from './validation-controller'; -import { validateTrigger } from './validate-trigger'; -import { ValidateBindingBehaviorBase } from './validate-binding-behavior-base'; -/** - * Binding behavior. Indicates the bound property should be validated - * when the validate trigger specified by the associated controller's - * validateTrigger property occurs. - */ -export declare class ValidateBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(controller: ValidationController): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property will be validated - * manually, by calling controller.validate(). No automatic validation - * triggered by data-entry or blur will occur. - */ -export declare class ValidateManuallyBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs. - */ -export declare class ValidateOnBlurBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element is changed by the user, causing a change - * to the model. - */ -export declare class ValidateOnChangeBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs or is changed by the user, causing - * a change to the model. - */ -export declare class ValidateOnChangeOrBlurBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} diff --git a/dist/amd/validate-binding-behavior.js b/dist/amd/validate-binding-behavior.js deleted file mode 100644 index 5050f5be..00000000 --- a/dist/amd/validate-binding-behavior.js +++ /dev/null @@ -1,98 +0,0 @@ -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -define(["require", "exports", "aurelia-task-queue", "./validate-trigger", "./validate-binding-behavior-base"], function (require, exports, aurelia_task_queue_1, validate_trigger_1, validate_binding_behavior_base_1) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - /** - * Binding behavior. Indicates the bound property should be validated - * when the validate trigger specified by the associated controller's - * validateTrigger property occurs. - */ - var ValidateBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateBindingBehavior, _super); - function ValidateBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateBindingBehavior.prototype.getValidateTrigger = function (controller) { - return controller.validateTrigger; - }; - ValidateBindingBehavior.inject = [aurelia_task_queue_1.TaskQueue]; - return ValidateBindingBehavior; - }(validate_binding_behavior_base_1.ValidateBindingBehaviorBase)); - exports.ValidateBindingBehavior = ValidateBindingBehavior; - /** - * Binding behavior. Indicates the bound property will be validated - * manually, by calling controller.validate(). No automatic validation - * triggered by data-entry or blur will occur. - */ - var ValidateManuallyBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateManuallyBindingBehavior, _super); - function ValidateManuallyBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateManuallyBindingBehavior.prototype.getValidateTrigger = function () { - return validate_trigger_1.validateTrigger.manual; - }; - ValidateManuallyBindingBehavior.inject = [aurelia_task_queue_1.TaskQueue]; - return ValidateManuallyBindingBehavior; - }(validate_binding_behavior_base_1.ValidateBindingBehaviorBase)); - exports.ValidateManuallyBindingBehavior = ValidateManuallyBindingBehavior; - /** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs. - */ - var ValidateOnBlurBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateOnBlurBindingBehavior, _super); - function ValidateOnBlurBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateOnBlurBindingBehavior.prototype.getValidateTrigger = function () { - return validate_trigger_1.validateTrigger.blur; - }; - ValidateOnBlurBindingBehavior.inject = [aurelia_task_queue_1.TaskQueue]; - return ValidateOnBlurBindingBehavior; - }(validate_binding_behavior_base_1.ValidateBindingBehaviorBase)); - exports.ValidateOnBlurBindingBehavior = ValidateOnBlurBindingBehavior; - /** - * Binding behavior. Indicates the bound property should be validated - * when the associated element is changed by the user, causing a change - * to the model. - */ - var ValidateOnChangeBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateOnChangeBindingBehavior, _super); - function ValidateOnChangeBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateOnChangeBindingBehavior.prototype.getValidateTrigger = function () { - return validate_trigger_1.validateTrigger.change; - }; - ValidateOnChangeBindingBehavior.inject = [aurelia_task_queue_1.TaskQueue]; - return ValidateOnChangeBindingBehavior; - }(validate_binding_behavior_base_1.ValidateBindingBehaviorBase)); - exports.ValidateOnChangeBindingBehavior = ValidateOnChangeBindingBehavior; - /** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs or is changed by the user, causing - * a change to the model. - */ - var ValidateOnChangeOrBlurBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateOnChangeOrBlurBindingBehavior, _super); - function ValidateOnChangeOrBlurBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateOnChangeOrBlurBindingBehavior.prototype.getValidateTrigger = function () { - return validate_trigger_1.validateTrigger.changeOrBlur; - }; - ValidateOnChangeOrBlurBindingBehavior.inject = [aurelia_task_queue_1.TaskQueue]; - return ValidateOnChangeOrBlurBindingBehavior; - }(validate_binding_behavior_base_1.ValidateBindingBehaviorBase)); - exports.ValidateOnChangeOrBlurBindingBehavior = ValidateOnChangeOrBlurBindingBehavior; -}); diff --git a/dist/amd/validate-event.d.ts b/dist/amd/validate-event.d.ts deleted file mode 100644 index 0fbacbb7..00000000 --- a/dist/amd/validate-event.d.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { ValidateResult } from './validate-result'; -import { ValidateInstruction } from './validate-instruction'; -import { ControllerValidateResult } from './controller-validate-result'; -export declare class ValidateEvent { - /** - * The type of validate event. Either "validate" or "reset". - */ - readonly type: 'validate' | 'reset'; - /** - * The controller's current array of errors. For an array containing both - * failed rules and passed rules, use the "results" property. - */ - readonly errors: ValidateResult[]; - /** - * The controller's current array of validate results. This - * includes both passed rules and failed rules. For an array of only failed rules, - * use the "errors" property. - */ - readonly results: ValidateResult[]; - /** - * The instruction passed to the "validate" or "reset" event. Will be null when - * the controller's validate/reset method was called with no instruction argument. - */ - readonly instruction: ValidateInstruction | null; - /** - * In events with type === "validate", this property will contain the result - * of validating the instruction (see "instruction" property). Use the controllerValidateResult - * to access the validate results specific to the call to "validate" - * (as opposed to using the "results" and "errors" properties to access the controller's entire - * set of results/errors). - */ - readonly controllerValidateResult: ControllerValidateResult | null; - constructor( - /** - * The type of validate event. Either "validate" or "reset". - */ - type: 'validate' | 'reset', - /** - * The controller's current array of errors. For an array containing both - * failed rules and passed rules, use the "results" property. - */ - errors: ValidateResult[], - /** - * The controller's current array of validate results. This - * includes both passed rules and failed rules. For an array of only failed rules, - * use the "errors" property. - */ - results: ValidateResult[], - /** - * The instruction passed to the "validate" or "reset" event. Will be null when - * the controller's validate/reset method was called with no instruction argument. - */ - instruction: ValidateInstruction | null, - /** - * In events with type === "validate", this property will contain the result - * of validating the instruction (see "instruction" property). Use the controllerValidateResult - * to access the validate results specific to the call to "validate" - * (as opposed to using the "results" and "errors" properties to access the controller's entire - * set of results/errors). - */ - controllerValidateResult: ControllerValidateResult | null); -} diff --git a/dist/amd/validate-event.js b/dist/amd/validate-event.js deleted file mode 100644 index 98a1d8f9..00000000 --- a/dist/amd/validate-event.js +++ /dev/null @@ -1,43 +0,0 @@ -define(["require", "exports"], function (require, exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - var ValidateEvent = /** @class */ (function () { - function ValidateEvent( - /** - * The type of validate event. Either "validate" or "reset". - */ - type, - /** - * The controller's current array of errors. For an array containing both - * failed rules and passed rules, use the "results" property. - */ - errors, - /** - * The controller's current array of validate results. This - * includes both passed rules and failed rules. For an array of only failed rules, - * use the "errors" property. - */ - results, - /** - * The instruction passed to the "validate" or "reset" event. Will be null when - * the controller's validate/reset method was called with no instruction argument. - */ - instruction, - /** - * In events with type === "validate", this property will contain the result - * of validating the instruction (see "instruction" property). Use the controllerValidateResult - * to access the validate results specific to the call to "validate" - * (as opposed to using the "results" and "errors" properties to access the controller's entire - * set of results/errors). - */ - controllerValidateResult) { - this.type = type; - this.errors = errors; - this.results = results; - this.instruction = instruction; - this.controllerValidateResult = controllerValidateResult; - } - return ValidateEvent; - }()); - exports.ValidateEvent = ValidateEvent; -}); diff --git a/dist/amd/validate-instruction.d.ts b/dist/amd/validate-instruction.d.ts deleted file mode 100644 index 2f792a70..00000000 --- a/dist/amd/validate-instruction.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Instructions for the validation controller's validate method. - */ -export interface ValidateInstruction { - /** - * The object to validate. - */ - object: any; - /** - * The property to validate. Optional. - */ - propertyName?: any; - /** - * The rules to validate. Optional. - */ - rules?: any; -} diff --git a/dist/amd/validate-instruction.js b/dist/amd/validate-instruction.js deleted file mode 100644 index 2ae92b6a..00000000 --- a/dist/amd/validate-instruction.js +++ /dev/null @@ -1,4 +0,0 @@ -define(["require", "exports"], function (require, exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); -}); diff --git a/dist/amd/validate-result.js b/dist/amd/validate-result.js deleted file mode 100644 index 500f9bdb..00000000 --- a/dist/amd/validate-result.js +++ /dev/null @@ -1,30 +0,0 @@ -define(["require", "exports"], function (require, exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - /** - * The result of validating an individual validation rule. - */ - var ValidateResult = /** @class */ (function () { - /** - * @param rule The rule associated with the result. Validator implementation specific. - * @param object The object that was validated. - * @param propertyName The name of the property that was validated. - * @param error The error, if the result is a validation error. - */ - function ValidateResult(rule, object, propertyName, valid, message) { - if (message === void 0) { message = null; } - this.rule = rule; - this.object = object; - this.propertyName = propertyName; - this.valid = valid; - this.message = message; - this.id = ValidateResult.nextId++; - } - ValidateResult.prototype.toString = function () { - return this.valid ? 'Valid.' : this.message; - }; - ValidateResult.nextId = 0; - return ValidateResult; - }()); - exports.ValidateResult = ValidateResult; -}); diff --git a/dist/amd/validate-trigger.js b/dist/amd/validate-trigger.js deleted file mode 100644 index 04759b85..00000000 --- a/dist/amd/validate-trigger.js +++ /dev/null @@ -1,28 +0,0 @@ -define(["require", "exports"], function (require, exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - /** - * Validation triggers. - */ - var validateTrigger; - (function (validateTrigger) { - /** - * Manual validation. Use the controller's `validate()` and `reset()` methods - * to validate all bindings. - */ - validateTrigger[validateTrigger["manual"] = 0] = "manual"; - /** - * Validate the binding when the binding's target element fires a DOM "blur" event. - */ - validateTrigger[validateTrigger["blur"] = 1] = "blur"; - /** - * Validate the binding when it updates the model due to a change in the view. - */ - validateTrigger[validateTrigger["change"] = 2] = "change"; - /** - * Validate the binding when the binding's target element fires a DOM "blur" event and - * when it updates the model due to a change in the view. - */ - validateTrigger[validateTrigger["changeOrBlur"] = 3] = "changeOrBlur"; - })(validateTrigger = exports.validateTrigger || (exports.validateTrigger = {})); -}); diff --git a/dist/amd/validation-controller-factory.d.ts b/dist/amd/validation-controller-factory.d.ts deleted file mode 100644 index 2c51999e..00000000 --- a/dist/amd/validation-controller-factory.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Container } from 'aurelia-dependency-injection'; -import { ValidationController } from './validation-controller'; -import { Validator } from './validator'; -/** - * Creates ValidationController instances. - */ -export declare class ValidationControllerFactory { - private container; - static get(container: Container): ValidationControllerFactory; - constructor(container: Container); - /** - * Creates a new controller instance. - */ - create(validator?: Validator): ValidationController; - /** - * Creates a new controller and registers it in the current element's container so that it's - * available to the validate binding behavior and renderers. - */ - createForCurrentScope(validator?: Validator): ValidationController; -} diff --git a/dist/amd/validation-controller-factory.js b/dist/amd/validation-controller-factory.js deleted file mode 100644 index a5a1380f..00000000 --- a/dist/amd/validation-controller-factory.js +++ /dev/null @@ -1,37 +0,0 @@ -define(["require", "exports", "./validation-controller", "./validator", "./property-accessor-parser"], function (require, exports, validation_controller_1, validator_1, property_accessor_parser_1) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - /** - * Creates ValidationController instances. - */ - var ValidationControllerFactory = /** @class */ (function () { - function ValidationControllerFactory(container) { - this.container = container; - } - ValidationControllerFactory.get = function (container) { - return new ValidationControllerFactory(container); - }; - /** - * Creates a new controller instance. - */ - ValidationControllerFactory.prototype.create = function (validator) { - if (!validator) { - validator = this.container.get(validator_1.Validator); - } - var propertyParser = this.container.get(property_accessor_parser_1.PropertyAccessorParser); - return new validation_controller_1.ValidationController(validator, propertyParser); - }; - /** - * Creates a new controller and registers it in the current element's container so that it's - * available to the validate binding behavior and renderers. - */ - ValidationControllerFactory.prototype.createForCurrentScope = function (validator) { - var controller = this.create(validator); - this.container.registerInstance(validation_controller_1.ValidationController, controller); - return controller; - }; - return ValidationControllerFactory; - }()); - exports.ValidationControllerFactory = ValidationControllerFactory; - ValidationControllerFactory['protocol:aurelia:resolver'] = true; -}); diff --git a/dist/amd/validation-controller.js b/dist/amd/validation-controller.js deleted file mode 100644 index be344ba1..00000000 --- a/dist/amd/validation-controller.js +++ /dev/null @@ -1,411 +0,0 @@ -define(["require", "exports", "./validator", "./validate-trigger", "./property-info", "./validate-result", "./property-accessor-parser", "./validate-event"], function (require, exports, validator_1, validate_trigger_1, property_info_1, validate_result_1, property_accessor_parser_1, validate_event_1) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - /** - * Orchestrates validation. - * Manages a set of bindings, renderers and objects. - * Exposes the current list of validation results for binding purposes. - */ - var ValidationController = /** @class */ (function () { - function ValidationController(validator, propertyParser) { - this.validator = validator; - this.propertyParser = propertyParser; - // Registered bindings (via the validate binding behavior) - this.bindings = new Map(); - // Renderers that have been added to the controller instance. - this.renderers = []; - /** - * Validation results that have been rendered by the controller. - */ - this.results = []; - /** - * Validation errors that have been rendered by the controller. - */ - this.errors = []; - /** - * Whether the controller is currently validating. - */ - this.validating = false; - // Elements related to validation results that have been rendered. - this.elements = new Map(); - // Objects that have been added to the controller instance (entity-style validation). - this.objects = new Map(); - /** - * The trigger that will invoke automatic validation of a property used in a binding. - */ - this.validateTrigger = validate_trigger_1.validateTrigger.blur; - // Promise that resolves when validation has completed. - this.finishValidating = Promise.resolve(); - this.eventCallbacks = []; - } - /** - * Subscribe to controller validate and reset events. These events occur when the - * controller's "validate"" and "reset" methods are called. - * @param callback The callback to be invoked when the controller validates or resets. - */ - ValidationController.prototype.subscribe = function (callback) { - var _this = this; - this.eventCallbacks.push(callback); - return { - dispose: function () { - var index = _this.eventCallbacks.indexOf(callback); - if (index === -1) { - return; - } - _this.eventCallbacks.splice(index, 1); - } - }; - }; - /** - * Adds an object to the set of objects that should be validated when validate is called. - * @param object The object. - * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. - */ - ValidationController.prototype.addObject = function (object, rules) { - this.objects.set(object, rules); - }; - /** - * Removes an object from the set of objects that should be validated when validate is called. - * @param object The object. - */ - ValidationController.prototype.removeObject = function (object) { - this.objects.delete(object); - this.processResultDelta('reset', this.results.filter(function (result) { return result.object === object; }), []); - }; - /** - * Adds and renders an error. - */ - ValidationController.prototype.addError = function (message, object, propertyName) { - if (propertyName === void 0) { propertyName = null; } - var resolvedPropertyName; - if (propertyName === null) { - resolvedPropertyName = propertyName; - } - else { - resolvedPropertyName = this.propertyParser.parse(propertyName); - } - var result = new validate_result_1.ValidateResult({ __manuallyAdded__: true }, object, resolvedPropertyName, false, message); - this.processResultDelta('validate', [], [result]); - return result; - }; - /** - * Removes and unrenders an error. - */ - ValidationController.prototype.removeError = function (result) { - if (this.results.indexOf(result) !== -1) { - this.processResultDelta('reset', [result], []); - } - }; - /** - * Adds a renderer. - * @param renderer The renderer. - */ - ValidationController.prototype.addRenderer = function (renderer) { - var _this = this; - this.renderers.push(renderer); - renderer.render({ - kind: 'validate', - render: this.results.map(function (result) { return ({ result: result, elements: _this.elements.get(result) }); }), - unrender: [] - }); - }; - /** - * Removes a renderer. - * @param renderer The renderer. - */ - ValidationController.prototype.removeRenderer = function (renderer) { - var _this = this; - this.renderers.splice(this.renderers.indexOf(renderer), 1); - renderer.render({ - kind: 'reset', - render: [], - unrender: this.results.map(function (result) { return ({ result: result, elements: _this.elements.get(result) }); }) - }); - }; - /** - * Registers a binding with the controller. - * @param binding The binding instance. - * @param target The DOM element. - * @param rules (optional) rules associated with the binding. Validator implementation specific. - */ - ValidationController.prototype.registerBinding = function (binding, target, rules) { - this.bindings.set(binding, { target: target, rules: rules, propertyInfo: null }); - }; - /** - * Unregisters a binding with the controller. - * @param binding The binding instance. - */ - ValidationController.prototype.unregisterBinding = function (binding) { - this.resetBinding(binding); - this.bindings.delete(binding); - }; - /** - * Interprets the instruction and returns a predicate that will identify - * relevant results in the list of rendered validation results. - */ - ValidationController.prototype.getInstructionPredicate = function (instruction) { - var _this = this; - if (instruction) { - var object_1 = instruction.object, propertyName_1 = instruction.propertyName, rules_1 = instruction.rules; - var predicate_1; - if (instruction.propertyName) { - predicate_1 = function (x) { return x.object === object_1 && x.propertyName === propertyName_1; }; - } - else { - predicate_1 = function (x) { return x.object === object_1; }; - } - if (rules_1) { - return function (x) { return predicate_1(x) && _this.validator.ruleExists(rules_1, x.rule); }; - } - return predicate_1; - } - else { - return function () { return true; }; - } - }; - /** - * Validates and renders results. - * @param instruction Optional. Instructions on what to validate. If undefined, all - * objects and bindings will be validated. - */ - ValidationController.prototype.validate = function (instruction) { - var _this = this; - // Get a function that will process the validation instruction. - var execute; - if (instruction) { - // tslint:disable-next-line:prefer-const - var object_2 = instruction.object, propertyName_2 = instruction.propertyName, rules_2 = instruction.rules; - // if rules were not specified, check the object map. - rules_2 = rules_2 || this.objects.get(object_2); - // property specified? - if (instruction.propertyName === undefined) { - // validate the specified object. - execute = function () { return _this.validator.validateObject(object_2, rules_2); }; - } - else { - // validate the specified property. - execute = function () { return _this.validator.validateProperty(object_2, propertyName_2, rules_2); }; - } - } - else { - // validate all objects and bindings. - execute = function () { - var promises = []; - for (var _i = 0, _a = Array.from(_this.objects); _i < _a.length; _i++) { - var _b = _a[_i], object = _b[0], rules = _b[1]; - promises.push(_this.validator.validateObject(object, rules)); - } - for (var _c = 0, _d = Array.from(_this.bindings); _c < _d.length; _c++) { - var _e = _d[_c], binding = _e[0], rules = _e[1].rules; - var propertyInfo = property_info_1.getPropertyInfo(binding.sourceExpression, binding.source); - if (!propertyInfo || _this.objects.has(propertyInfo.object)) { - continue; - } - promises.push(_this.validator.validateProperty(propertyInfo.object, propertyInfo.propertyName, rules)); - } - return Promise.all(promises).then(function (resultSets) { return resultSets.reduce(function (a, b) { return a.concat(b); }, []); }); - }; - } - // Wait for any existing validation to finish, execute the instruction, render the results. - this.validating = true; - var returnPromise = this.finishValidating - .then(execute) - .then(function (newResults) { - var predicate = _this.getInstructionPredicate(instruction); - var oldResults = _this.results.filter(predicate); - _this.processResultDelta('validate', oldResults, newResults); - if (returnPromise === _this.finishValidating) { - _this.validating = false; - } - var result = { - instruction: instruction, - valid: newResults.find(function (x) { return !x.valid; }) === undefined, - results: newResults - }; - _this.invokeCallbacks(instruction, result); - return result; - }) - .catch(function (exception) { - // recover, to enable subsequent calls to validate() - _this.validating = false; - _this.finishValidating = Promise.resolve(); - return Promise.reject(exception); - }); - this.finishValidating = returnPromise; - return returnPromise; - }; - /** - * Resets any rendered validation results (unrenders). - * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results - * will be unrendered. - */ - ValidationController.prototype.reset = function (instruction) { - var predicate = this.getInstructionPredicate(instruction); - var oldResults = this.results.filter(predicate); - this.processResultDelta('reset', oldResults, []); - this.invokeCallbacks(instruction, null); - }; - /** - * Gets the elements associated with an object and propertyName (if any). - */ - ValidationController.prototype.getAssociatedElements = function (_a) { - var object = _a.object, propertyName = _a.propertyName; - var elements = []; - for (var _i = 0, _b = Array.from(this.bindings); _i < _b.length; _i++) { - var _c = _b[_i], binding = _c[0], target = _c[1].target; - var propertyInfo = property_info_1.getPropertyInfo(binding.sourceExpression, binding.source); - if (propertyInfo && propertyInfo.object === object && propertyInfo.propertyName === propertyName) { - elements.push(target); - } - } - return elements; - }; - ValidationController.prototype.processResultDelta = function (kind, oldResults, newResults) { - // prepare the instruction. - var instruction = { - kind: kind, - render: [], - unrender: [] - }; - // create a shallow copy of newResults so we can mutate it without causing side-effects. - newResults = newResults.slice(0); - var _loop_1 = function (oldResult) { - // get the elements associated with the old result. - var elements = this_1.elements.get(oldResult); - // remove the old result from the element map. - this_1.elements.delete(oldResult); - // create the unrender instruction. - instruction.unrender.push({ result: oldResult, elements: elements }); - // determine if there's a corresponding new result for the old result we are unrendering. - var newResultIndex = newResults.findIndex(function (x) { return x.rule === oldResult.rule && x.object === oldResult.object && x.propertyName === oldResult.propertyName; }); - if (newResultIndex === -1) { - // no corresponding new result... simple remove. - this_1.results.splice(this_1.results.indexOf(oldResult), 1); - if (!oldResult.valid) { - this_1.errors.splice(this_1.errors.indexOf(oldResult), 1); - } - } - else { - // there is a corresponding new result... - var newResult = newResults.splice(newResultIndex, 1)[0]; - // get the elements that are associated with the new result. - var elements_1 = this_1.getAssociatedElements(newResult); - this_1.elements.set(newResult, elements_1); - // create a render instruction for the new result. - instruction.render.push({ result: newResult, elements: elements_1 }); - // do an in-place replacement of the old result with the new result. - // this ensures any repeats bound to this.results will not thrash. - this_1.results.splice(this_1.results.indexOf(oldResult), 1, newResult); - if (!oldResult.valid && newResult.valid) { - this_1.errors.splice(this_1.errors.indexOf(oldResult), 1); - } - else if (!oldResult.valid && !newResult.valid) { - this_1.errors.splice(this_1.errors.indexOf(oldResult), 1, newResult); - } - else if (!newResult.valid) { - this_1.errors.push(newResult); - } - } - }; - var this_1 = this; - // create unrender instructions from the old results. - for (var _i = 0, oldResults_1 = oldResults; _i < oldResults_1.length; _i++) { - var oldResult = oldResults_1[_i]; - _loop_1(oldResult); - } - // create render instructions from the remaining new results. - for (var _a = 0, newResults_1 = newResults; _a < newResults_1.length; _a++) { - var result = newResults_1[_a]; - var elements = this.getAssociatedElements(result); - instruction.render.push({ result: result, elements: elements }); - this.elements.set(result, elements); - this.results.push(result); - if (!result.valid) { - this.errors.push(result); - } - } - // render. - for (var _b = 0, _c = this.renderers; _b < _c.length; _b++) { - var renderer = _c[_b]; - renderer.render(instruction); - } - }; - /** - * Validates the property associated with a binding. - */ - ValidationController.prototype.validateBinding = function (binding) { - if (!binding.isBound) { - return; - } - var propertyInfo = property_info_1.getPropertyInfo(binding.sourceExpression, binding.source); - var rules; - var registeredBinding = this.bindings.get(binding); - if (registeredBinding) { - rules = registeredBinding.rules; - registeredBinding.propertyInfo = propertyInfo; - } - if (!propertyInfo) { - return; - } - var object = propertyInfo.object, propertyName = propertyInfo.propertyName; - this.validate({ object: object, propertyName: propertyName, rules: rules }); - }; - /** - * Resets the results for a property associated with a binding. - */ - ValidationController.prototype.resetBinding = function (binding) { - var registeredBinding = this.bindings.get(binding); - var propertyInfo = property_info_1.getPropertyInfo(binding.sourceExpression, binding.source); - if (!propertyInfo && registeredBinding) { - propertyInfo = registeredBinding.propertyInfo; - } - if (registeredBinding) { - registeredBinding.propertyInfo = null; - } - if (!propertyInfo) { - return; - } - var object = propertyInfo.object, propertyName = propertyInfo.propertyName; - this.reset({ object: object, propertyName: propertyName }); - }; - /** - * Changes the controller's validateTrigger. - * @param newTrigger The new validateTrigger - */ - ValidationController.prototype.changeTrigger = function (newTrigger) { - this.validateTrigger = newTrigger; - var bindings = Array.from(this.bindings.keys()); - for (var _i = 0, bindings_1 = bindings; _i < bindings_1.length; _i++) { - var binding = bindings_1[_i]; - var source = binding.source; - binding.unbind(); - binding.bind(source); - } - }; - /** - * Revalidates the controller's current set of errors. - */ - ValidationController.prototype.revalidateErrors = function () { - for (var _i = 0, _a = this.errors; _i < _a.length; _i++) { - var _b = _a[_i], object = _b.object, propertyName = _b.propertyName, rule = _b.rule; - if (rule.__manuallyAdded__) { - continue; - } - var rules = [[rule]]; - this.validate({ object: object, propertyName: propertyName, rules: rules }); - } - }; - ValidationController.prototype.invokeCallbacks = function (instruction, result) { - if (this.eventCallbacks.length === 0) { - return; - } - var event = new validate_event_1.ValidateEvent(result ? 'validate' : 'reset', this.errors, this.results, instruction || null, result); - for (var i = 0; i < this.eventCallbacks.length; i++) { - this.eventCallbacks[i](event); - } - }; - ValidationController.inject = [validator_1.Validator, property_accessor_parser_1.PropertyAccessorParser]; - return ValidationController; - }()); - exports.ValidationController = ValidationController; -}); diff --git a/dist/amd/validation-errors-custom-attribute.d.ts b/dist/amd/validation-errors-custom-attribute.d.ts deleted file mode 100644 index 056e08ea..00000000 --- a/dist/amd/validation-errors-custom-attribute.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Lazy } from 'aurelia-dependency-injection'; -import { ValidationController } from './validation-controller'; -import { ValidateResult } from './validate-result'; -import { ValidationRenderer, RenderInstruction } from './validation-renderer'; -export interface RenderedError { - error: ValidateResult; - targets: Element[]; -} -export declare class ValidationErrorsCustomAttribute implements ValidationRenderer { - private boundaryElement; - private controllerAccessor; - static inject(): ({ - new (): Element; - prototype: Element; - } | Lazy)[]; - controller: ValidationController | null; - errors: RenderedError[]; - private errorsInternal; - constructor(boundaryElement: Element, controllerAccessor: () => ValidationController); - sort(): void; - interestingElements(elements: Element[]): Element[]; - render(instruction: RenderInstruction): void; - bind(): void; - unbind(): void; -} diff --git a/dist/amd/validation-errors-custom-attribute.js b/dist/amd/validation-errors-custom-attribute.js deleted file mode 100644 index bd6a1bb3..00000000 --- a/dist/amd/validation-errors-custom-attribute.js +++ /dev/null @@ -1,81 +0,0 @@ -var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -}; -define(["require", "exports", "aurelia-binding", "aurelia-dependency-injection", "aurelia-templating", "./validation-controller", "aurelia-pal"], function (require, exports, aurelia_binding_1, aurelia_dependency_injection_1, aurelia_templating_1, validation_controller_1, aurelia_pal_1) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - var ValidationErrorsCustomAttribute = /** @class */ (function () { - function ValidationErrorsCustomAttribute(boundaryElement, controllerAccessor) { - this.boundaryElement = boundaryElement; - this.controllerAccessor = controllerAccessor; - this.controller = null; - this.errors = []; - this.errorsInternal = []; - } - ValidationErrorsCustomAttribute.inject = function () { return [aurelia_pal_1.DOM.Element, aurelia_dependency_injection_1.Lazy.of(validation_controller_1.ValidationController)]; }; - ValidationErrorsCustomAttribute.prototype.sort = function () { - this.errorsInternal.sort(function (a, b) { - if (a.targets[0] === b.targets[0]) { - return 0; - } - // tslint:disable-next-line:no-bitwise - return a.targets[0].compareDocumentPosition(b.targets[0]) & 2 ? 1 : -1; - }); - }; - ValidationErrorsCustomAttribute.prototype.interestingElements = function (elements) { - var _this = this; - return elements.filter(function (e) { return _this.boundaryElement.contains(e); }); - }; - ValidationErrorsCustomAttribute.prototype.render = function (instruction) { - var _loop_1 = function (result) { - var index = this_1.errorsInternal.findIndex(function (x) { return x.error === result; }); - if (index !== -1) { - this_1.errorsInternal.splice(index, 1); - } - }; - var this_1 = this; - for (var _i = 0, _a = instruction.unrender; _i < _a.length; _i++) { - var result = _a[_i].result; - _loop_1(result); - } - for (var _b = 0, _c = instruction.render; _b < _c.length; _b++) { - var _d = _c[_b], result = _d.result, elements = _d.elements; - if (result.valid) { - continue; - } - var targets = this.interestingElements(elements); - if (targets.length) { - this.errorsInternal.push({ error: result, targets: targets }); - } - } - this.sort(); - this.errors = this.errorsInternal; - }; - ValidationErrorsCustomAttribute.prototype.bind = function () { - if (!this.controller) { - this.controller = this.controllerAccessor(); - } - // this will call render() with the side-effect of updating this.errors - this.controller.addRenderer(this); - }; - ValidationErrorsCustomAttribute.prototype.unbind = function () { - if (this.controller) { - this.controller.removeRenderer(this); - } - }; - __decorate([ - aurelia_templating_1.bindable({ defaultBindingMode: aurelia_binding_1.bindingMode.oneWay }) - ], ValidationErrorsCustomAttribute.prototype, "controller", void 0); - __decorate([ - aurelia_templating_1.bindable({ primaryProperty: true, defaultBindingMode: aurelia_binding_1.bindingMode.twoWay }) - ], ValidationErrorsCustomAttribute.prototype, "errors", void 0); - ValidationErrorsCustomAttribute = __decorate([ - aurelia_templating_1.customAttribute('validation-errors') - ], ValidationErrorsCustomAttribute); - return ValidationErrorsCustomAttribute; - }()); - exports.ValidationErrorsCustomAttribute = ValidationErrorsCustomAttribute; -}); diff --git a/dist/amd/validation-renderer-custom-attribute.d.ts b/dist/amd/validation-renderer-custom-attribute.d.ts deleted file mode 100644 index 9f48614e..00000000 --- a/dist/amd/validation-renderer-custom-attribute.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export declare class ValidationRendererCustomAttribute { - private container; - private controller; - private value; - private renderer; - created(view: any): void; - bind(): void; - unbind(): void; -} diff --git a/dist/amd/validation-renderer-custom-attribute.js b/dist/amd/validation-renderer-custom-attribute.js deleted file mode 100644 index b9b5d782..00000000 --- a/dist/amd/validation-renderer-custom-attribute.js +++ /dev/null @@ -1,23 +0,0 @@ -define(["require", "exports", "./validation-controller"], function (require, exports, validation_controller_1) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - var ValidationRendererCustomAttribute = /** @class */ (function () { - function ValidationRendererCustomAttribute() { - } - ValidationRendererCustomAttribute.prototype.created = function (view) { - this.container = view.container; - }; - ValidationRendererCustomAttribute.prototype.bind = function () { - this.controller = this.container.get(validation_controller_1.ValidationController); - this.renderer = this.container.get(this.value); - this.controller.addRenderer(this.renderer); - }; - ValidationRendererCustomAttribute.prototype.unbind = function () { - this.controller.removeRenderer(this.renderer); - this.controller = null; - this.renderer = null; - }; - return ValidationRendererCustomAttribute; - }()); - exports.ValidationRendererCustomAttribute = ValidationRendererCustomAttribute; -}); diff --git a/dist/amd/validation-renderer.d.ts b/dist/amd/validation-renderer.d.ts deleted file mode 100644 index eb430d9d..00000000 --- a/dist/amd/validation-renderer.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { ValidateResult } from './validate-result'; -/** - * A result to render (or unrender) and the associated elements (if any) - */ -export interface ResultInstruction { - /** - * The validation result. - */ - result: ValidateResult; - /** - * The associated elements (if any). - */ - elements: Element[]; -} -/** - * Defines which validation results to render and which validation results to unrender. - */ -export interface RenderInstruction { - /** - * The "kind" of render instruction. Either 'validate' or 'reset'. - */ - kind: 'validate' | 'reset'; - /** - * The results to render. - */ - render: ResultInstruction[]; - /** - * The results to unrender. - */ - unrender: ResultInstruction[]; -} -/** - * Renders validation results. - */ -export interface ValidationRenderer { - /** - * Render the validation results. - * @param instruction The render instruction. Defines which results to render and which - * results to unrender. - */ - render(instruction: RenderInstruction): void; -} diff --git a/dist/amd/validation-renderer.js b/dist/amd/validation-renderer.js deleted file mode 100644 index 2ae92b6a..00000000 --- a/dist/amd/validation-renderer.js +++ /dev/null @@ -1,4 +0,0 @@ -define(["require", "exports"], function (require, exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); -}); diff --git a/dist/amd/validator.d.ts b/dist/amd/validator.d.ts deleted file mode 100644 index 82c045e8..00000000 --- a/dist/amd/validator.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ValidateResult } from './validate-result'; -/** - * Validates objects and properties. - */ -export declare abstract class Validator { - /** - * Validates the specified property. - * @param object The object to validate. - * @param propertyName The name of the property to validate. - * @param rules Optional. If unspecified, the implementation should lookup the rules for the - * specified object. This may not be possible for all implementations of this interface. - */ - abstract validateProperty(object: any, propertyName: string, rules?: any): Promise; - /** - * Validates all rules for specified object and it's properties. - * @param object The object to validate. - * @param rules Optional. If unspecified, the implementation should lookup the rules for the - * specified object. This may not be possible for all implementations of this interface. - */ - abstract validateObject(object: any, rules?: any): Promise; - /** - * Determines whether a rule exists in a set of rules. - * @param rules The rules to search. - * @parem rule The rule to find. - */ - abstract ruleExists(rules: any, rule: any): boolean; -} diff --git a/dist/amd/validator.js b/dist/amd/validator.js deleted file mode 100644 index c0f3bad3..00000000 --- a/dist/amd/validator.js +++ /dev/null @@ -1,13 +0,0 @@ -define(["require", "exports"], function (require, exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - /** - * Validates objects and properties. - */ - var Validator = /** @class */ (function () { - function Validator() { - } - return Validator; - }()); - exports.Validator = Validator; -}); diff --git a/dist/commonjs/aurelia-validation.d.ts b/dist/commonjs/aurelia-validation.d.ts deleted file mode 100644 index d744ccfb..00000000 --- a/dist/commonjs/aurelia-validation.d.ts +++ /dev/null @@ -1,46 +0,0 @@ -export * from './controller-validate-result'; -export * from './get-target-dom-element'; -export * from './property-info'; -export * from './property-accessor-parser'; -export * from './validate-binding-behavior'; -export * from './validate-event'; -export * from './validate-instruction'; -export * from './validate-result'; -export * from './validate-trigger'; -export * from './validation-controller'; -export * from './validation-controller-factory'; -export * from './validation-errors-custom-attribute'; -export * from './validation-renderer-custom-attribute'; -export * from './validation-renderer'; -export * from './validator'; -export * from './implementation/rule'; -export * from './implementation/rules'; -export * from './implementation/standard-validator'; -export * from './implementation/validation-messages'; -export * from './implementation/validation-message-parser'; -export * from './implementation/validation-rules'; -import { Container } from 'aurelia-dependency-injection'; -import { Validator } from './validator'; -/** - * Aurelia Validation Configuration API - */ -export declare class AureliaValidationConfiguration { - private validatorType; - /** - * Use a custom Validator implementation. - */ - customValidator(type: { - new (...args: any[]): Validator; - }): void; - /** - * Applies the configuration. - */ - apply(container: Container): void; -} -/** - * Configures the plugin. - */ -export declare function configure(frameworkConfig: { - container: Container; - globalResources?: (...resources: string[]) => any; -}, callback?: (config: AureliaValidationConfiguration) => void): void; diff --git a/dist/commonjs/aurelia-validation.js b/dist/commonjs/aurelia-validation.js index 32d3c103..ca92994d 100644 --- a/dist/commonjs/aurelia-validation.js +++ b/dist/commonjs/aurelia-validation.js @@ -1,74 +1,1802 @@ -"use strict"; -// Exports -function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var aureliaPal = require('aurelia-pal'); +var aureliaBinding = require('aurelia-binding'); +var aureliaDependencyInjection = require('aurelia-dependency-injection'); +var aureliaTaskQueue = require('aurelia-task-queue'); +var aureliaTemplating = require('aurelia-templating'); +var aureliaFramework = require('aurelia-framework'); +var LogManager = require('aurelia-logging'); + +/** + * Gets the DOM element associated with the data-binding. Most of the time it's + * the binding.target but sometimes binding.target is an aurelia custom element, + * or custom attribute which is a javascript "class" instance, so we need to use + * the controller's container to retrieve the actual DOM element. + */ +function getTargetDOMElement(binding, view) { + var target = binding.target; + // DOM element + if (target instanceof Element) { + return target; + } + // custom element or custom attribute + // tslint:disable-next-line:prefer-const + for (var i = 0, ii = view.controllers.length; i < ii; i++) { + var controller = view.controllers[i]; + if (controller.viewModel === target) { + var element = controller.container.get(aureliaPal.DOM.Element); + if (element) { + return element; + } + throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\"."); + } + } + throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\"."); } -Object.defineProperty(exports, "__esModule", { value: true }); -__export(require("./get-target-dom-element")); -__export(require("./property-info")); -__export(require("./property-accessor-parser")); -__export(require("./validate-binding-behavior")); -__export(require("./validate-event")); -__export(require("./validate-result")); -__export(require("./validate-trigger")); -__export(require("./validation-controller")); -__export(require("./validation-controller-factory")); -__export(require("./validation-errors-custom-attribute")); -__export(require("./validation-renderer-custom-attribute")); -__export(require("./validator")); -__export(require("./implementation/rules")); -__export(require("./implementation/standard-validator")); -__export(require("./implementation/validation-messages")); -__export(require("./implementation/validation-message-parser")); -__export(require("./implementation/validation-rules")); -// Configuration -var aurelia_pal_1 = require("aurelia-pal"); -var validator_1 = require("./validator"); -var standard_validator_1 = require("./implementation/standard-validator"); -var validation_message_parser_1 = require("./implementation/validation-message-parser"); -var property_accessor_parser_1 = require("./property-accessor-parser"); -var validation_rules_1 = require("./implementation/validation-rules"); -/** - * Aurelia Validation Configuration API - */ -var AureliaValidationConfiguration = /** @class */ (function () { - function AureliaValidationConfiguration() { - this.validatorType = standard_validator_1.StandardValidator; - } - /** - * Use a custom Validator implementation. - */ - AureliaValidationConfiguration.prototype.customValidator = function (type) { - this.validatorType = type; - }; - /** - * Applies the configuration. - */ - AureliaValidationConfiguration.prototype.apply = function (container) { - var validator = container.get(this.validatorType); - container.registerInstance(validator_1.Validator, validator); - }; - return AureliaValidationConfiguration; + +function getObject(expression, objectExpression, source) { + var value = objectExpression.evaluate(source, null); + if (value === null || value === undefined || value instanceof Object) { + return value; + } + // tslint:disable-next-line:max-line-length + throw new Error("The '" + objectExpression + "' part of '" + expression + "' evaluates to " + value + " instead of an object, null or undefined."); +} +/** + * Retrieves the object and property name for the specified expression. + * @param expression The expression + * @param source The scope + */ +function getPropertyInfo(expression, source) { + var originalExpression = expression; + while (expression instanceof aureliaBinding.BindingBehavior || expression instanceof aureliaBinding.ValueConverter) { + expression = expression.expression; + } + var object; + var propertyName; + if (expression instanceof aureliaBinding.AccessScope) { + object = aureliaBinding.getContextFor(expression.name, source, expression.ancestor); + propertyName = expression.name; + } + else if (expression instanceof aureliaBinding.AccessMember) { + object = getObject(originalExpression, expression.object, source); + propertyName = expression.name; + } + else if (expression instanceof aureliaBinding.AccessKeyed) { + object = getObject(originalExpression, expression.object, source); + propertyName = expression.key.evaluate(source); + } + else { + throw new Error("Expression '" + originalExpression + "' is not compatible with the validate binding-behavior."); + } + if (object === null || object === undefined) { + return null; + } + return { object: object, propertyName: propertyName }; +} + +function isString(value) { + return Object.prototype.toString.call(value) === '[object String]'; +} +function isNumber(value) { + return Object.prototype.toString.call(value) === '[object Number]'; +} + +var PropertyAccessorParser = /** @class */ (function () { + function PropertyAccessorParser(parser) { + this.parser = parser; + } + PropertyAccessorParser.prototype.parse = function (property) { + if (isString(property) || isNumber(property)) { + return property; + } + var accessorText = getAccessorExpression(property.toString()); + var accessor = this.parser.parse(accessorText); + if (accessor instanceof aureliaBinding.AccessScope + || accessor instanceof aureliaBinding.AccessMember && accessor.object instanceof aureliaBinding.AccessScope) { + return accessor.name; + } + throw new Error("Invalid property expression: \"" + accessor + "\""); + }; + PropertyAccessorParser.inject = [aureliaBinding.Parser]; + return PropertyAccessorParser; +}()); +function getAccessorExpression(fn) { + /* tslint:disable:max-line-length */ + var classic = /^function\s*\([$_\w\d]+\)\s*\{(?:\s*"use strict";)?\s*(?:[$_\w\d.['"\]+;]+)?\s*return\s+[$_\w\d]+\.([$_\w\d]+)\s*;?\s*\}$/; + /* tslint:enable:max-line-length */ + var arrow = /^\(?[$_\w\d]+\)?\s*=>\s*[$_\w\d]+\.([$_\w\d]+)$/; + var match = classic.exec(fn) || arrow.exec(fn); + if (match === null) { + throw new Error("Unable to parse accessor function:\n" + fn); + } + return match[1]; +} + +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at http://www.apache.org/licenses/LICENSE-2.0 + +THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED +WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +MERCHANTABLITY OR NON-INFRINGEMENT. + +See the Apache Version 2.0 License for specific language governing permissions +and limitations under the License. +***************************************************************************** */ +/* global Reflect, Promise */ + +var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); +}; + +function __extends(d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} + +function __decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +} + +/** + * Validation triggers. + */ +(function (validateTrigger) { + /** + * Manual validation. Use the controller's `validate()` and `reset()` methods + * to validate all bindings. + */ + validateTrigger[validateTrigger["manual"] = 0] = "manual"; + /** + * Validate the binding when the binding's target element fires a DOM "blur" event. + */ + validateTrigger[validateTrigger["blur"] = 1] = "blur"; + /** + * Validate the binding when it updates the model due to a change in the view. + */ + validateTrigger[validateTrigger["change"] = 2] = "change"; + /** + * Validate the binding when the binding's target element fires a DOM "blur" event and + * when it updates the model due to a change in the view. + */ + validateTrigger[validateTrigger["changeOrBlur"] = 3] = "changeOrBlur"; +})(exports.validateTrigger || (exports.validateTrigger = {})); + +/** + * Validates objects and properties. + */ +var Validator = /** @class */ (function () { + function Validator() { + } + return Validator; }()); -exports.AureliaValidationConfiguration = AureliaValidationConfiguration; -/** - * Configures the plugin. - */ -function configure(frameworkConfig, callback) { - // the fluent rule definition API needs the parser to translate messages - // to interpolation expressions. - var messageParser = frameworkConfig.container.get(validation_message_parser_1.ValidationMessageParser); - var propertyParser = frameworkConfig.container.get(property_accessor_parser_1.PropertyAccessorParser); - validation_rules_1.ValidationRules.initialize(messageParser, propertyParser); - // configure... - var config = new AureliaValidationConfiguration(); - if (callback instanceof Function) { - callback(config); - } - config.apply(frameworkConfig.container); - // globalize the behaviors. - if (frameworkConfig.globalResources) { - frameworkConfig.globalResources(aurelia_pal_1.PLATFORM.moduleName('./validate-binding-behavior'), aurelia_pal_1.PLATFORM.moduleName('./validation-errors-custom-attribute'), aurelia_pal_1.PLATFORM.moduleName('./validation-renderer-custom-attribute')); - } + +/** + * The result of validating an individual validation rule. + */ +var ValidateResult = /** @class */ (function () { + /** + * @param rule The rule associated with the result. Validator implementation specific. + * @param object The object that was validated. + * @param propertyName The name of the property that was validated. + * @param error The error, if the result is a validation error. + */ + function ValidateResult(rule, object, propertyName, valid, message) { + if (message === void 0) { message = null; } + this.rule = rule; + this.object = object; + this.propertyName = propertyName; + this.valid = valid; + this.message = message; + this.id = ValidateResult.nextId++; + } + ValidateResult.prototype.toString = function () { + return this.valid ? 'Valid.' : this.message; + }; + ValidateResult.nextId = 0; + return ValidateResult; +}()); + +var ValidateEvent = /** @class */ (function () { + function ValidateEvent( + /** + * The type of validate event. Either "validate" or "reset". + */ + type, + /** + * The controller's current array of errors. For an array containing both + * failed rules and passed rules, use the "results" property. + */ + errors, + /** + * The controller's current array of validate results. This + * includes both passed rules and failed rules. For an array of only failed rules, + * use the "errors" property. + */ + results, + /** + * The instruction passed to the "validate" or "reset" event. Will be null when + * the controller's validate/reset method was called with no instruction argument. + */ + instruction, + /** + * In events with type === "validate", this property will contain the result + * of validating the instruction (see "instruction" property). Use the controllerValidateResult + * to access the validate results specific to the call to "validate" + * (as opposed to using the "results" and "errors" properties to access the controller's entire + * set of results/errors). + */ + controllerValidateResult) { + this.type = type; + this.errors = errors; + this.results = results; + this.instruction = instruction; + this.controllerValidateResult = controllerValidateResult; + } + return ValidateEvent; +}()); + +/** + * Orchestrates validation. + * Manages a set of bindings, renderers and objects. + * Exposes the current list of validation results for binding purposes. + */ +var ValidationController = /** @class */ (function () { + function ValidationController(validator, propertyParser) { + this.validator = validator; + this.propertyParser = propertyParser; + // Registered bindings (via the validate binding behavior) + this.bindings = new Map(); + // Renderers that have been added to the controller instance. + this.renderers = []; + /** + * Validation results that have been rendered by the controller. + */ + this.results = []; + /** + * Validation errors that have been rendered by the controller. + */ + this.errors = []; + /** + * Whether the controller is currently validating. + */ + this.validating = false; + // Elements related to validation results that have been rendered. + this.elements = new Map(); + // Objects that have been added to the controller instance (entity-style validation). + this.objects = new Map(); + /** + * The trigger that will invoke automatic validation of a property used in a binding. + */ + this.validateTrigger = exports.validateTrigger.blur; + // Promise that resolves when validation has completed. + this.finishValidating = Promise.resolve(); + this.eventCallbacks = []; + } + /** + * Subscribe to controller validate and reset events. These events occur when the + * controller's "validate"" and "reset" methods are called. + * @param callback The callback to be invoked when the controller validates or resets. + */ + ValidationController.prototype.subscribe = function (callback) { + var _this = this; + this.eventCallbacks.push(callback); + return { + dispose: function () { + var index = _this.eventCallbacks.indexOf(callback); + if (index === -1) { + return; + } + _this.eventCallbacks.splice(index, 1); + } + }; + }; + /** + * Adds an object to the set of objects that should be validated when validate is called. + * @param object The object. + * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. + */ + ValidationController.prototype.addObject = function (object, rules) { + this.objects.set(object, rules); + }; + /** + * Removes an object from the set of objects that should be validated when validate is called. + * @param object The object. + */ + ValidationController.prototype.removeObject = function (object) { + this.objects.delete(object); + this.processResultDelta('reset', this.results.filter(function (result) { return result.object === object; }), []); + }; + /** + * Adds and renders an error. + */ + ValidationController.prototype.addError = function (message, object, propertyName) { + if (propertyName === void 0) { propertyName = null; } + var resolvedPropertyName; + if (propertyName === null) { + resolvedPropertyName = propertyName; + } + else { + resolvedPropertyName = this.propertyParser.parse(propertyName); + } + var result = new ValidateResult({ __manuallyAdded__: true }, object, resolvedPropertyName, false, message); + this.processResultDelta('validate', [], [result]); + return result; + }; + /** + * Removes and unrenders an error. + */ + ValidationController.prototype.removeError = function (result) { + if (this.results.indexOf(result) !== -1) { + this.processResultDelta('reset', [result], []); + } + }; + /** + * Adds a renderer. + * @param renderer The renderer. + */ + ValidationController.prototype.addRenderer = function (renderer) { + var _this = this; + this.renderers.push(renderer); + renderer.render({ + kind: 'validate', + render: this.results.map(function (result) { return ({ result: result, elements: _this.elements.get(result) }); }), + unrender: [] + }); + }; + /** + * Removes a renderer. + * @param renderer The renderer. + */ + ValidationController.prototype.removeRenderer = function (renderer) { + var _this = this; + this.renderers.splice(this.renderers.indexOf(renderer), 1); + renderer.render({ + kind: 'reset', + render: [], + unrender: this.results.map(function (result) { return ({ result: result, elements: _this.elements.get(result) }); }) + }); + }; + /** + * Registers a binding with the controller. + * @param binding The binding instance. + * @param target The DOM element. + * @param rules (optional) rules associated with the binding. Validator implementation specific. + */ + ValidationController.prototype.registerBinding = function (binding, target, rules) { + this.bindings.set(binding, { target: target, rules: rules, propertyInfo: null }); + }; + /** + * Unregisters a binding with the controller. + * @param binding The binding instance. + */ + ValidationController.prototype.unregisterBinding = function (binding) { + this.resetBinding(binding); + this.bindings.delete(binding); + }; + /** + * Interprets the instruction and returns a predicate that will identify + * relevant results in the list of rendered validation results. + */ + ValidationController.prototype.getInstructionPredicate = function (instruction) { + var _this = this; + if (instruction) { + var object_1 = instruction.object, propertyName_1 = instruction.propertyName, rules_1 = instruction.rules; + var predicate_1; + if (instruction.propertyName) { + predicate_1 = function (x) { return x.object === object_1 && x.propertyName === propertyName_1; }; + } + else { + predicate_1 = function (x) { return x.object === object_1; }; + } + if (rules_1) { + return function (x) { return predicate_1(x) && _this.validator.ruleExists(rules_1, x.rule); }; + } + return predicate_1; + } + else { + return function () { return true; }; + } + }; + /** + * Validates and renders results. + * @param instruction Optional. Instructions on what to validate. If undefined, all + * objects and bindings will be validated. + */ + ValidationController.prototype.validate = function (instruction) { + var _this = this; + // Get a function that will process the validation instruction. + var execute; + if (instruction) { + // tslint:disable-next-line:prefer-const + var object_2 = instruction.object, propertyName_2 = instruction.propertyName, rules_2 = instruction.rules; + // if rules were not specified, check the object map. + rules_2 = rules_2 || this.objects.get(object_2); + // property specified? + if (instruction.propertyName === undefined) { + // validate the specified object. + execute = function () { return _this.validator.validateObject(object_2, rules_2); }; + } + else { + // validate the specified property. + execute = function () { return _this.validator.validateProperty(object_2, propertyName_2, rules_2); }; + } + } + else { + // validate all objects and bindings. + execute = function () { + var promises = []; + for (var _i = 0, _a = Array.from(_this.objects); _i < _a.length; _i++) { + var _b = _a[_i], object = _b[0], rules = _b[1]; + promises.push(_this.validator.validateObject(object, rules)); + } + for (var _c = 0, _d = Array.from(_this.bindings); _c < _d.length; _c++) { + var _e = _d[_c], binding = _e[0], rules = _e[1].rules; + var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + if (!propertyInfo || _this.objects.has(propertyInfo.object)) { + continue; + } + promises.push(_this.validator.validateProperty(propertyInfo.object, propertyInfo.propertyName, rules)); + } + return Promise.all(promises).then(function (resultSets) { return resultSets.reduce(function (a, b) { return a.concat(b); }, []); }); + }; + } + // Wait for any existing validation to finish, execute the instruction, render the results. + this.validating = true; + var returnPromise = this.finishValidating + .then(execute) + .then(function (newResults) { + var predicate = _this.getInstructionPredicate(instruction); + var oldResults = _this.results.filter(predicate); + _this.processResultDelta('validate', oldResults, newResults); + if (returnPromise === _this.finishValidating) { + _this.validating = false; + } + var result = { + instruction: instruction, + valid: newResults.find(function (x) { return !x.valid; }) === undefined, + results: newResults + }; + _this.invokeCallbacks(instruction, result); + return result; + }) + .catch(function (exception) { + // recover, to enable subsequent calls to validate() + _this.validating = false; + _this.finishValidating = Promise.resolve(); + return Promise.reject(exception); + }); + this.finishValidating = returnPromise; + return returnPromise; + }; + /** + * Resets any rendered validation results (unrenders). + * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results + * will be unrendered. + */ + ValidationController.prototype.reset = function (instruction) { + var predicate = this.getInstructionPredicate(instruction); + var oldResults = this.results.filter(predicate); + this.processResultDelta('reset', oldResults, []); + this.invokeCallbacks(instruction, null); + }; + /** + * Gets the elements associated with an object and propertyName (if any). + */ + ValidationController.prototype.getAssociatedElements = function (_a) { + var object = _a.object, propertyName = _a.propertyName; + var elements = []; + for (var _i = 0, _b = Array.from(this.bindings); _i < _b.length; _i++) { + var _c = _b[_i], binding = _c[0], target = _c[1].target; + var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + if (propertyInfo && propertyInfo.object === object && propertyInfo.propertyName === propertyName) { + elements.push(target); + } + } + return elements; + }; + ValidationController.prototype.processResultDelta = function (kind, oldResults, newResults) { + // prepare the instruction. + var instruction = { + kind: kind, + render: [], + unrender: [] + }; + // create a shallow copy of newResults so we can mutate it without causing side-effects. + newResults = newResults.slice(0); + var _loop_1 = function (oldResult) { + // get the elements associated with the old result. + var elements = this_1.elements.get(oldResult); + // remove the old result from the element map. + this_1.elements.delete(oldResult); + // create the unrender instruction. + instruction.unrender.push({ result: oldResult, elements: elements }); + // determine if there's a corresponding new result for the old result we are unrendering. + var newResultIndex = newResults.findIndex(function (x) { return x.rule === oldResult.rule && x.object === oldResult.object && x.propertyName === oldResult.propertyName; }); + if (newResultIndex === -1) { + // no corresponding new result... simple remove. + this_1.results.splice(this_1.results.indexOf(oldResult), 1); + if (!oldResult.valid) { + this_1.errors.splice(this_1.errors.indexOf(oldResult), 1); + } + } + else { + // there is a corresponding new result... + var newResult = newResults.splice(newResultIndex, 1)[0]; + // get the elements that are associated with the new result. + var elements_1 = this_1.getAssociatedElements(newResult); + this_1.elements.set(newResult, elements_1); + // create a render instruction for the new result. + instruction.render.push({ result: newResult, elements: elements_1 }); + // do an in-place replacement of the old result with the new result. + // this ensures any repeats bound to this.results will not thrash. + this_1.results.splice(this_1.results.indexOf(oldResult), 1, newResult); + if (!oldResult.valid && newResult.valid) { + this_1.errors.splice(this_1.errors.indexOf(oldResult), 1); + } + else if (!oldResult.valid && !newResult.valid) { + this_1.errors.splice(this_1.errors.indexOf(oldResult), 1, newResult); + } + else if (!newResult.valid) { + this_1.errors.push(newResult); + } + } + }; + var this_1 = this; + // create unrender instructions from the old results. + for (var _i = 0, oldResults_1 = oldResults; _i < oldResults_1.length; _i++) { + var oldResult = oldResults_1[_i]; + _loop_1(oldResult); + } + // create render instructions from the remaining new results. + for (var _a = 0, newResults_1 = newResults; _a < newResults_1.length; _a++) { + var result = newResults_1[_a]; + var elements = this.getAssociatedElements(result); + instruction.render.push({ result: result, elements: elements }); + this.elements.set(result, elements); + this.results.push(result); + if (!result.valid) { + this.errors.push(result); + } + } + // render. + for (var _b = 0, _c = this.renderers; _b < _c.length; _b++) { + var renderer = _c[_b]; + renderer.render(instruction); + } + }; + /** + * Validates the property associated with a binding. + */ + ValidationController.prototype.validateBinding = function (binding) { + if (!binding.isBound) { + return; + } + var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + var rules; + var registeredBinding = this.bindings.get(binding); + if (registeredBinding) { + rules = registeredBinding.rules; + registeredBinding.propertyInfo = propertyInfo; + } + if (!propertyInfo) { + return; + } + var object = propertyInfo.object, propertyName = propertyInfo.propertyName; + this.validate({ object: object, propertyName: propertyName, rules: rules }); + }; + /** + * Resets the results for a property associated with a binding. + */ + ValidationController.prototype.resetBinding = function (binding) { + var registeredBinding = this.bindings.get(binding); + var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + if (!propertyInfo && registeredBinding) { + propertyInfo = registeredBinding.propertyInfo; + } + if (registeredBinding) { + registeredBinding.propertyInfo = null; + } + if (!propertyInfo) { + return; + } + var object = propertyInfo.object, propertyName = propertyInfo.propertyName; + this.reset({ object: object, propertyName: propertyName }); + }; + /** + * Changes the controller's validateTrigger. + * @param newTrigger The new validateTrigger + */ + ValidationController.prototype.changeTrigger = function (newTrigger) { + this.validateTrigger = newTrigger; + var bindings = Array.from(this.bindings.keys()); + for (var _i = 0, bindings_1 = bindings; _i < bindings_1.length; _i++) { + var binding = bindings_1[_i]; + var source = binding.source; + binding.unbind(); + binding.bind(source); + } + }; + /** + * Revalidates the controller's current set of errors. + */ + ValidationController.prototype.revalidateErrors = function () { + for (var _i = 0, _a = this.errors; _i < _a.length; _i++) { + var _b = _a[_i], object = _b.object, propertyName = _b.propertyName, rule = _b.rule; + if (rule.__manuallyAdded__) { + continue; + } + var rules = [[rule]]; + this.validate({ object: object, propertyName: propertyName, rules: rules }); + } + }; + ValidationController.prototype.invokeCallbacks = function (instruction, result) { + if (this.eventCallbacks.length === 0) { + return; + } + var event = new ValidateEvent(result ? 'validate' : 'reset', this.errors, this.results, instruction || null, result); + for (var i = 0; i < this.eventCallbacks.length; i++) { + this.eventCallbacks[i](event); + } + }; + ValidationController.inject = [Validator, PropertyAccessorParser]; + return ValidationController; +}()); + +/** + * Binding behavior. Indicates the bound property should be validated. + */ +var ValidateBindingBehaviorBase = /** @class */ (function () { + function ValidateBindingBehaviorBase(taskQueue) { + this.taskQueue = taskQueue; + } + ValidateBindingBehaviorBase.prototype.bind = function (binding, source, rulesOrController, rules) { + var _this = this; + // identify the target element. + var target = getTargetDOMElement(binding, source); + // locate the controller. + var controller; + if (rulesOrController instanceof ValidationController) { + controller = rulesOrController; + } + else { + controller = source.container.get(aureliaDependencyInjection.Optional.of(ValidationController)); + rules = rulesOrController; + } + if (controller === null) { + throw new Error("A ValidationController has not been registered."); + } + controller.registerBinding(binding, target, rules); + binding.validationController = controller; + var trigger = this.getValidateTrigger(controller); + // tslint:disable-next-line:no-bitwise + if (trigger & exports.validateTrigger.change) { + binding.vbbUpdateSource = binding.updateSource; + // tslint:disable-next-line:only-arrow-functions + // tslint:disable-next-line:space-before-function-paren + binding.updateSource = function (value) { + this.vbbUpdateSource(value); + this.validationController.validateBinding(this); + }; + } + // tslint:disable-next-line:no-bitwise + if (trigger & exports.validateTrigger.blur) { + binding.validateBlurHandler = function () { + _this.taskQueue.queueMicroTask(function () { return controller.validateBinding(binding); }); + }; + binding.validateTarget = target; + target.addEventListener('blur', binding.validateBlurHandler); + } + if (trigger !== exports.validateTrigger.manual) { + binding.standardUpdateTarget = binding.updateTarget; + // tslint:disable-next-line:only-arrow-functions + // tslint:disable-next-line:space-before-function-paren + binding.updateTarget = function (value) { + this.standardUpdateTarget(value); + this.validationController.resetBinding(this); + }; + } + }; + ValidateBindingBehaviorBase.prototype.unbind = function (binding) { + // reset the binding to it's original state. + if (binding.vbbUpdateSource) { + binding.updateSource = binding.vbbUpdateSource; + binding.vbbUpdateSource = null; + } + if (binding.standardUpdateTarget) { + binding.updateTarget = binding.standardUpdateTarget; + binding.standardUpdateTarget = null; + } + if (binding.validateBlurHandler) { + binding.validateTarget.removeEventListener('blur', binding.validateBlurHandler); + binding.validateBlurHandler = null; + binding.validateTarget = null; + } + binding.validationController.unregisterBinding(binding); + binding.validationController = null; + }; + return ValidateBindingBehaviorBase; +}()); + +/** + * Binding behavior. Indicates the bound property should be validated + * when the validate trigger specified by the associated controller's + * validateTrigger property occurs. + */ +var ValidateBindingBehavior = /** @class */ (function (_super) { + __extends(ValidateBindingBehavior, _super); + function ValidateBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateBindingBehavior.prototype.getValidateTrigger = function (controller) { + return controller.validateTrigger; + }; + ValidateBindingBehavior.inject = [aureliaTaskQueue.TaskQueue]; + return ValidateBindingBehavior; +}(ValidateBindingBehaviorBase)); +/** + * Binding behavior. Indicates the bound property will be validated + * manually, by calling controller.validate(). No automatic validation + * triggered by data-entry or blur will occur. + */ +var ValidateManuallyBindingBehavior = /** @class */ (function (_super) { + __extends(ValidateManuallyBindingBehavior, _super); + function ValidateManuallyBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateManuallyBindingBehavior.prototype.getValidateTrigger = function () { + return exports.validateTrigger.manual; + }; + ValidateManuallyBindingBehavior.inject = [aureliaTaskQueue.TaskQueue]; + return ValidateManuallyBindingBehavior; +}(ValidateBindingBehaviorBase)); +/** + * Binding behavior. Indicates the bound property should be validated + * when the associated element blurs. + */ +var ValidateOnBlurBindingBehavior = /** @class */ (function (_super) { + __extends(ValidateOnBlurBindingBehavior, _super); + function ValidateOnBlurBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateOnBlurBindingBehavior.prototype.getValidateTrigger = function () { + return exports.validateTrigger.blur; + }; + ValidateOnBlurBindingBehavior.inject = [aureliaTaskQueue.TaskQueue]; + return ValidateOnBlurBindingBehavior; +}(ValidateBindingBehaviorBase)); +/** + * Binding behavior. Indicates the bound property should be validated + * when the associated element is changed by the user, causing a change + * to the model. + */ +var ValidateOnChangeBindingBehavior = /** @class */ (function (_super) { + __extends(ValidateOnChangeBindingBehavior, _super); + function ValidateOnChangeBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateOnChangeBindingBehavior.prototype.getValidateTrigger = function () { + return exports.validateTrigger.change; + }; + ValidateOnChangeBindingBehavior.inject = [aureliaTaskQueue.TaskQueue]; + return ValidateOnChangeBindingBehavior; +}(ValidateBindingBehaviorBase)); +/** + * Binding behavior. Indicates the bound property should be validated + * when the associated element blurs or is changed by the user, causing + * a change to the model. + */ +var ValidateOnChangeOrBlurBindingBehavior = /** @class */ (function (_super) { + __extends(ValidateOnChangeOrBlurBindingBehavior, _super); + function ValidateOnChangeOrBlurBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateOnChangeOrBlurBindingBehavior.prototype.getValidateTrigger = function () { + return exports.validateTrigger.changeOrBlur; + }; + ValidateOnChangeOrBlurBindingBehavior.inject = [aureliaTaskQueue.TaskQueue]; + return ValidateOnChangeOrBlurBindingBehavior; +}(ValidateBindingBehaviorBase)); + +/** + * Creates ValidationController instances. + */ +var ValidationControllerFactory = /** @class */ (function () { + function ValidationControllerFactory(container) { + this.container = container; + } + ValidationControllerFactory.get = function (container) { + return new ValidationControllerFactory(container); + }; + /** + * Creates a new controller instance. + */ + ValidationControllerFactory.prototype.create = function (validator) { + if (!validator) { + validator = this.container.get(Validator); + } + var propertyParser = this.container.get(PropertyAccessorParser); + return new ValidationController(validator, propertyParser); + }; + /** + * Creates a new controller and registers it in the current element's container so that it's + * available to the validate binding behavior and renderers. + */ + ValidationControllerFactory.prototype.createForCurrentScope = function (validator) { + var controller = this.create(validator); + this.container.registerInstance(ValidationController, controller); + return controller; + }; + return ValidationControllerFactory; +}()); +ValidationControllerFactory['protocol:aurelia:resolver'] = true; + +var ValidationErrorsCustomAttribute = /** @class */ (function () { + function ValidationErrorsCustomAttribute(boundaryElement, controllerAccessor) { + this.boundaryElement = boundaryElement; + this.controllerAccessor = controllerAccessor; + this.controller = null; + this.errors = []; + this.errorsInternal = []; + } + ValidationErrorsCustomAttribute.inject = function () { + return [aureliaPal.DOM.Element, aureliaDependencyInjection.Lazy.of(ValidationController)]; + }; + ValidationErrorsCustomAttribute.prototype.sort = function () { + this.errorsInternal.sort(function (a, b) { + if (a.targets[0] === b.targets[0]) { + return 0; + } + // tslint:disable-next-line:no-bitwise + return a.targets[0].compareDocumentPosition(b.targets[0]) & 2 ? 1 : -1; + }); + }; + ValidationErrorsCustomAttribute.prototype.interestingElements = function (elements) { + var _this = this; + return elements.filter(function (e) { return _this.boundaryElement.contains(e); }); + }; + ValidationErrorsCustomAttribute.prototype.render = function (instruction) { + var _loop_1 = function (result) { + var index = this_1.errorsInternal.findIndex(function (x) { return x.error === result; }); + if (index !== -1) { + this_1.errorsInternal.splice(index, 1); + } + }; + var this_1 = this; + for (var _i = 0, _a = instruction.unrender; _i < _a.length; _i++) { + var result = _a[_i].result; + _loop_1(result); + } + for (var _b = 0, _c = instruction.render; _b < _c.length; _b++) { + var _d = _c[_b], result = _d.result, elements = _d.elements; + if (result.valid) { + continue; + } + var targets = this.interestingElements(elements); + if (targets.length) { + this.errorsInternal.push({ error: result, targets: targets }); + } + } + this.sort(); + this.errors = this.errorsInternal; + }; + ValidationErrorsCustomAttribute.prototype.bind = function () { + if (!this.controller) { + this.controller = this.controllerAccessor(); + } + // this will call render() with the side-effect of updating this.errors + this.controller.addRenderer(this); + }; + ValidationErrorsCustomAttribute.prototype.unbind = function () { + if (this.controller) { + this.controller.removeRenderer(this); + } + }; + __decorate([ + aureliaTemplating.bindable({ defaultBindingMode: aureliaBinding.bindingMode.oneWay }) + ], ValidationErrorsCustomAttribute.prototype, "controller", void 0); + __decorate([ + aureliaTemplating.bindable({ primaryProperty: true, defaultBindingMode: aureliaBinding.bindingMode.twoWay }) + ], ValidationErrorsCustomAttribute.prototype, "errors", void 0); + ValidationErrorsCustomAttribute = __decorate([ + aureliaTemplating.customAttribute('validation-errors') + ], ValidationErrorsCustomAttribute); + return ValidationErrorsCustomAttribute; +}()); + +var ValidationRendererCustomAttribute = /** @class */ (function () { + function ValidationRendererCustomAttribute() { + } + ValidationRendererCustomAttribute.prototype.created = function (view) { + this.container = view.container; + }; + ValidationRendererCustomAttribute.prototype.bind = function () { + this.controller = this.container.get(ValidationController); + this.renderer = this.container.get(this.value); + this.controller.addRenderer(this.renderer); + }; + ValidationRendererCustomAttribute.prototype.unbind = function () { + this.controller.removeRenderer(this.renderer); + this.controller = null; + this.renderer = null; + }; + ValidationRendererCustomAttribute = __decorate([ + aureliaFramework.customAttribute('validation-renderer') + ], ValidationRendererCustomAttribute); + return ValidationRendererCustomAttribute; +}()); + +/** + * Sets, unsets and retrieves rules on an object or constructor function. + */ +var Rules = /** @class */ (function () { + function Rules() { + } + /** + * Applies the rules to a target. + */ + Rules.set = function (target, rules) { + if (target instanceof Function) { + target = target.prototype; + } + Object.defineProperty(target, Rules.key, { enumerable: false, configurable: false, writable: true, value: rules }); + }; + /** + * Removes rules from a target. + */ + Rules.unset = function (target) { + if (target instanceof Function) { + target = target.prototype; + } + target[Rules.key] = null; + }; + /** + * Retrieves the target's rules. + */ + Rules.get = function (target) { + return target[Rules.key] || null; + }; + /** + * The name of the property that stores the rules. + */ + Rules.key = '__rules__'; + return Rules; +}()); + +// tslint:disable:no-empty +var ExpressionVisitor = /** @class */ (function () { + function ExpressionVisitor() { + } + ExpressionVisitor.prototype.visitChain = function (chain) { + this.visitArgs(chain.expressions); + }; + ExpressionVisitor.prototype.visitBindingBehavior = function (behavior) { + behavior.expression.accept(this); + this.visitArgs(behavior.args); + }; + ExpressionVisitor.prototype.visitValueConverter = function (converter) { + converter.expression.accept(this); + this.visitArgs(converter.args); + }; + ExpressionVisitor.prototype.visitAssign = function (assign) { + assign.target.accept(this); + assign.value.accept(this); + }; + ExpressionVisitor.prototype.visitConditional = function (conditional) { + conditional.condition.accept(this); + conditional.yes.accept(this); + conditional.no.accept(this); + }; + ExpressionVisitor.prototype.visitAccessThis = function (access) { + access.ancestor = access.ancestor; + }; + ExpressionVisitor.prototype.visitAccessScope = function (access) { + access.name = access.name; + }; + ExpressionVisitor.prototype.visitAccessMember = function (access) { + access.object.accept(this); + }; + ExpressionVisitor.prototype.visitAccessKeyed = function (access) { + access.object.accept(this); + access.key.accept(this); + }; + ExpressionVisitor.prototype.visitCallScope = function (call) { + this.visitArgs(call.args); + }; + ExpressionVisitor.prototype.visitCallFunction = function (call) { + call.func.accept(this); + this.visitArgs(call.args); + }; + ExpressionVisitor.prototype.visitCallMember = function (call) { + call.object.accept(this); + this.visitArgs(call.args); + }; + ExpressionVisitor.prototype.visitPrefix = function (prefix) { + prefix.expression.accept(this); + }; + ExpressionVisitor.prototype.visitBinary = function (binary) { + binary.left.accept(this); + binary.right.accept(this); + }; + ExpressionVisitor.prototype.visitLiteralPrimitive = function (literal) { + literal.value = literal.value; + }; + ExpressionVisitor.prototype.visitLiteralArray = function (literal) { + this.visitArgs(literal.elements); + }; + ExpressionVisitor.prototype.visitLiteralObject = function (literal) { + this.visitArgs(literal.values); + }; + ExpressionVisitor.prototype.visitLiteralString = function (literal) { + literal.value = literal.value; + }; + ExpressionVisitor.prototype.visitArgs = function (args) { + for (var i = 0; i < args.length; i++) { + args[i].accept(this); + } + }; + return ExpressionVisitor; +}()); + +var ValidationMessageParser = /** @class */ (function () { + function ValidationMessageParser(bindinqLanguage) { + this.bindinqLanguage = bindinqLanguage; + this.emptyStringExpression = new aureliaBinding.LiteralString(''); + this.nullExpression = new aureliaBinding.LiteralPrimitive(null); + this.undefinedExpression = new aureliaBinding.LiteralPrimitive(undefined); + this.cache = {}; + } + ValidationMessageParser.prototype.parse = function (message) { + if (this.cache[message] !== undefined) { + return this.cache[message]; + } + var parts = this.bindinqLanguage.parseInterpolation(null, message); + if (parts === null) { + return new aureliaBinding.LiteralString(message); + } + var expression = new aureliaBinding.LiteralString(parts[0]); + for (var i = 1; i < parts.length; i += 2) { + expression = new aureliaBinding.Binary('+', expression, new aureliaBinding.Binary('+', this.coalesce(parts[i]), new aureliaBinding.LiteralString(parts[i + 1]))); + } + MessageExpressionValidator.validate(expression, message); + this.cache[message] = expression; + return expression; + }; + ValidationMessageParser.prototype.coalesce = function (part) { + // part === null || part === undefined ? '' : part + return new aureliaBinding.Conditional(new aureliaBinding.Binary('||', new aureliaBinding.Binary('===', part, this.nullExpression), new aureliaBinding.Binary('===', part, this.undefinedExpression)), this.emptyStringExpression, new aureliaBinding.CallMember(part, 'toString', [])); + }; + ValidationMessageParser.inject = [aureliaTemplating.BindingLanguage]; + return ValidationMessageParser; +}()); +var MessageExpressionValidator = /** @class */ (function (_super) { + __extends(MessageExpressionValidator, _super); + function MessageExpressionValidator(originalMessage) { + var _this = _super.call(this) || this; + _this.originalMessage = originalMessage; + return _this; + } + MessageExpressionValidator.validate = function (expression, originalMessage) { + var visitor = new MessageExpressionValidator(originalMessage); + expression.accept(visitor); + }; + MessageExpressionValidator.prototype.visitAccessScope = function (access) { + if (access.ancestor !== 0) { + throw new Error('$parent is not permitted in validation message expressions.'); + } + if (['displayName', 'propertyName', 'value', 'object', 'config', 'getDisplayName'].indexOf(access.name) !== -1) { + LogManager.getLogger('aurelia-validation') + // tslint:disable-next-line:max-line-length + .warn("Did you mean to use \"$" + access.name + "\" instead of \"" + access.name + "\" in this validation message template: \"" + this.originalMessage + "\"?"); + } + }; + return MessageExpressionValidator; +}(ExpressionVisitor)); + +/** + * Dictionary of validation messages. [messageKey]: messageExpression + */ +var validationMessages = { + /** + * The default validation message. Used with rules that have no standard message. + */ + default: "${$displayName} is invalid.", + required: "${$displayName} is required.", + matches: "${$displayName} is not correctly formatted.", + email: "${$displayName} is not a valid email.", + minLength: "${$displayName} must be at least ${$config.length} character${$config.length === 1 ? '' : 's'}.", + maxLength: "${$displayName} cannot be longer than ${$config.length} character${$config.length === 1 ? '' : 's'}.", + minItems: "${$displayName} must contain at least ${$config.count} item${$config.count === 1 ? '' : 's'}.", + maxItems: "${$displayName} cannot contain more than ${$config.count} item${$config.count === 1 ? '' : 's'}.", + equals: "${$displayName} must be ${$config.expectedValue}.", +}; +/** + * Retrieves validation messages and property display names. + */ +var ValidationMessageProvider = /** @class */ (function () { + function ValidationMessageProvider(parser) { + this.parser = parser; + } + /** + * Returns a message binding expression that corresponds to the key. + * @param key The message key. + */ + ValidationMessageProvider.prototype.getMessage = function (key) { + var message; + if (key in validationMessages) { + message = validationMessages[key]; + } + else { + message = validationMessages['default']; + } + return this.parser.parse(message); + }; + /** + * Formulates a property display name using the property name and the configured + * displayName (if provided). + * Override this with your own custom logic. + * @param propertyName The property name. + */ + ValidationMessageProvider.prototype.getDisplayName = function (propertyName, displayName) { + if (displayName !== null && displayName !== undefined) { + return (displayName instanceof Function) ? displayName() : displayName; + } + // split on upper-case letters. + var words = propertyName.toString().split(/(?=[A-Z])/).join(' '); + // capitalize first letter. + return words.charAt(0).toUpperCase() + words.slice(1); + }; + ValidationMessageProvider.inject = [ValidationMessageParser]; + return ValidationMessageProvider; +}()); + +/** + * Validates. + * Responsible for validating objects and properties. + */ +var StandardValidator = /** @class */ (function (_super) { + __extends(StandardValidator, _super); + function StandardValidator(messageProvider, resources) { + var _this = _super.call(this) || this; + _this.messageProvider = messageProvider; + _this.lookupFunctions = resources.lookupFunctions; + _this.getDisplayName = messageProvider.getDisplayName.bind(messageProvider); + return _this; + } + /** + * Validates the specified property. + * @param object The object to validate. + * @param propertyName The name of the property to validate. + * @param rules Optional. If unspecified, the rules will be looked up using the metadata + * for the object created by ValidationRules....on(class/object) + */ + StandardValidator.prototype.validateProperty = function (object, propertyName, rules) { + return this.validate(object, propertyName, rules || null); + }; + /** + * Validates all rules for specified object and it's properties. + * @param object The object to validate. + * @param rules Optional. If unspecified, the rules will be looked up using the metadata + * for the object created by ValidationRules....on(class/object) + */ + StandardValidator.prototype.validateObject = function (object, rules) { + return this.validate(object, null, rules || null); + }; + /** + * Determines whether a rule exists in a set of rules. + * @param rules The rules to search. + * @parem rule The rule to find. + */ + StandardValidator.prototype.ruleExists = function (rules, rule) { + var i = rules.length; + while (i--) { + if (rules[i].indexOf(rule) !== -1) { + return true; + } + } + return false; + }; + StandardValidator.prototype.getMessage = function (rule, object, value) { + var expression = rule.message || this.messageProvider.getMessage(rule.messageKey); + // tslint:disable-next-line:prefer-const + var _a = rule.property, propertyName = _a.name, displayName = _a.displayName; + if (propertyName !== null) { + displayName = this.messageProvider.getDisplayName(propertyName, displayName); + } + var overrideContext = { + $displayName: displayName, + $propertyName: propertyName, + $value: value, + $object: object, + $config: rule.config, + // returns the name of a given property, given just the property name (irrespective of the property's displayName) + // split on capital letters, first letter ensured to be capitalized + $getDisplayName: this.getDisplayName + }; + return expression.evaluate({ bindingContext: object, overrideContext: overrideContext }, this.lookupFunctions); + }; + StandardValidator.prototype.validateRuleSequence = function (object, propertyName, ruleSequence, sequence, results) { + var _this = this; + // are we validating all properties or a single property? + var validateAllProperties = propertyName === null || propertyName === undefined; + var rules = ruleSequence[sequence]; + var allValid = true; + // validate each rule. + var promises = []; + var _loop_1 = function (i) { + var rule = rules[i]; + // is the rule related to the property we're validating. + // tslint:disable-next-line:triple-equals | Use loose equality for property keys + if (!validateAllProperties && rule.property.name != propertyName) { + return "continue"; + } + // is this a conditional rule? is the condition met? + if (rule.when && !rule.when(object)) { + return "continue"; + } + // validate. + var value = rule.property.name === null ? object : object[rule.property.name]; + var promiseOrBoolean = rule.condition(value, object); + if (!(promiseOrBoolean instanceof Promise)) { + promiseOrBoolean = Promise.resolve(promiseOrBoolean); + } + promises.push(promiseOrBoolean.then(function (valid) { + var message = valid ? null : _this.getMessage(rule, object, value); + results.push(new ValidateResult(rule, object, rule.property.name, valid, message)); + allValid = allValid && valid; + return valid; + })); + }; + for (var i = 0; i < rules.length; i++) { + _loop_1(i); + } + return Promise.all(promises) + .then(function () { + sequence++; + if (allValid && sequence < ruleSequence.length) { + return _this.validateRuleSequence(object, propertyName, ruleSequence, sequence, results); + } + return results; + }); + }; + StandardValidator.prototype.validate = function (object, propertyName, rules) { + // rules specified? + if (!rules) { + // no. attempt to locate the rules. + rules = Rules.get(object); + } + // any rules? + if (!rules || rules.length === 0) { + return Promise.resolve([]); + } + return this.validateRuleSequence(object, propertyName, rules, 0, []); + }; + StandardValidator.inject = [ValidationMessageProvider, aureliaTemplating.ViewResources]; + return StandardValidator; +}(Validator)); + +/** + * Part of the fluent rule API. Enables customizing property rules. + */ +var FluentRuleCustomizer = /** @class */ (function () { + function FluentRuleCustomizer(property, condition, config, fluentEnsure, fluentRules, parsers) { + if (config === void 0) { config = {}; } + this.fluentEnsure = fluentEnsure; + this.fluentRules = fluentRules; + this.parsers = parsers; + this.rule = { + property: property, + condition: condition, + config: config, + when: null, + messageKey: 'default', + message: null, + sequence: fluentRules.sequence + }; + this.fluentEnsure._addRule(this.rule); + } + /** + * Validate subsequent rules after previously declared rules have + * been validated successfully. Use to postpone validation of costly + * rules until less expensive rules pass validation. + */ + FluentRuleCustomizer.prototype.then = function () { + this.fluentRules.sequence++; + return this; + }; + /** + * Specifies the key to use when looking up the rule's validation message. + */ + FluentRuleCustomizer.prototype.withMessageKey = function (key) { + this.rule.messageKey = key; + this.rule.message = null; + return this; + }; + /** + * Specifies rule's validation message. + */ + FluentRuleCustomizer.prototype.withMessage = function (message) { + this.rule.messageKey = 'custom'; + this.rule.message = this.parsers.message.parse(message); + return this; + }; + /** + * Specifies a condition that must be met before attempting to validate the rule. + * @param condition A function that accepts the object as a parameter and returns true + * or false whether the rule should be evaluated. + */ + FluentRuleCustomizer.prototype.when = function (condition) { + this.rule.when = condition; + return this; + }; + /** + * Tags the rule instance, enabling the rule to be found easily + * using ValidationRules.taggedRules(rules, tag) + */ + FluentRuleCustomizer.prototype.tag = function (tag) { + this.rule.tag = tag; + return this; + }; + ///// FluentEnsure APIs ///// + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor function. + */ + FluentRuleCustomizer.prototype.ensure = function (subject) { + return this.fluentEnsure.ensure(subject); + }; + /** + * Targets an object with validation rules. + */ + FluentRuleCustomizer.prototype.ensureObject = function () { + return this.fluentEnsure.ensureObject(); + }; + Object.defineProperty(FluentRuleCustomizer.prototype, "rules", { + /** + * Rules that have been defined using the fluent API. + */ + get: function () { + return this.fluentEnsure.rules; + }, + enumerable: true, + configurable: true + }); + /** + * Applies the rules to a class or object, making them discoverable by the StandardValidator. + * @param target A class or object. + */ + FluentRuleCustomizer.prototype.on = function (target) { + return this.fluentEnsure.on(target); + }; + ///////// FluentRules APIs ///////// + /** + * Applies an ad-hoc rule function to the ensured property or object. + * @param condition The function to validate the rule. + * Will be called with two arguments, the property value and the object. + * Should return a boolean or a Promise that resolves to a boolean. + */ + FluentRuleCustomizer.prototype.satisfies = function (condition, config) { + return this.fluentRules.satisfies(condition, config); + }; + /** + * Applies a rule by name. + * @param name The name of the custom or standard rule. + * @param args The rule's arguments. + */ + FluentRuleCustomizer.prototype.satisfiesRule = function (name) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + var _a; + return (_a = this.fluentRules).satisfiesRule.apply(_a, [name].concat(args)); + }; + /** + * Applies the "required" rule to the property. + * The value cannot be null, undefined or whitespace. + */ + FluentRuleCustomizer.prototype.required = function () { + return this.fluentRules.required(); + }; + /** + * Applies the "matches" rule to the property. + * Value must match the specified regular expression. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.matches = function (regex) { + return this.fluentRules.matches(regex); + }; + /** + * Applies the "email" rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.email = function () { + return this.fluentRules.email(); + }; + /** + * Applies the "minLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.minLength = function (length) { + return this.fluentRules.minLength(length); + }; + /** + * Applies the "maxLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.maxLength = function (length) { + return this.fluentRules.maxLength(length); + }; + /** + * Applies the "minItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRuleCustomizer.prototype.minItems = function (count) { + return this.fluentRules.minItems(count); + }; + /** + * Applies the "maxItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRuleCustomizer.prototype.maxItems = function (count) { + return this.fluentRules.maxItems(count); + }; + /** + * Applies the "equals" validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.equals = function (expectedValue) { + return this.fluentRules.equals(expectedValue); + }; + return FluentRuleCustomizer; +}()); +/** + * Part of the fluent rule API. Enables applying rules to properties and objects. + */ +var FluentRules = /** @class */ (function () { + function FluentRules(fluentEnsure, parsers, property) { + this.fluentEnsure = fluentEnsure; + this.parsers = parsers; + this.property = property; + /** + * Current rule sequence number. Used to postpone evaluation of rules until rules + * with lower sequence number have successfully validated. The "then" fluent API method + * manages this property, there's usually no need to set it directly. + */ + this.sequence = 0; + } + /** + * Sets the display name of the ensured property. + */ + FluentRules.prototype.displayName = function (name) { + this.property.displayName = name; + return this; + }; + /** + * Applies an ad-hoc rule function to the ensured property or object. + * @param condition The function to validate the rule. + * Will be called with two arguments, the property value and the object. + * Should return a boolean or a Promise that resolves to a boolean. + */ + FluentRules.prototype.satisfies = function (condition, config) { + return new FluentRuleCustomizer(this.property, condition, config, this.fluentEnsure, this, this.parsers); + }; + /** + * Applies a rule by name. + * @param name The name of the custom or standard rule. + * @param args The rule's arguments. + */ + FluentRules.prototype.satisfiesRule = function (name) { + var _this = this; + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + var rule = FluentRules.customRules[name]; + if (!rule) { + // standard rule? + rule = this[name]; + if (rule instanceof Function) { + return rule.call.apply(rule, [this].concat(args)); + } + throw new Error("Rule with name \"" + name + "\" does not exist."); + } + var config = rule.argsToConfig ? rule.argsToConfig.apply(rule, args) : undefined; + return this.satisfies(function (value, obj) { + var _a; + return (_a = rule.condition).call.apply(_a, [_this, value, obj].concat(args)); + }, config) + .withMessageKey(name); + }; + /** + * Applies the "required" rule to the property. + * The value cannot be null, undefined or whitespace. + */ + FluentRules.prototype.required = function () { + return this.satisfies(function (value) { + return value !== null + && value !== undefined + && !(isString(value) && !/\S/.test(value)); + }).withMessageKey('required'); + }; + /** + * Applies the "matches" rule to the property. + * Value must match the specified regular expression. + * null, undefined and empty-string values are considered valid. + */ + FluentRules.prototype.matches = function (regex) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || regex.test(value); }) + .withMessageKey('matches'); + }; + /** + * Applies the "email" rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRules.prototype.email = function () { + // regex from https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address + /* tslint:disable:max-line-length */ + return this.matches(/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/) + /* tslint:enable:max-line-length */ + .withMessageKey('email'); + }; + /** + * Applies the "minLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRules.prototype.minLength = function (length) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || value.length >= length; }, { length: length }) + .withMessageKey('minLength'); + }; + /** + * Applies the "maxLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRules.prototype.maxLength = function (length) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || value.length <= length; }, { length: length }) + .withMessageKey('maxLength'); + }; + /** + * Applies the "minItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRules.prototype.minItems = function (count) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length >= count; }, { count: count }) + .withMessageKey('minItems'); + }; + /** + * Applies the "maxItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRules.prototype.maxItems = function (count) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length <= count; }, { count: count }) + .withMessageKey('maxItems'); + }; + /** + * Applies the "equals" validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRules.prototype.equals = function (expectedValue) { + return this.satisfies(function (value) { return value === null || value === undefined || value === '' || value === expectedValue; }, { expectedValue: expectedValue }) + .withMessageKey('equals'); + }; + FluentRules.customRules = {}; + return FluentRules; +}()); +/** + * Part of the fluent rule API. Enables targeting properties and objects with rules. + */ +var FluentEnsure = /** @class */ (function () { + function FluentEnsure(parsers) { + this.parsers = parsers; + /** + * Rules that have been defined using the fluent API. + */ + this.rules = []; + } + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor + * function. + */ + FluentEnsure.prototype.ensure = function (property) { + this.assertInitialized(); + var name = this.parsers.property.parse(property); + var fluentRules = new FluentRules(this, this.parsers, { name: name, displayName: null }); + return this.mergeRules(fluentRules, name); + }; + /** + * Targets an object with validation rules. + */ + FluentEnsure.prototype.ensureObject = function () { + this.assertInitialized(); + var fluentRules = new FluentRules(this, this.parsers, { name: null, displayName: null }); + return this.mergeRules(fluentRules, null); + }; + /** + * Applies the rules to a class or object, making them discoverable by the StandardValidator. + * @param target A class or object. + */ + FluentEnsure.prototype.on = function (target) { + Rules.set(target, this.rules); + return this; + }; + /** + * Adds a rule definition to the sequenced ruleset. + * @internal + */ + FluentEnsure.prototype._addRule = function (rule) { + while (this.rules.length < rule.sequence + 1) { + this.rules.push([]); + } + this.rules[rule.sequence].push(rule); + }; + FluentEnsure.prototype.assertInitialized = function () { + if (this.parsers) { + return; + } + throw new Error("Did you forget to add \".plugin('aurelia-validation')\" to your main.js?"); + }; + FluentEnsure.prototype.mergeRules = function (fluentRules, propertyName) { + // tslint:disable-next-line:triple-equals | Use loose equality for property keys + var existingRules = this.rules.find(function (r) { return r.length > 0 && r[0].property.name == propertyName; }); + if (existingRules) { + var rule = existingRules[existingRules.length - 1]; + fluentRules.sequence = rule.sequence; + if (rule.property.displayName !== null) { + fluentRules = fluentRules.displayName(rule.property.displayName); + } + } + return fluentRules; + }; + return FluentEnsure; +}()); +/** + * Fluent rule definition API. + */ +var ValidationRules = /** @class */ (function () { + function ValidationRules() { + } + ValidationRules.initialize = function (messageParser, propertyParser) { + this.parsers = { + message: messageParser, + property: propertyParser + }; + }; + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor function. + */ + ValidationRules.ensure = function (property) { + return new FluentEnsure(ValidationRules.parsers).ensure(property); + }; + /** + * Targets an object with validation rules. + */ + ValidationRules.ensureObject = function () { + return new FluentEnsure(ValidationRules.parsers).ensureObject(); + }; + /** + * Defines a custom rule. + * @param name The name of the custom rule. Also serves as the message key. + * @param condition The rule function. + * @param message The message expression + * @param argsToConfig A function that maps the rule's arguments to a "config" + * object that can be used when evaluating the message expression. + */ + ValidationRules.customRule = function (name, condition, message, argsToConfig) { + validationMessages[name] = message; + FluentRules.customRules[name] = { condition: condition, argsToConfig: argsToConfig }; + }; + /** + * Returns rules with the matching tag. + * @param rules The rules to search. + * @param tag The tag to search for. + */ + ValidationRules.taggedRules = function (rules, tag) { + return rules.map(function (x) { return x.filter(function (r) { return r.tag === tag; }); }); + }; + /** + * Returns rules that have no tag. + * @param rules The rules to search. + */ + ValidationRules.untaggedRules = function (rules) { + return rules.map(function (x) { return x.filter(function (r) { return r.tag === undefined; }); }); + }; + /** + * Removes the rules from a class or object. + * @param target A class or object. + */ + ValidationRules.off = function (target) { + Rules.unset(target); + }; + return ValidationRules; +}()); + +// Exports +/** + * Aurelia Validation Configuration API + */ +var AureliaValidationConfiguration = /** @class */ (function () { + function AureliaValidationConfiguration() { + this.validatorType = StandardValidator; + } + /** + * Use a custom Validator implementation. + */ + AureliaValidationConfiguration.prototype.customValidator = function (type) { + this.validatorType = type; + }; + /** + * Applies the configuration. + */ + AureliaValidationConfiguration.prototype.apply = function (container) { + var validator = container.get(this.validatorType); + container.registerInstance(Validator, validator); + }; + return AureliaValidationConfiguration; +}()); +/** + * Configures the plugin. + */ +function configure( +// tslint:disable-next-line:ban-types +frameworkConfig, callback) { + // the fluent rule definition API needs the parser to translate messages + // to interpolation expressions. + var messageParser = frameworkConfig.container.get(ValidationMessageParser); + var propertyParser = frameworkConfig.container.get(PropertyAccessorParser); + ValidationRules.initialize(messageParser, propertyParser); + // configure... + var config = new AureliaValidationConfiguration(); + if (callback instanceof Function) { + callback(config); + } + config.apply(frameworkConfig.container); + // globalize the behaviors. + if (frameworkConfig.globalResources) { + frameworkConfig.globalResources(ValidateBindingBehavior, ValidateManuallyBindingBehavior, ValidateOnBlurBindingBehavior, ValidateOnChangeBindingBehavior, ValidateOnChangeOrBlurBindingBehavior, ValidationErrorsCustomAttribute, ValidationRendererCustomAttribute); + } } + +exports.AureliaValidationConfiguration = AureliaValidationConfiguration; exports.configure = configure; +exports.getTargetDOMElement = getTargetDOMElement; +exports.getPropertyInfo = getPropertyInfo; +exports.PropertyAccessorParser = PropertyAccessorParser; +exports.getAccessorExpression = getAccessorExpression; +exports.ValidateBindingBehavior = ValidateBindingBehavior; +exports.ValidateManuallyBindingBehavior = ValidateManuallyBindingBehavior; +exports.ValidateOnBlurBindingBehavior = ValidateOnBlurBindingBehavior; +exports.ValidateOnChangeBindingBehavior = ValidateOnChangeBindingBehavior; +exports.ValidateOnChangeOrBlurBindingBehavior = ValidateOnChangeOrBlurBindingBehavior; +exports.ValidateEvent = ValidateEvent; +exports.ValidateResult = ValidateResult; +exports.ValidationController = ValidationController; +exports.ValidationControllerFactory = ValidationControllerFactory; +exports.ValidationErrorsCustomAttribute = ValidationErrorsCustomAttribute; +exports.ValidationRendererCustomAttribute = ValidationRendererCustomAttribute; +exports.Validator = Validator; +exports.Rules = Rules; +exports.StandardValidator = StandardValidator; +exports.validationMessages = validationMessages; +exports.ValidationMessageProvider = ValidationMessageProvider; +exports.ValidationMessageParser = ValidationMessageParser; +exports.MessageExpressionValidator = MessageExpressionValidator; +exports.FluentRuleCustomizer = FluentRuleCustomizer; +exports.FluentRules = FluentRules; +exports.FluentEnsure = FluentEnsure; +exports.ValidationRules = ValidationRules; diff --git a/dist/commonjs/controller-validate-result.d.ts b/dist/commonjs/controller-validate-result.d.ts deleted file mode 100644 index 5f814ed0..00000000 --- a/dist/commonjs/controller-validate-result.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { ValidateResult } from './validate-result'; -import { ValidateInstruction } from './validate-instruction'; -/** - * The result of a call to the validation controller's validate method. - */ -export interface ControllerValidateResult { - /** - * Whether validation passed. - */ - valid: boolean; - /** - * The validation result of every rule that was evaluated. - */ - results: ValidateResult[]; - /** - * The instruction passed to the controller's validate method. - */ - instruction?: ValidateInstruction; -} diff --git a/dist/commonjs/controller-validate-result.js b/dist/commonjs/controller-validate-result.js deleted file mode 100644 index c8ad2e54..00000000 --- a/dist/commonjs/controller-validate-result.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/dist/commonjs/get-target-dom-element.d.ts b/dist/commonjs/get-target-dom-element.d.ts deleted file mode 100644 index 314fc952..00000000 --- a/dist/commonjs/get-target-dom-element.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Gets the DOM element associated with the data-binding. Most of the time it's - * the binding.target but sometimes binding.target is an aurelia custom element, - * or custom attribute which is a javascript "class" instance, so we need to use - * the controller's container to retrieve the actual DOM element. - */ -export declare function getTargetDOMElement(binding: any, view: any): Element; diff --git a/dist/commonjs/get-target-dom-element.js b/dist/commonjs/get-target-dom-element.js deleted file mode 100644 index c6a2d7a9..00000000 --- a/dist/commonjs/get-target-dom-element.js +++ /dev/null @@ -1,30 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var aurelia_pal_1 = require("aurelia-pal"); -/** - * Gets the DOM element associated with the data-binding. Most of the time it's - * the binding.target but sometimes binding.target is an aurelia custom element, - * or custom attribute which is a javascript "class" instance, so we need to use - * the controller's container to retrieve the actual DOM element. - */ -function getTargetDOMElement(binding, view) { - var target = binding.target; - // DOM element - if (target instanceof Element) { - return target; - } - // custom element or custom attribute - // tslint:disable-next-line:prefer-const - for (var i = 0, ii = view.controllers.length; i < ii; i++) { - var controller = view.controllers[i]; - if (controller.viewModel === target) { - var element = controller.container.get(aurelia_pal_1.DOM.Element); - if (element) { - return element; - } - throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\"."); - } - } - throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\"."); -} -exports.getTargetDOMElement = getTargetDOMElement; diff --git a/dist/commonjs/implementation/expression-visitor.js b/dist/commonjs/implementation/expression-visitor.js deleted file mode 100644 index ba924f58..00000000 --- a/dist/commonjs/implementation/expression-visitor.js +++ /dev/null @@ -1,77 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -// tslint:disable:no-empty -var ExpressionVisitor = /** @class */ (function () { - function ExpressionVisitor() { - } - ExpressionVisitor.prototype.visitChain = function (chain) { - this.visitArgs(chain.expressions); - }; - ExpressionVisitor.prototype.visitBindingBehavior = function (behavior) { - behavior.expression.accept(this); - this.visitArgs(behavior.args); - }; - ExpressionVisitor.prototype.visitValueConverter = function (converter) { - converter.expression.accept(this); - this.visitArgs(converter.args); - }; - ExpressionVisitor.prototype.visitAssign = function (assign) { - assign.target.accept(this); - assign.value.accept(this); - }; - ExpressionVisitor.prototype.visitConditional = function (conditional) { - conditional.condition.accept(this); - conditional.yes.accept(this); - conditional.no.accept(this); - }; - ExpressionVisitor.prototype.visitAccessThis = function (access) { - access.ancestor = access.ancestor; - }; - ExpressionVisitor.prototype.visitAccessScope = function (access) { - access.name = access.name; - }; - ExpressionVisitor.prototype.visitAccessMember = function (access) { - access.object.accept(this); - }; - ExpressionVisitor.prototype.visitAccessKeyed = function (access) { - access.object.accept(this); - access.key.accept(this); - }; - ExpressionVisitor.prototype.visitCallScope = function (call) { - this.visitArgs(call.args); - }; - ExpressionVisitor.prototype.visitCallFunction = function (call) { - call.func.accept(this); - this.visitArgs(call.args); - }; - ExpressionVisitor.prototype.visitCallMember = function (call) { - call.object.accept(this); - this.visitArgs(call.args); - }; - ExpressionVisitor.prototype.visitPrefix = function (prefix) { - prefix.expression.accept(this); - }; - ExpressionVisitor.prototype.visitBinary = function (binary) { - binary.left.accept(this); - binary.right.accept(this); - }; - ExpressionVisitor.prototype.visitLiteralPrimitive = function (literal) { - literal.value = literal.value; - }; - ExpressionVisitor.prototype.visitLiteralArray = function (literal) { - this.visitArgs(literal.elements); - }; - ExpressionVisitor.prototype.visitLiteralObject = function (literal) { - this.visitArgs(literal.values); - }; - ExpressionVisitor.prototype.visitLiteralString = function (literal) { - literal.value = literal.value; - }; - ExpressionVisitor.prototype.visitArgs = function (args) { - for (var i = 0; i < args.length; i++) { - args[i].accept(this); - } - }; - return ExpressionVisitor; -}()); -exports.ExpressionVisitor = ExpressionVisitor; diff --git a/dist/commonjs/implementation/rule.d.ts b/dist/commonjs/implementation/rule.d.ts deleted file mode 100644 index ffbb7b21..00000000 --- a/dist/commonjs/implementation/rule.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Expression } from 'aurelia-binding'; -export declare type ValidationDisplayNameAccessor = () => string; -/** - * Information related to a property that is the subject of validation. - */ -export interface RuleProperty { - /** - * The property name. null indicates the rule targets the object itself. - */ - name: string | number | null; - /** - * The displayName of the property (or object). - */ - displayName: string | ValidationDisplayNameAccessor | null; -} -/** - * A rule definition. Associations a rule with a property or object. - */ -export interface Rule { - property: RuleProperty; - condition: (value: TValue, object?: TObject) => boolean | Promise; - config: object; - when: ((object: TObject) => boolean) | null; - messageKey: string; - message: Expression | null; - sequence: number; - tag?: string; -} diff --git a/dist/commonjs/implementation/rule.js b/dist/commonjs/implementation/rule.js deleted file mode 100644 index c8ad2e54..00000000 --- a/dist/commonjs/implementation/rule.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/dist/commonjs/implementation/rules.d.ts b/dist/commonjs/implementation/rules.d.ts deleted file mode 100644 index 30947f6f..00000000 --- a/dist/commonjs/implementation/rules.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Rule } from './rule'; -/** - * Sets, unsets and retrieves rules on an object or constructor function. - */ -export declare class Rules { - /** - * The name of the property that stores the rules. - */ - private static key; - /** - * Applies the rules to a target. - */ - static set(target: any, rules: Rule[][]): void; - /** - * Removes rules from a target. - */ - static unset(target: any): void; - /** - * Retrieves the target's rules. - */ - static get(target: any): Rule[][] | null; -} diff --git a/dist/commonjs/implementation/rules.js b/dist/commonjs/implementation/rules.js deleted file mode 100644 index 9b3f30e6..00000000 --- a/dist/commonjs/implementation/rules.js +++ /dev/null @@ -1,39 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * Sets, unsets and retrieves rules on an object or constructor function. - */ -var Rules = /** @class */ (function () { - function Rules() { - } - /** - * Applies the rules to a target. - */ - Rules.set = function (target, rules) { - if (target instanceof Function) { - target = target.prototype; - } - Object.defineProperty(target, Rules.key, { enumerable: false, configurable: false, writable: true, value: rules }); - }; - /** - * Removes rules from a target. - */ - Rules.unset = function (target) { - if (target instanceof Function) { - target = target.prototype; - } - target[Rules.key] = null; - }; - /** - * Retrieves the target's rules. - */ - Rules.get = function (target) { - return target[Rules.key] || null; - }; - /** - * The name of the property that stores the rules. - */ - Rules.key = '__rules__'; - return Rules; -}()); -exports.Rules = Rules; diff --git a/dist/commonjs/implementation/standard-validator.d.ts b/dist/commonjs/implementation/standard-validator.d.ts deleted file mode 100644 index c47a7d2e..00000000 --- a/dist/commonjs/implementation/standard-validator.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { ViewResources } from 'aurelia-templating'; -import { Validator } from '../validator'; -import { ValidateResult } from '../validate-result'; -import { Rule } from './rule'; -import { ValidationMessageProvider } from './validation-messages'; -/** - * Validates. - * Responsible for validating objects and properties. - */ -export declare class StandardValidator extends Validator { - static inject: (typeof ViewResources | typeof ValidationMessageProvider)[]; - private messageProvider; - private lookupFunctions; - private getDisplayName; - constructor(messageProvider: ValidationMessageProvider, resources: ViewResources); - /** - * Validates the specified property. - * @param object The object to validate. - * @param propertyName The name of the property to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - validateProperty(object: any, propertyName: string | number, rules?: any): Promise; - /** - * Validates all rules for specified object and it's properties. - * @param object The object to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - validateObject(object: any, rules?: any): Promise; - /** - * Determines whether a rule exists in a set of rules. - * @param rules The rules to search. - * @parem rule The rule to find. - */ - ruleExists(rules: Rule[][], rule: Rule): boolean; - private getMessage(rule, object, value); - private validateRuleSequence(object, propertyName, ruleSequence, sequence, results); - private validate(object, propertyName, rules); -} diff --git a/dist/commonjs/implementation/standard-validator.js b/dist/commonjs/implementation/standard-validator.js deleted file mode 100644 index 5b567a4d..00000000 --- a/dist/commonjs/implementation/standard-validator.js +++ /dev/null @@ -1,142 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var aurelia_templating_1 = require("aurelia-templating"); -var validator_1 = require("../validator"); -var validate_result_1 = require("../validate-result"); -var rules_1 = require("./rules"); -var validation_messages_1 = require("./validation-messages"); -/** - * Validates. - * Responsible for validating objects and properties. - */ -var StandardValidator = /** @class */ (function (_super) { - __extends(StandardValidator, _super); - function StandardValidator(messageProvider, resources) { - var _this = _super.call(this) || this; - _this.messageProvider = messageProvider; - _this.lookupFunctions = resources.lookupFunctions; - _this.getDisplayName = messageProvider.getDisplayName.bind(messageProvider); - return _this; - } - /** - * Validates the specified property. - * @param object The object to validate. - * @param propertyName The name of the property to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - StandardValidator.prototype.validateProperty = function (object, propertyName, rules) { - return this.validate(object, propertyName, rules || null); - }; - /** - * Validates all rules for specified object and it's properties. - * @param object The object to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - StandardValidator.prototype.validateObject = function (object, rules) { - return this.validate(object, null, rules || null); - }; - /** - * Determines whether a rule exists in a set of rules. - * @param rules The rules to search. - * @parem rule The rule to find. - */ - StandardValidator.prototype.ruleExists = function (rules, rule) { - var i = rules.length; - while (i--) { - if (rules[i].indexOf(rule) !== -1) { - return true; - } - } - return false; - }; - StandardValidator.prototype.getMessage = function (rule, object, value) { - var expression = rule.message || this.messageProvider.getMessage(rule.messageKey); - // tslint:disable-next-line:prefer-const - var _a = rule.property, propertyName = _a.name, displayName = _a.displayName; - if (propertyName !== null) { - displayName = this.messageProvider.getDisplayName(propertyName, displayName); - } - var overrideContext = { - $displayName: displayName, - $propertyName: propertyName, - $value: value, - $object: object, - $config: rule.config, - // returns the name of a given property, given just the property name (irrespective of the property's displayName) - // split on capital letters, first letter ensured to be capitalized - $getDisplayName: this.getDisplayName - }; - return expression.evaluate({ bindingContext: object, overrideContext: overrideContext }, this.lookupFunctions); - }; - StandardValidator.prototype.validateRuleSequence = function (object, propertyName, ruleSequence, sequence, results) { - var _this = this; - // are we validating all properties or a single property? - var validateAllProperties = propertyName === null || propertyName === undefined; - var rules = ruleSequence[sequence]; - var allValid = true; - // validate each rule. - var promises = []; - var _loop_1 = function (i) { - var rule = rules[i]; - // is the rule related to the property we're validating. - // tslint:disable-next-line:triple-equals | Use loose equality for property keys - if (!validateAllProperties && rule.property.name != propertyName) { - return "continue"; - } - // is this a conditional rule? is the condition met? - if (rule.when && !rule.when(object)) { - return "continue"; - } - // validate. - var value = rule.property.name === null ? object : object[rule.property.name]; - var promiseOrBoolean = rule.condition(value, object); - if (!(promiseOrBoolean instanceof Promise)) { - promiseOrBoolean = Promise.resolve(promiseOrBoolean); - } - promises.push(promiseOrBoolean.then(function (valid) { - var message = valid ? null : _this.getMessage(rule, object, value); - results.push(new validate_result_1.ValidateResult(rule, object, rule.property.name, valid, message)); - allValid = allValid && valid; - return valid; - })); - }; - for (var i = 0; i < rules.length; i++) { - _loop_1(i); - } - return Promise.all(promises) - .then(function () { - sequence++; - if (allValid && sequence < ruleSequence.length) { - return _this.validateRuleSequence(object, propertyName, ruleSequence, sequence, results); - } - return results; - }); - }; - StandardValidator.prototype.validate = function (object, propertyName, rules) { - // rules specified? - if (!rules) { - // no. attempt to locate the rules. - rules = rules_1.Rules.get(object); - } - // any rules? - if (!rules || rules.length === 0) { - return Promise.resolve([]); - } - return this.validateRuleSequence(object, propertyName, rules, 0, []); - }; - StandardValidator.inject = [validation_messages_1.ValidationMessageProvider, aurelia_templating_1.ViewResources]; - return StandardValidator; -}(validator_1.Validator)); -exports.StandardValidator = StandardValidator; diff --git a/dist/commonjs/implementation/validation-message-parser.d.ts b/dist/commonjs/implementation/validation-message-parser.d.ts deleted file mode 100644 index 39d288c0..00000000 --- a/dist/commonjs/implementation/validation-message-parser.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Expression, AccessScope } from 'aurelia-binding'; -import { BindingLanguage } from 'aurelia-templating'; -import { ExpressionVisitor } from './expression-visitor'; -export declare class ValidationMessageParser { - private bindinqLanguage; - static inject: (typeof BindingLanguage)[]; - private emptyStringExpression; - private nullExpression; - private undefinedExpression; - private cache; - constructor(bindinqLanguage: BindingLanguage); - parse(message: string): Expression; - private coalesce(part); -} -export declare class MessageExpressionValidator extends ExpressionVisitor { - private originalMessage; - static validate(expression: Expression, originalMessage: string): void; - constructor(originalMessage: string); - visitAccessScope(access: AccessScope): void; -} diff --git a/dist/commonjs/implementation/validation-message-parser.js b/dist/commonjs/implementation/validation-message-parser.js deleted file mode 100644 index 3322c134..00000000 --- a/dist/commonjs/implementation/validation-message-parser.js +++ /dev/null @@ -1,71 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var aurelia_binding_1 = require("aurelia-binding"); -var aurelia_templating_1 = require("aurelia-templating"); -var LogManager = require("aurelia-logging"); -var expression_visitor_1 = require("./expression-visitor"); -var ValidationMessageParser = /** @class */ (function () { - function ValidationMessageParser(bindinqLanguage) { - this.bindinqLanguage = bindinqLanguage; - this.emptyStringExpression = new aurelia_binding_1.LiteralString(''); - this.nullExpression = new aurelia_binding_1.LiteralPrimitive(null); - this.undefinedExpression = new aurelia_binding_1.LiteralPrimitive(undefined); - this.cache = {}; - } - ValidationMessageParser.prototype.parse = function (message) { - if (this.cache[message] !== undefined) { - return this.cache[message]; - } - var parts = this.bindinqLanguage.parseInterpolation(null, message); - if (parts === null) { - return new aurelia_binding_1.LiteralString(message); - } - var expression = new aurelia_binding_1.LiteralString(parts[0]); - for (var i = 1; i < parts.length; i += 2) { - expression = new aurelia_binding_1.Binary('+', expression, new aurelia_binding_1.Binary('+', this.coalesce(parts[i]), new aurelia_binding_1.LiteralString(parts[i + 1]))); - } - MessageExpressionValidator.validate(expression, message); - this.cache[message] = expression; - return expression; - }; - ValidationMessageParser.prototype.coalesce = function (part) { - // part === null || part === undefined ? '' : part - return new aurelia_binding_1.Conditional(new aurelia_binding_1.Binary('||', new aurelia_binding_1.Binary('===', part, this.nullExpression), new aurelia_binding_1.Binary('===', part, this.undefinedExpression)), this.emptyStringExpression, new aurelia_binding_1.CallMember(part, 'toString', [])); - }; - ValidationMessageParser.inject = [aurelia_templating_1.BindingLanguage]; - return ValidationMessageParser; -}()); -exports.ValidationMessageParser = ValidationMessageParser; -var MessageExpressionValidator = /** @class */ (function (_super) { - __extends(MessageExpressionValidator, _super); - function MessageExpressionValidator(originalMessage) { - var _this = _super.call(this) || this; - _this.originalMessage = originalMessage; - return _this; - } - MessageExpressionValidator.validate = function (expression, originalMessage) { - var visitor = new MessageExpressionValidator(originalMessage); - expression.accept(visitor); - }; - MessageExpressionValidator.prototype.visitAccessScope = function (access) { - if (access.ancestor !== 0) { - throw new Error('$parent is not permitted in validation message expressions.'); - } - if (['displayName', 'propertyName', 'value', 'object', 'config', 'getDisplayName'].indexOf(access.name) !== -1) { - LogManager.getLogger('aurelia-validation') - .warn("Did you mean to use \"$" + access.name + "\" instead of \"" + access.name + "\" in this validation message template: \"" + this.originalMessage + "\"?"); - } - }; - return MessageExpressionValidator; -}(expression_visitor_1.ExpressionVisitor)); -exports.MessageExpressionValidator = MessageExpressionValidator; diff --git a/dist/commonjs/implementation/validation-messages.js b/dist/commonjs/implementation/validation-messages.js deleted file mode 100644 index da7d8980..00000000 --- a/dist/commonjs/implementation/validation-messages.js +++ /dev/null @@ -1,60 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var validation_message_parser_1 = require("./validation-message-parser"); -/** - * Dictionary of validation messages. [messageKey]: messageExpression - */ -exports.validationMessages = { - /** - * The default validation message. Used with rules that have no standard message. - */ - default: "${$displayName} is invalid.", - required: "${$displayName} is required.", - matches: "${$displayName} is not correctly formatted.", - email: "${$displayName} is not a valid email.", - minLength: "${$displayName} must be at least ${$config.length} character${$config.length === 1 ? '' : 's'}.", - maxLength: "${$displayName} cannot be longer than ${$config.length} character${$config.length === 1 ? '' : 's'}.", - minItems: "${$displayName} must contain at least ${$config.count} item${$config.count === 1 ? '' : 's'}.", - maxItems: "${$displayName} cannot contain more than ${$config.count} item${$config.count === 1 ? '' : 's'}.", - equals: "${$displayName} must be ${$config.expectedValue}.", -}; -/** - * Retrieves validation messages and property display names. - */ -var ValidationMessageProvider = /** @class */ (function () { - function ValidationMessageProvider(parser) { - this.parser = parser; - } - /** - * Returns a message binding expression that corresponds to the key. - * @param key The message key. - */ - ValidationMessageProvider.prototype.getMessage = function (key) { - var message; - if (key in exports.validationMessages) { - message = exports.validationMessages[key]; - } - else { - message = exports.validationMessages['default']; - } - return this.parser.parse(message); - }; - /** - * Formulates a property display name using the property name and the configured - * displayName (if provided). - * Override this with your own custom logic. - * @param propertyName The property name. - */ - ValidationMessageProvider.prototype.getDisplayName = function (propertyName, displayName) { - if (displayName !== null && displayName !== undefined) { - return (displayName instanceof Function) ? displayName() : displayName; - } - // split on upper-case letters. - var words = propertyName.toString().split(/(?=[A-Z])/).join(' '); - // capitalize first letter. - return words.charAt(0).toUpperCase() + words.slice(1); - }; - ValidationMessageProvider.inject = [validation_message_parser_1.ValidationMessageParser]; - return ValidationMessageProvider; -}()); -exports.ValidationMessageProvider = ValidationMessageProvider; diff --git a/dist/commonjs/implementation/validation-rules.js b/dist/commonjs/implementation/validation-rules.js deleted file mode 100644 index 20acb56f..00000000 --- a/dist/commonjs/implementation/validation-rules.js +++ /dev/null @@ -1,444 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var rules_1 = require("./rules"); -var validation_messages_1 = require("./validation-messages"); -var util_1 = require("../util"); -/** - * Part of the fluent rule API. Enables customizing property rules. - */ -var FluentRuleCustomizer = /** @class */ (function () { - function FluentRuleCustomizer(property, condition, config, fluentEnsure, fluentRules, parsers) { - if (config === void 0) { config = {}; } - this.fluentEnsure = fluentEnsure; - this.fluentRules = fluentRules; - this.parsers = parsers; - this.rule = { - property: property, - condition: condition, - config: config, - when: null, - messageKey: 'default', - message: null, - sequence: fluentRules.sequence - }; - this.fluentEnsure._addRule(this.rule); - } - /** - * Validate subsequent rules after previously declared rules have - * been validated successfully. Use to postpone validation of costly - * rules until less expensive rules pass validation. - */ - FluentRuleCustomizer.prototype.then = function () { - this.fluentRules.sequence++; - return this; - }; - /** - * Specifies the key to use when looking up the rule's validation message. - */ - FluentRuleCustomizer.prototype.withMessageKey = function (key) { - this.rule.messageKey = key; - this.rule.message = null; - return this; - }; - /** - * Specifies rule's validation message. - */ - FluentRuleCustomizer.prototype.withMessage = function (message) { - this.rule.messageKey = 'custom'; - this.rule.message = this.parsers.message.parse(message); - return this; - }; - /** - * Specifies a condition that must be met before attempting to validate the rule. - * @param condition A function that accepts the object as a parameter and returns true - * or false whether the rule should be evaluated. - */ - FluentRuleCustomizer.prototype.when = function (condition) { - this.rule.when = condition; - return this; - }; - /** - * Tags the rule instance, enabling the rule to be found easily - * using ValidationRules.taggedRules(rules, tag) - */ - FluentRuleCustomizer.prototype.tag = function (tag) { - this.rule.tag = tag; - return this; - }; - ///// FluentEnsure APIs ///// - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - FluentRuleCustomizer.prototype.ensure = function (subject) { - return this.fluentEnsure.ensure(subject); - }; - /** - * Targets an object with validation rules. - */ - FluentRuleCustomizer.prototype.ensureObject = function () { - return this.fluentEnsure.ensureObject(); - }; - Object.defineProperty(FluentRuleCustomizer.prototype, "rules", { - /** - * Rules that have been defined using the fluent API. - */ - get: function () { - return this.fluentEnsure.rules; - }, - enumerable: true, - configurable: true - }); - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - FluentRuleCustomizer.prototype.on = function (target) { - return this.fluentEnsure.on(target); - }; - ///////// FluentRules APIs ///////// - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - FluentRuleCustomizer.prototype.satisfies = function (condition, config) { - return this.fluentRules.satisfies(condition, config); - }; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - FluentRuleCustomizer.prototype.satisfiesRule = function (name) { - var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; - } - return (_a = this.fluentRules).satisfiesRule.apply(_a, [name].concat(args)); - var _a; - }; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - FluentRuleCustomizer.prototype.required = function () { - return this.fluentRules.required(); - }; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.matches = function (regex) { - return this.fluentRules.matches(regex); - }; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.email = function () { - return this.fluentRules.email(); - }; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.minLength = function (length) { - return this.fluentRules.minLength(length); - }; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.maxLength = function (length) { - return this.fluentRules.maxLength(length); - }; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRuleCustomizer.prototype.minItems = function (count) { - return this.fluentRules.minItems(count); - }; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRuleCustomizer.prototype.maxItems = function (count) { - return this.fluentRules.maxItems(count); - }; - /** - * Applies the "equals" validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.equals = function (expectedValue) { - return this.fluentRules.equals(expectedValue); - }; - return FluentRuleCustomizer; -}()); -exports.FluentRuleCustomizer = FluentRuleCustomizer; -/** - * Part of the fluent rule API. Enables applying rules to properties and objects. - */ -var FluentRules = /** @class */ (function () { - function FluentRules(fluentEnsure, parsers, property) { - this.fluentEnsure = fluentEnsure; - this.parsers = parsers; - this.property = property; - /** - * Current rule sequence number. Used to postpone evaluation of rules until rules - * with lower sequence number have successfully validated. The "then" fluent API method - * manages this property, there's usually no need to set it directly. - */ - this.sequence = 0; - } - /** - * Sets the display name of the ensured property. - */ - FluentRules.prototype.displayName = function (name) { - this.property.displayName = name; - return this; - }; - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - FluentRules.prototype.satisfies = function (condition, config) { - return new FluentRuleCustomizer(this.property, condition, config, this.fluentEnsure, this, this.parsers); - }; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - FluentRules.prototype.satisfiesRule = function (name) { - var _this = this; - var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; - } - var rule = FluentRules.customRules[name]; - if (!rule) { - // standard rule? - rule = this[name]; - if (rule instanceof Function) { - return rule.call.apply(rule, [this].concat(args)); - } - throw new Error("Rule with name \"" + name + "\" does not exist."); - } - var config = rule.argsToConfig ? rule.argsToConfig.apply(rule, args) : undefined; - return this.satisfies(function (value, obj) { - return (_a = rule.condition).call.apply(_a, [_this, value, obj].concat(args)); - var _a; - }, config) - .withMessageKey(name); - }; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - FluentRules.prototype.required = function () { - return this.satisfies(function (value) { - return value !== null - && value !== undefined - && !(util_1.isString(value) && !/\S/.test(value)); - }).withMessageKey('required'); - }; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - FluentRules.prototype.matches = function (regex) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || regex.test(value); }) - .withMessageKey('matches'); - }; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRules.prototype.email = function () { - // regex from https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address - /* tslint:disable:max-line-length */ - return this.matches(/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/) - .withMessageKey('email'); - }; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRules.prototype.minLength = function (length) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || value.length >= length; }, { length: length }) - .withMessageKey('minLength'); - }; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRules.prototype.maxLength = function (length) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || value.length <= length; }, { length: length }) - .withMessageKey('maxLength'); - }; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRules.prototype.minItems = function (count) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length >= count; }, { count: count }) - .withMessageKey('minItems'); - }; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRules.prototype.maxItems = function (count) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length <= count; }, { count: count }) - .withMessageKey('maxItems'); - }; - /** - * Applies the "equals" validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRules.prototype.equals = function (expectedValue) { - return this.satisfies(function (value) { return value === null || value === undefined || value === '' || value === expectedValue; }, { expectedValue: expectedValue }) - .withMessageKey('equals'); - }; - FluentRules.customRules = {}; - return FluentRules; -}()); -exports.FluentRules = FluentRules; -/** - * Part of the fluent rule API. Enables targeting properties and objects with rules. - */ -var FluentEnsure = /** @class */ (function () { - function FluentEnsure(parsers) { - this.parsers = parsers; - /** - * Rules that have been defined using the fluent API. - */ - this.rules = []; - } - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor - * function. - */ - FluentEnsure.prototype.ensure = function (property) { - this.assertInitialized(); - var name = this.parsers.property.parse(property); - var fluentRules = new FluentRules(this, this.parsers, { name: name, displayName: null }); - return this.mergeRules(fluentRules, name); - }; - /** - * Targets an object with validation rules. - */ - FluentEnsure.prototype.ensureObject = function () { - this.assertInitialized(); - var fluentRules = new FluentRules(this, this.parsers, { name: null, displayName: null }); - return this.mergeRules(fluentRules, null); - }; - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - FluentEnsure.prototype.on = function (target) { - rules_1.Rules.set(target, this.rules); - return this; - }; - /** - * Adds a rule definition to the sequenced ruleset. - * @internal - */ - FluentEnsure.prototype._addRule = function (rule) { - while (this.rules.length < rule.sequence + 1) { - this.rules.push([]); - } - this.rules[rule.sequence].push(rule); - }; - FluentEnsure.prototype.assertInitialized = function () { - if (this.parsers) { - return; - } - throw new Error("Did you forget to add \".plugin('aurelia-validation')\" to your main.js?"); - }; - FluentEnsure.prototype.mergeRules = function (fluentRules, propertyName) { - // tslint:disable-next-line:triple-equals | Use loose equality for property keys - var existingRules = this.rules.find(function (r) { return r.length > 0 && r[0].property.name == propertyName; }); - if (existingRules) { - var rule = existingRules[existingRules.length - 1]; - fluentRules.sequence = rule.sequence; - if (rule.property.displayName !== null) { - fluentRules = fluentRules.displayName(rule.property.displayName); - } - } - return fluentRules; - }; - return FluentEnsure; -}()); -exports.FluentEnsure = FluentEnsure; -/** - * Fluent rule definition API. - */ -var ValidationRules = /** @class */ (function () { - function ValidationRules() { - } - ValidationRules.initialize = function (messageParser, propertyParser) { - this.parsers = { - message: messageParser, - property: propertyParser - }; - }; - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - ValidationRules.ensure = function (property) { - return new FluentEnsure(ValidationRules.parsers).ensure(property); - }; - /** - * Targets an object with validation rules. - */ - ValidationRules.ensureObject = function () { - return new FluentEnsure(ValidationRules.parsers).ensureObject(); - }; - /** - * Defines a custom rule. - * @param name The name of the custom rule. Also serves as the message key. - * @param condition The rule function. - * @param message The message expression - * @param argsToConfig A function that maps the rule's arguments to a "config" - * object that can be used when evaluating the message expression. - */ - ValidationRules.customRule = function (name, condition, message, argsToConfig) { - validation_messages_1.validationMessages[name] = message; - FluentRules.customRules[name] = { condition: condition, argsToConfig: argsToConfig }; - }; - /** - * Returns rules with the matching tag. - * @param rules The rules to search. - * @param tag The tag to search for. - */ - ValidationRules.taggedRules = function (rules, tag) { - return rules.map(function (x) { return x.filter(function (r) { return r.tag === tag; }); }); - }; - /** - * Returns rules that have no tag. - * @param rules The rules to search. - */ - ValidationRules.untaggedRules = function (rules) { - return rules.map(function (x) { return x.filter(function (r) { return r.tag === undefined; }); }); - }; - /** - * Removes the rules from a class or object. - * @param target A class or object. - */ - ValidationRules.off = function (target) { - rules_1.Rules.unset(target); - }; - return ValidationRules; -}()); -exports.ValidationRules = ValidationRules; diff --git a/dist/commonjs/property-accessor-parser.d.ts b/dist/commonjs/property-accessor-parser.d.ts deleted file mode 100644 index ba64614b..00000000 --- a/dist/commonjs/property-accessor-parser.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Parser } from 'aurelia-binding'; -export declare type PropertyAccessor = (object: TObject) => TValue; -export declare class PropertyAccessorParser { - private parser; - static inject: (typeof Parser)[]; - constructor(parser: Parser); - parse(property: string | number | PropertyAccessor): string | number; -} -export declare function getAccessorExpression(fn: string): string; diff --git a/dist/commonjs/property-accessor-parser.js b/dist/commonjs/property-accessor-parser.js deleted file mode 100644 index 439eb57f..00000000 --- a/dist/commonjs/property-accessor-parser.js +++ /dev/null @@ -1,36 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var aurelia_binding_1 = require("aurelia-binding"); -var util_1 = require("./util"); -var PropertyAccessorParser = /** @class */ (function () { - function PropertyAccessorParser(parser) { - this.parser = parser; - } - PropertyAccessorParser.prototype.parse = function (property) { - if (util_1.isString(property) || util_1.isNumber(property)) { - return property; - } - var accessorText = getAccessorExpression(property.toString()); - var accessor = this.parser.parse(accessorText); - if (accessor instanceof aurelia_binding_1.AccessScope - || accessor instanceof aurelia_binding_1.AccessMember && accessor.object instanceof aurelia_binding_1.AccessScope) { - return accessor.name; - } - throw new Error("Invalid property expression: \"" + accessor + "\""); - }; - PropertyAccessorParser.inject = [aurelia_binding_1.Parser]; - return PropertyAccessorParser; -}()); -exports.PropertyAccessorParser = PropertyAccessorParser; -function getAccessorExpression(fn) { - /* tslint:disable:max-line-length */ - var classic = /^function\s*\([$_\w\d]+\)\s*\{(?:\s*"use strict";)?\s*(?:[$_\w\d.['"\]+;]+)?\s*return\s+[$_\w\d]+\.([$_\w\d]+)\s*;?\s*\}$/; - /* tslint:enable:max-line-length */ - var arrow = /^\(?[$_\w\d]+\)?\s*=>\s*[$_\w\d]+\.([$_\w\d]+)$/; - var match = classic.exec(fn) || arrow.exec(fn); - if (match === null) { - throw new Error("Unable to parse accessor function:\n" + fn); - } - return match[1]; -} -exports.getAccessorExpression = getAccessorExpression; diff --git a/dist/commonjs/property-info.d.ts b/dist/commonjs/property-info.d.ts deleted file mode 100644 index 35fef1d5..00000000 --- a/dist/commonjs/property-info.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Expression, Scope } from 'aurelia-binding'; -/** - * Retrieves the object and property name for the specified expression. - * @param expression The expression - * @param source The scope - */ -export declare function getPropertyInfo(expression: Expression, source: Scope): { - object: object; - propertyName: string; -} | null; diff --git a/dist/commonjs/property-info.js b/dist/commonjs/property-info.js deleted file mode 100644 index de2a9028..00000000 --- a/dist/commonjs/property-info.js +++ /dev/null @@ -1,44 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var aurelia_binding_1 = require("aurelia-binding"); -function getObject(expression, objectExpression, source) { - var value = objectExpression.evaluate(source, null); - if (value === null || value === undefined || value instanceof Object) { - return value; - } - // tslint:disable-next-line:max-line-length - throw new Error("The '" + objectExpression + "' part of '" + expression + "' evaluates to " + value + " instead of an object, null or undefined."); -} -/** - * Retrieves the object and property name for the specified expression. - * @param expression The expression - * @param source The scope - */ -function getPropertyInfo(expression, source) { - var originalExpression = expression; - while (expression instanceof aurelia_binding_1.BindingBehavior || expression instanceof aurelia_binding_1.ValueConverter) { - expression = expression.expression; - } - var object; - var propertyName; - if (expression instanceof aurelia_binding_1.AccessScope) { - object = aurelia_binding_1.getContextFor(expression.name, source, expression.ancestor); - propertyName = expression.name; - } - else if (expression instanceof aurelia_binding_1.AccessMember) { - object = getObject(originalExpression, expression.object, source); - propertyName = expression.name; - } - else if (expression instanceof aurelia_binding_1.AccessKeyed) { - object = getObject(originalExpression, expression.object, source); - propertyName = expression.key.evaluate(source); - } - else { - throw new Error("Expression '" + originalExpression + "' is not compatible with the validate binding-behavior."); - } - if (object === null || object === undefined) { - return null; - } - return { object: object, propertyName: propertyName }; -} -exports.getPropertyInfo = getPropertyInfo; diff --git a/dist/commonjs/util.d.ts b/dist/commonjs/util.d.ts deleted file mode 100644 index f6873f03..00000000 --- a/dist/commonjs/util.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export declare function isString(value: any): boolean; -export declare function isNumber(value: any): boolean; diff --git a/dist/commonjs/util.js b/dist/commonjs/util.js deleted file mode 100644 index 7829c8b1..00000000 --- a/dist/commonjs/util.js +++ /dev/null @@ -1,10 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -function isString(value) { - return Object.prototype.toString.call(value) === '[object String]'; -} -exports.isString = isString; -function isNumber(value) { - return Object.prototype.toString.call(value) === '[object Number]'; -} -exports.isNumber = isNumber; diff --git a/dist/commonjs/validate-binding-behavior-base.d.ts b/dist/commonjs/validate-binding-behavior-base.d.ts deleted file mode 100644 index 971c8e83..00000000 --- a/dist/commonjs/validate-binding-behavior-base.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { TaskQueue } from 'aurelia-task-queue'; -import { ValidationController } from './validation-controller'; -import { validateTrigger } from './validate-trigger'; -/** - * Binding behavior. Indicates the bound property should be validated. - */ -export declare abstract class ValidateBindingBehaviorBase { - private taskQueue; - constructor(taskQueue: TaskQueue); - protected abstract getValidateTrigger(controller: ValidationController): validateTrigger; - bind(binding: any, source: any, rulesOrController?: ValidationController | any, rules?: any): void; - unbind(binding: any): void; -} diff --git a/dist/commonjs/validate-binding-behavior-base.js b/dist/commonjs/validate-binding-behavior-base.js deleted file mode 100644 index f5b6d775..00000000 --- a/dist/commonjs/validate-binding-behavior-base.js +++ /dev/null @@ -1,81 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var aurelia_dependency_injection_1 = require("aurelia-dependency-injection"); -var validation_controller_1 = require("./validation-controller"); -var validate_trigger_1 = require("./validate-trigger"); -var get_target_dom_element_1 = require("./get-target-dom-element"); -/** - * Binding behavior. Indicates the bound property should be validated. - */ -var ValidateBindingBehaviorBase = /** @class */ (function () { - function ValidateBindingBehaviorBase(taskQueue) { - this.taskQueue = taskQueue; - } - ValidateBindingBehaviorBase.prototype.bind = function (binding, source, rulesOrController, rules) { - var _this = this; - // identify the target element. - var target = get_target_dom_element_1.getTargetDOMElement(binding, source); - // locate the controller. - var controller; - if (rulesOrController instanceof validation_controller_1.ValidationController) { - controller = rulesOrController; - } - else { - controller = source.container.get(aurelia_dependency_injection_1.Optional.of(validation_controller_1.ValidationController)); - rules = rulesOrController; - } - if (controller === null) { - throw new Error("A ValidationController has not been registered."); - } - controller.registerBinding(binding, target, rules); - binding.validationController = controller; - var trigger = this.getValidateTrigger(controller); - // tslint:disable-next-line:no-bitwise - if (trigger & validate_trigger_1.validateTrigger.change) { - binding.vbbUpdateSource = binding.updateSource; - // tslint:disable-next-line:only-arrow-functions - // tslint:disable-next-line:space-before-function-paren - binding.updateSource = function (value) { - this.vbbUpdateSource(value); - this.validationController.validateBinding(this); - }; - } - // tslint:disable-next-line:no-bitwise - if (trigger & validate_trigger_1.validateTrigger.blur) { - binding.validateBlurHandler = function () { - _this.taskQueue.queueMicroTask(function () { return controller.validateBinding(binding); }); - }; - binding.validateTarget = target; - target.addEventListener('blur', binding.validateBlurHandler); - } - if (trigger !== validate_trigger_1.validateTrigger.manual) { - binding.standardUpdateTarget = binding.updateTarget; - // tslint:disable-next-line:only-arrow-functions - // tslint:disable-next-line:space-before-function-paren - binding.updateTarget = function (value) { - this.standardUpdateTarget(value); - this.validationController.resetBinding(this); - }; - } - }; - ValidateBindingBehaviorBase.prototype.unbind = function (binding) { - // reset the binding to it's original state. - if (binding.vbbUpdateSource) { - binding.updateSource = binding.vbbUpdateSource; - binding.vbbUpdateSource = null; - } - if (binding.standardUpdateTarget) { - binding.updateTarget = binding.standardUpdateTarget; - binding.standardUpdateTarget = null; - } - if (binding.validateBlurHandler) { - binding.validateTarget.removeEventListener('blur', binding.validateBlurHandler); - binding.validateBlurHandler = null; - binding.validateTarget = null; - } - binding.validationController.unregisterBinding(binding); - binding.validationController = null; - }; - return ValidateBindingBehaviorBase; -}()); -exports.ValidateBindingBehaviorBase = ValidateBindingBehaviorBase; diff --git a/dist/commonjs/validate-binding-behavior.d.ts b/dist/commonjs/validate-binding-behavior.d.ts deleted file mode 100644 index 08b5d9e0..00000000 --- a/dist/commonjs/validate-binding-behavior.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { TaskQueue } from 'aurelia-task-queue'; -import { ValidationController } from './validation-controller'; -import { validateTrigger } from './validate-trigger'; -import { ValidateBindingBehaviorBase } from './validate-binding-behavior-base'; -/** - * Binding behavior. Indicates the bound property should be validated - * when the validate trigger specified by the associated controller's - * validateTrigger property occurs. - */ -export declare class ValidateBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(controller: ValidationController): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property will be validated - * manually, by calling controller.validate(). No automatic validation - * triggered by data-entry or blur will occur. - */ -export declare class ValidateManuallyBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs. - */ -export declare class ValidateOnBlurBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element is changed by the user, causing a change - * to the model. - */ -export declare class ValidateOnChangeBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs or is changed by the user, causing - * a change to the model. - */ -export declare class ValidateOnChangeOrBlurBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} diff --git a/dist/commonjs/validate-binding-behavior.js b/dist/commonjs/validate-binding-behavior.js deleted file mode 100644 index 2615f89d..00000000 --- a/dist/commonjs/validate-binding-behavior.js +++ /dev/null @@ -1,99 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var aurelia_task_queue_1 = require("aurelia-task-queue"); -var validate_trigger_1 = require("./validate-trigger"); -var validate_binding_behavior_base_1 = require("./validate-binding-behavior-base"); -/** - * Binding behavior. Indicates the bound property should be validated - * when the validate trigger specified by the associated controller's - * validateTrigger property occurs. - */ -var ValidateBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateBindingBehavior, _super); - function ValidateBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateBindingBehavior.prototype.getValidateTrigger = function (controller) { - return controller.validateTrigger; - }; - ValidateBindingBehavior.inject = [aurelia_task_queue_1.TaskQueue]; - return ValidateBindingBehavior; -}(validate_binding_behavior_base_1.ValidateBindingBehaviorBase)); -exports.ValidateBindingBehavior = ValidateBindingBehavior; -/** - * Binding behavior. Indicates the bound property will be validated - * manually, by calling controller.validate(). No automatic validation - * triggered by data-entry or blur will occur. - */ -var ValidateManuallyBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateManuallyBindingBehavior, _super); - function ValidateManuallyBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateManuallyBindingBehavior.prototype.getValidateTrigger = function () { - return validate_trigger_1.validateTrigger.manual; - }; - ValidateManuallyBindingBehavior.inject = [aurelia_task_queue_1.TaskQueue]; - return ValidateManuallyBindingBehavior; -}(validate_binding_behavior_base_1.ValidateBindingBehaviorBase)); -exports.ValidateManuallyBindingBehavior = ValidateManuallyBindingBehavior; -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs. - */ -var ValidateOnBlurBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateOnBlurBindingBehavior, _super); - function ValidateOnBlurBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateOnBlurBindingBehavior.prototype.getValidateTrigger = function () { - return validate_trigger_1.validateTrigger.blur; - }; - ValidateOnBlurBindingBehavior.inject = [aurelia_task_queue_1.TaskQueue]; - return ValidateOnBlurBindingBehavior; -}(validate_binding_behavior_base_1.ValidateBindingBehaviorBase)); -exports.ValidateOnBlurBindingBehavior = ValidateOnBlurBindingBehavior; -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element is changed by the user, causing a change - * to the model. - */ -var ValidateOnChangeBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateOnChangeBindingBehavior, _super); - function ValidateOnChangeBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateOnChangeBindingBehavior.prototype.getValidateTrigger = function () { - return validate_trigger_1.validateTrigger.change; - }; - ValidateOnChangeBindingBehavior.inject = [aurelia_task_queue_1.TaskQueue]; - return ValidateOnChangeBindingBehavior; -}(validate_binding_behavior_base_1.ValidateBindingBehaviorBase)); -exports.ValidateOnChangeBindingBehavior = ValidateOnChangeBindingBehavior; -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs or is changed by the user, causing - * a change to the model. - */ -var ValidateOnChangeOrBlurBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateOnChangeOrBlurBindingBehavior, _super); - function ValidateOnChangeOrBlurBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateOnChangeOrBlurBindingBehavior.prototype.getValidateTrigger = function () { - return validate_trigger_1.validateTrigger.changeOrBlur; - }; - ValidateOnChangeOrBlurBindingBehavior.inject = [aurelia_task_queue_1.TaskQueue]; - return ValidateOnChangeOrBlurBindingBehavior; -}(validate_binding_behavior_base_1.ValidateBindingBehaviorBase)); -exports.ValidateOnChangeOrBlurBindingBehavior = ValidateOnChangeOrBlurBindingBehavior; diff --git a/dist/commonjs/validate-event.d.ts b/dist/commonjs/validate-event.d.ts deleted file mode 100644 index 0fbacbb7..00000000 --- a/dist/commonjs/validate-event.d.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { ValidateResult } from './validate-result'; -import { ValidateInstruction } from './validate-instruction'; -import { ControllerValidateResult } from './controller-validate-result'; -export declare class ValidateEvent { - /** - * The type of validate event. Either "validate" or "reset". - */ - readonly type: 'validate' | 'reset'; - /** - * The controller's current array of errors. For an array containing both - * failed rules and passed rules, use the "results" property. - */ - readonly errors: ValidateResult[]; - /** - * The controller's current array of validate results. This - * includes both passed rules and failed rules. For an array of only failed rules, - * use the "errors" property. - */ - readonly results: ValidateResult[]; - /** - * The instruction passed to the "validate" or "reset" event. Will be null when - * the controller's validate/reset method was called with no instruction argument. - */ - readonly instruction: ValidateInstruction | null; - /** - * In events with type === "validate", this property will contain the result - * of validating the instruction (see "instruction" property). Use the controllerValidateResult - * to access the validate results specific to the call to "validate" - * (as opposed to using the "results" and "errors" properties to access the controller's entire - * set of results/errors). - */ - readonly controllerValidateResult: ControllerValidateResult | null; - constructor( - /** - * The type of validate event. Either "validate" or "reset". - */ - type: 'validate' | 'reset', - /** - * The controller's current array of errors. For an array containing both - * failed rules and passed rules, use the "results" property. - */ - errors: ValidateResult[], - /** - * The controller's current array of validate results. This - * includes both passed rules and failed rules. For an array of only failed rules, - * use the "errors" property. - */ - results: ValidateResult[], - /** - * The instruction passed to the "validate" or "reset" event. Will be null when - * the controller's validate/reset method was called with no instruction argument. - */ - instruction: ValidateInstruction | null, - /** - * In events with type === "validate", this property will contain the result - * of validating the instruction (see "instruction" property). Use the controllerValidateResult - * to access the validate results specific to the call to "validate" - * (as opposed to using the "results" and "errors" properties to access the controller's entire - * set of results/errors). - */ - controllerValidateResult: ControllerValidateResult | null); -} diff --git a/dist/commonjs/validate-event.js b/dist/commonjs/validate-event.js deleted file mode 100644 index bc2e1890..00000000 --- a/dist/commonjs/validate-event.js +++ /dev/null @@ -1,41 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var ValidateEvent = /** @class */ (function () { - function ValidateEvent( - /** - * The type of validate event. Either "validate" or "reset". - */ - type, - /** - * The controller's current array of errors. For an array containing both - * failed rules and passed rules, use the "results" property. - */ - errors, - /** - * The controller's current array of validate results. This - * includes both passed rules and failed rules. For an array of only failed rules, - * use the "errors" property. - */ - results, - /** - * The instruction passed to the "validate" or "reset" event. Will be null when - * the controller's validate/reset method was called with no instruction argument. - */ - instruction, - /** - * In events with type === "validate", this property will contain the result - * of validating the instruction (see "instruction" property). Use the controllerValidateResult - * to access the validate results specific to the call to "validate" - * (as opposed to using the "results" and "errors" properties to access the controller's entire - * set of results/errors). - */ - controllerValidateResult) { - this.type = type; - this.errors = errors; - this.results = results; - this.instruction = instruction; - this.controllerValidateResult = controllerValidateResult; - } - return ValidateEvent; -}()); -exports.ValidateEvent = ValidateEvent; diff --git a/dist/commonjs/validate-instruction.js b/dist/commonjs/validate-instruction.js deleted file mode 100644 index c8ad2e54..00000000 --- a/dist/commonjs/validate-instruction.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/dist/commonjs/validate-result.d.ts b/dist/commonjs/validate-result.d.ts deleted file mode 100644 index 91d79995..00000000 --- a/dist/commonjs/validate-result.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * The result of validating an individual validation rule. - */ -export declare class ValidateResult { - rule: any; - object: any; - propertyName: string | number | null; - valid: boolean; - message: string | null; - private static nextId; - /** - * A number that uniquely identifies the result instance. - */ - id: number; - /** - * @param rule The rule associated with the result. Validator implementation specific. - * @param object The object that was validated. - * @param propertyName The name of the property that was validated. - * @param error The error, if the result is a validation error. - */ - constructor(rule: any, object: any, propertyName: string | number | null, valid: boolean, message?: string | null); - toString(): string | null; -} diff --git a/dist/commonjs/validate-result.js b/dist/commonjs/validate-result.js deleted file mode 100644 index 04472b88..00000000 --- a/dist/commonjs/validate-result.js +++ /dev/null @@ -1,28 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * The result of validating an individual validation rule. - */ -var ValidateResult = /** @class */ (function () { - /** - * @param rule The rule associated with the result. Validator implementation specific. - * @param object The object that was validated. - * @param propertyName The name of the property that was validated. - * @param error The error, if the result is a validation error. - */ - function ValidateResult(rule, object, propertyName, valid, message) { - if (message === void 0) { message = null; } - this.rule = rule; - this.object = object; - this.propertyName = propertyName; - this.valid = valid; - this.message = message; - this.id = ValidateResult.nextId++; - } - ValidateResult.prototype.toString = function () { - return this.valid ? 'Valid.' : this.message; - }; - ValidateResult.nextId = 0; - return ValidateResult; -}()); -exports.ValidateResult = ValidateResult; diff --git a/dist/commonjs/validate-trigger.d.ts b/dist/commonjs/validate-trigger.d.ts deleted file mode 100644 index 43e76851..00000000 --- a/dist/commonjs/validate-trigger.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Validation triggers. - */ -export declare enum validateTrigger { - /** - * Manual validation. Use the controller's `validate()` and `reset()` methods - * to validate all bindings. - */ - manual = 0, - /** - * Validate the binding when the binding's target element fires a DOM "blur" event. - */ - blur = 1, - /** - * Validate the binding when it updates the model due to a change in the view. - */ - change = 2, - /** - * Validate the binding when the binding's target element fires a DOM "blur" event and - * when it updates the model due to a change in the view. - */ - changeOrBlur = 3, -} diff --git a/dist/commonjs/validate-trigger.js b/dist/commonjs/validate-trigger.js deleted file mode 100644 index ce6b8bb3..00000000 --- a/dist/commonjs/validate-trigger.js +++ /dev/null @@ -1,26 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * Validation triggers. - */ -var validateTrigger; -(function (validateTrigger) { - /** - * Manual validation. Use the controller's `validate()` and `reset()` methods - * to validate all bindings. - */ - validateTrigger[validateTrigger["manual"] = 0] = "manual"; - /** - * Validate the binding when the binding's target element fires a DOM "blur" event. - */ - validateTrigger[validateTrigger["blur"] = 1] = "blur"; - /** - * Validate the binding when it updates the model due to a change in the view. - */ - validateTrigger[validateTrigger["change"] = 2] = "change"; - /** - * Validate the binding when the binding's target element fires a DOM "blur" event and - * when it updates the model due to a change in the view. - */ - validateTrigger[validateTrigger["changeOrBlur"] = 3] = "changeOrBlur"; -})(validateTrigger = exports.validateTrigger || (exports.validateTrigger = {})); diff --git a/dist/commonjs/validation-controller-factory.d.ts b/dist/commonjs/validation-controller-factory.d.ts deleted file mode 100644 index 2c51999e..00000000 --- a/dist/commonjs/validation-controller-factory.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Container } from 'aurelia-dependency-injection'; -import { ValidationController } from './validation-controller'; -import { Validator } from './validator'; -/** - * Creates ValidationController instances. - */ -export declare class ValidationControllerFactory { - private container; - static get(container: Container): ValidationControllerFactory; - constructor(container: Container); - /** - * Creates a new controller instance. - */ - create(validator?: Validator): ValidationController; - /** - * Creates a new controller and registers it in the current element's container so that it's - * available to the validate binding behavior and renderers. - */ - createForCurrentScope(validator?: Validator): ValidationController; -} diff --git a/dist/commonjs/validation-controller-factory.js b/dist/commonjs/validation-controller-factory.js deleted file mode 100644 index 2cf50e22..00000000 --- a/dist/commonjs/validation-controller-factory.js +++ /dev/null @@ -1,38 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var validation_controller_1 = require("./validation-controller"); -var validator_1 = require("./validator"); -var property_accessor_parser_1 = require("./property-accessor-parser"); -/** - * Creates ValidationController instances. - */ -var ValidationControllerFactory = /** @class */ (function () { - function ValidationControllerFactory(container) { - this.container = container; - } - ValidationControllerFactory.get = function (container) { - return new ValidationControllerFactory(container); - }; - /** - * Creates a new controller instance. - */ - ValidationControllerFactory.prototype.create = function (validator) { - if (!validator) { - validator = this.container.get(validator_1.Validator); - } - var propertyParser = this.container.get(property_accessor_parser_1.PropertyAccessorParser); - return new validation_controller_1.ValidationController(validator, propertyParser); - }; - /** - * Creates a new controller and registers it in the current element's container so that it's - * available to the validate binding behavior and renderers. - */ - ValidationControllerFactory.prototype.createForCurrentScope = function (validator) { - var controller = this.create(validator); - this.container.registerInstance(validation_controller_1.ValidationController, controller); - return controller; - }; - return ValidationControllerFactory; -}()); -exports.ValidationControllerFactory = ValidationControllerFactory; -ValidationControllerFactory['protocol:aurelia:resolver'] = true; diff --git a/dist/commonjs/validation-controller.d.ts b/dist/commonjs/validation-controller.d.ts deleted file mode 100644 index 7f208d49..00000000 --- a/dist/commonjs/validation-controller.d.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { Binding } from 'aurelia-binding'; -import { Validator } from './validator'; -import { validateTrigger } from './validate-trigger'; -import { ValidationRenderer } from './validation-renderer'; -import { ValidateResult } from './validate-result'; -import { ValidateInstruction } from './validate-instruction'; -import { ControllerValidateResult } from './controller-validate-result'; -import { PropertyAccessorParser, PropertyAccessor } from './property-accessor-parser'; -import { ValidateEvent } from './validate-event'; -/** - * Orchestrates validation. - * Manages a set of bindings, renderers and objects. - * Exposes the current list of validation results for binding purposes. - */ -export declare class ValidationController { - private validator; - private propertyParser; - static inject: (typeof PropertyAccessorParser | typeof Validator)[]; - private bindings; - private renderers; - /** - * Validation results that have been rendered by the controller. - */ - private results; - /** - * Validation errors that have been rendered by the controller. - */ - errors: ValidateResult[]; - /** - * Whether the controller is currently validating. - */ - validating: boolean; - private elements; - private objects; - /** - * The trigger that will invoke automatic validation of a property used in a binding. - */ - validateTrigger: validateTrigger; - private finishValidating; - private eventCallbacks; - constructor(validator: Validator, propertyParser: PropertyAccessorParser); - /** - * Subscribe to controller validate and reset events. These events occur when the - * controller's "validate"" and "reset" methods are called. - * @param callback The callback to be invoked when the controller validates or resets. - */ - subscribe(callback: (event: ValidateEvent) => void): { - dispose: () => void; - }; - /** - * Adds an object to the set of objects that should be validated when validate is called. - * @param object The object. - * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. - */ - addObject(object: any, rules?: any): void; - /** - * Removes an object from the set of objects that should be validated when validate is called. - * @param object The object. - */ - removeObject(object: any): void; - /** - * Adds and renders an error. - */ - addError(message: string, object: TObject, propertyName?: string | PropertyAccessor | null): ValidateResult; - /** - * Removes and unrenders an error. - */ - removeError(result: ValidateResult): void; - /** - * Adds a renderer. - * @param renderer The renderer. - */ - addRenderer(renderer: ValidationRenderer): void; - /** - * Removes a renderer. - * @param renderer The renderer. - */ - removeRenderer(renderer: ValidationRenderer): void; - /** - * Registers a binding with the controller. - * @param binding The binding instance. - * @param target The DOM element. - * @param rules (optional) rules associated with the binding. Validator implementation specific. - */ - registerBinding(binding: Binding, target: Element, rules?: any): void; - /** - * Unregisters a binding with the controller. - * @param binding The binding instance. - */ - unregisterBinding(binding: Binding): void; - /** - * Interprets the instruction and returns a predicate that will identify - * relevant results in the list of rendered validation results. - */ - private getInstructionPredicate(instruction?); - /** - * Validates and renders results. - * @param instruction Optional. Instructions on what to validate. If undefined, all - * objects and bindings will be validated. - */ - validate(instruction?: ValidateInstruction): Promise; - /** - * Resets any rendered validation results (unrenders). - * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results - * will be unrendered. - */ - reset(instruction?: ValidateInstruction): void; - /** - * Gets the elements associated with an object and propertyName (if any). - */ - private getAssociatedElements({object, propertyName}); - private processResultDelta(kind, oldResults, newResults); - /** - * Validates the property associated with a binding. - */ - validateBinding(binding: Binding): void; - /** - * Resets the results for a property associated with a binding. - */ - resetBinding(binding: Binding): void; - /** - * Changes the controller's validateTrigger. - * @param newTrigger The new validateTrigger - */ - changeTrigger(newTrigger: validateTrigger): void; - /** - * Revalidates the controller's current set of errors. - */ - revalidateErrors(): void; - private invokeCallbacks(instruction, result); -} diff --git a/dist/commonjs/validation-controller.js b/dist/commonjs/validation-controller.js deleted file mode 100644 index 8d304766..00000000 --- a/dist/commonjs/validation-controller.js +++ /dev/null @@ -1,415 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var validator_1 = require("./validator"); -var validate_trigger_1 = require("./validate-trigger"); -var property_info_1 = require("./property-info"); -var validate_result_1 = require("./validate-result"); -var property_accessor_parser_1 = require("./property-accessor-parser"); -var validate_event_1 = require("./validate-event"); -/** - * Orchestrates validation. - * Manages a set of bindings, renderers and objects. - * Exposes the current list of validation results for binding purposes. - */ -var ValidationController = /** @class */ (function () { - function ValidationController(validator, propertyParser) { - this.validator = validator; - this.propertyParser = propertyParser; - // Registered bindings (via the validate binding behavior) - this.bindings = new Map(); - // Renderers that have been added to the controller instance. - this.renderers = []; - /** - * Validation results that have been rendered by the controller. - */ - this.results = []; - /** - * Validation errors that have been rendered by the controller. - */ - this.errors = []; - /** - * Whether the controller is currently validating. - */ - this.validating = false; - // Elements related to validation results that have been rendered. - this.elements = new Map(); - // Objects that have been added to the controller instance (entity-style validation). - this.objects = new Map(); - /** - * The trigger that will invoke automatic validation of a property used in a binding. - */ - this.validateTrigger = validate_trigger_1.validateTrigger.blur; - // Promise that resolves when validation has completed. - this.finishValidating = Promise.resolve(); - this.eventCallbacks = []; - } - /** - * Subscribe to controller validate and reset events. These events occur when the - * controller's "validate"" and "reset" methods are called. - * @param callback The callback to be invoked when the controller validates or resets. - */ - ValidationController.prototype.subscribe = function (callback) { - var _this = this; - this.eventCallbacks.push(callback); - return { - dispose: function () { - var index = _this.eventCallbacks.indexOf(callback); - if (index === -1) { - return; - } - _this.eventCallbacks.splice(index, 1); - } - }; - }; - /** - * Adds an object to the set of objects that should be validated when validate is called. - * @param object The object. - * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. - */ - ValidationController.prototype.addObject = function (object, rules) { - this.objects.set(object, rules); - }; - /** - * Removes an object from the set of objects that should be validated when validate is called. - * @param object The object. - */ - ValidationController.prototype.removeObject = function (object) { - this.objects.delete(object); - this.processResultDelta('reset', this.results.filter(function (result) { return result.object === object; }), []); - }; - /** - * Adds and renders an error. - */ - ValidationController.prototype.addError = function (message, object, propertyName) { - if (propertyName === void 0) { propertyName = null; } - var resolvedPropertyName; - if (propertyName === null) { - resolvedPropertyName = propertyName; - } - else { - resolvedPropertyName = this.propertyParser.parse(propertyName); - } - var result = new validate_result_1.ValidateResult({ __manuallyAdded__: true }, object, resolvedPropertyName, false, message); - this.processResultDelta('validate', [], [result]); - return result; - }; - /** - * Removes and unrenders an error. - */ - ValidationController.prototype.removeError = function (result) { - if (this.results.indexOf(result) !== -1) { - this.processResultDelta('reset', [result], []); - } - }; - /** - * Adds a renderer. - * @param renderer The renderer. - */ - ValidationController.prototype.addRenderer = function (renderer) { - var _this = this; - this.renderers.push(renderer); - renderer.render({ - kind: 'validate', - render: this.results.map(function (result) { return ({ result: result, elements: _this.elements.get(result) }); }), - unrender: [] - }); - }; - /** - * Removes a renderer. - * @param renderer The renderer. - */ - ValidationController.prototype.removeRenderer = function (renderer) { - var _this = this; - this.renderers.splice(this.renderers.indexOf(renderer), 1); - renderer.render({ - kind: 'reset', - render: [], - unrender: this.results.map(function (result) { return ({ result: result, elements: _this.elements.get(result) }); }) - }); - }; - /** - * Registers a binding with the controller. - * @param binding The binding instance. - * @param target The DOM element. - * @param rules (optional) rules associated with the binding. Validator implementation specific. - */ - ValidationController.prototype.registerBinding = function (binding, target, rules) { - this.bindings.set(binding, { target: target, rules: rules, propertyInfo: null }); - }; - /** - * Unregisters a binding with the controller. - * @param binding The binding instance. - */ - ValidationController.prototype.unregisterBinding = function (binding) { - this.resetBinding(binding); - this.bindings.delete(binding); - }; - /** - * Interprets the instruction and returns a predicate that will identify - * relevant results in the list of rendered validation results. - */ - ValidationController.prototype.getInstructionPredicate = function (instruction) { - var _this = this; - if (instruction) { - var object_1 = instruction.object, propertyName_1 = instruction.propertyName, rules_1 = instruction.rules; - var predicate_1; - if (instruction.propertyName) { - predicate_1 = function (x) { return x.object === object_1 && x.propertyName === propertyName_1; }; - } - else { - predicate_1 = function (x) { return x.object === object_1; }; - } - if (rules_1) { - return function (x) { return predicate_1(x) && _this.validator.ruleExists(rules_1, x.rule); }; - } - return predicate_1; - } - else { - return function () { return true; }; - } - }; - /** - * Validates and renders results. - * @param instruction Optional. Instructions on what to validate. If undefined, all - * objects and bindings will be validated. - */ - ValidationController.prototype.validate = function (instruction) { - var _this = this; - // Get a function that will process the validation instruction. - var execute; - if (instruction) { - // tslint:disable-next-line:prefer-const - var object_2 = instruction.object, propertyName_2 = instruction.propertyName, rules_2 = instruction.rules; - // if rules were not specified, check the object map. - rules_2 = rules_2 || this.objects.get(object_2); - // property specified? - if (instruction.propertyName === undefined) { - // validate the specified object. - execute = function () { return _this.validator.validateObject(object_2, rules_2); }; - } - else { - // validate the specified property. - execute = function () { return _this.validator.validateProperty(object_2, propertyName_2, rules_2); }; - } - } - else { - // validate all objects and bindings. - execute = function () { - var promises = []; - for (var _i = 0, _a = Array.from(_this.objects); _i < _a.length; _i++) { - var _b = _a[_i], object = _b[0], rules = _b[1]; - promises.push(_this.validator.validateObject(object, rules)); - } - for (var _c = 0, _d = Array.from(_this.bindings); _c < _d.length; _c++) { - var _e = _d[_c], binding = _e[0], rules = _e[1].rules; - var propertyInfo = property_info_1.getPropertyInfo(binding.sourceExpression, binding.source); - if (!propertyInfo || _this.objects.has(propertyInfo.object)) { - continue; - } - promises.push(_this.validator.validateProperty(propertyInfo.object, propertyInfo.propertyName, rules)); - } - return Promise.all(promises).then(function (resultSets) { return resultSets.reduce(function (a, b) { return a.concat(b); }, []); }); - }; - } - // Wait for any existing validation to finish, execute the instruction, render the results. - this.validating = true; - var returnPromise = this.finishValidating - .then(execute) - .then(function (newResults) { - var predicate = _this.getInstructionPredicate(instruction); - var oldResults = _this.results.filter(predicate); - _this.processResultDelta('validate', oldResults, newResults); - if (returnPromise === _this.finishValidating) { - _this.validating = false; - } - var result = { - instruction: instruction, - valid: newResults.find(function (x) { return !x.valid; }) === undefined, - results: newResults - }; - _this.invokeCallbacks(instruction, result); - return result; - }) - .catch(function (exception) { - // recover, to enable subsequent calls to validate() - _this.validating = false; - _this.finishValidating = Promise.resolve(); - return Promise.reject(exception); - }); - this.finishValidating = returnPromise; - return returnPromise; - }; - /** - * Resets any rendered validation results (unrenders). - * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results - * will be unrendered. - */ - ValidationController.prototype.reset = function (instruction) { - var predicate = this.getInstructionPredicate(instruction); - var oldResults = this.results.filter(predicate); - this.processResultDelta('reset', oldResults, []); - this.invokeCallbacks(instruction, null); - }; - /** - * Gets the elements associated with an object and propertyName (if any). - */ - ValidationController.prototype.getAssociatedElements = function (_a) { - var object = _a.object, propertyName = _a.propertyName; - var elements = []; - for (var _i = 0, _b = Array.from(this.bindings); _i < _b.length; _i++) { - var _c = _b[_i], binding = _c[0], target = _c[1].target; - var propertyInfo = property_info_1.getPropertyInfo(binding.sourceExpression, binding.source); - if (propertyInfo && propertyInfo.object === object && propertyInfo.propertyName === propertyName) { - elements.push(target); - } - } - return elements; - }; - ValidationController.prototype.processResultDelta = function (kind, oldResults, newResults) { - // prepare the instruction. - var instruction = { - kind: kind, - render: [], - unrender: [] - }; - // create a shallow copy of newResults so we can mutate it without causing side-effects. - newResults = newResults.slice(0); - var _loop_1 = function (oldResult) { - // get the elements associated with the old result. - var elements = this_1.elements.get(oldResult); - // remove the old result from the element map. - this_1.elements.delete(oldResult); - // create the unrender instruction. - instruction.unrender.push({ result: oldResult, elements: elements }); - // determine if there's a corresponding new result for the old result we are unrendering. - var newResultIndex = newResults.findIndex(function (x) { return x.rule === oldResult.rule && x.object === oldResult.object && x.propertyName === oldResult.propertyName; }); - if (newResultIndex === -1) { - // no corresponding new result... simple remove. - this_1.results.splice(this_1.results.indexOf(oldResult), 1); - if (!oldResult.valid) { - this_1.errors.splice(this_1.errors.indexOf(oldResult), 1); - } - } - else { - // there is a corresponding new result... - var newResult = newResults.splice(newResultIndex, 1)[0]; - // get the elements that are associated with the new result. - var elements_1 = this_1.getAssociatedElements(newResult); - this_1.elements.set(newResult, elements_1); - // create a render instruction for the new result. - instruction.render.push({ result: newResult, elements: elements_1 }); - // do an in-place replacement of the old result with the new result. - // this ensures any repeats bound to this.results will not thrash. - this_1.results.splice(this_1.results.indexOf(oldResult), 1, newResult); - if (!oldResult.valid && newResult.valid) { - this_1.errors.splice(this_1.errors.indexOf(oldResult), 1); - } - else if (!oldResult.valid && !newResult.valid) { - this_1.errors.splice(this_1.errors.indexOf(oldResult), 1, newResult); - } - else if (!newResult.valid) { - this_1.errors.push(newResult); - } - } - }; - var this_1 = this; - // create unrender instructions from the old results. - for (var _i = 0, oldResults_1 = oldResults; _i < oldResults_1.length; _i++) { - var oldResult = oldResults_1[_i]; - _loop_1(oldResult); - } - // create render instructions from the remaining new results. - for (var _a = 0, newResults_1 = newResults; _a < newResults_1.length; _a++) { - var result = newResults_1[_a]; - var elements = this.getAssociatedElements(result); - instruction.render.push({ result: result, elements: elements }); - this.elements.set(result, elements); - this.results.push(result); - if (!result.valid) { - this.errors.push(result); - } - } - // render. - for (var _b = 0, _c = this.renderers; _b < _c.length; _b++) { - var renderer = _c[_b]; - renderer.render(instruction); - } - }; - /** - * Validates the property associated with a binding. - */ - ValidationController.prototype.validateBinding = function (binding) { - if (!binding.isBound) { - return; - } - var propertyInfo = property_info_1.getPropertyInfo(binding.sourceExpression, binding.source); - var rules; - var registeredBinding = this.bindings.get(binding); - if (registeredBinding) { - rules = registeredBinding.rules; - registeredBinding.propertyInfo = propertyInfo; - } - if (!propertyInfo) { - return; - } - var object = propertyInfo.object, propertyName = propertyInfo.propertyName; - this.validate({ object: object, propertyName: propertyName, rules: rules }); - }; - /** - * Resets the results for a property associated with a binding. - */ - ValidationController.prototype.resetBinding = function (binding) { - var registeredBinding = this.bindings.get(binding); - var propertyInfo = property_info_1.getPropertyInfo(binding.sourceExpression, binding.source); - if (!propertyInfo && registeredBinding) { - propertyInfo = registeredBinding.propertyInfo; - } - if (registeredBinding) { - registeredBinding.propertyInfo = null; - } - if (!propertyInfo) { - return; - } - var object = propertyInfo.object, propertyName = propertyInfo.propertyName; - this.reset({ object: object, propertyName: propertyName }); - }; - /** - * Changes the controller's validateTrigger. - * @param newTrigger The new validateTrigger - */ - ValidationController.prototype.changeTrigger = function (newTrigger) { - this.validateTrigger = newTrigger; - var bindings = Array.from(this.bindings.keys()); - for (var _i = 0, bindings_1 = bindings; _i < bindings_1.length; _i++) { - var binding = bindings_1[_i]; - var source = binding.source; - binding.unbind(); - binding.bind(source); - } - }; - /** - * Revalidates the controller's current set of errors. - */ - ValidationController.prototype.revalidateErrors = function () { - for (var _i = 0, _a = this.errors; _i < _a.length; _i++) { - var _b = _a[_i], object = _b.object, propertyName = _b.propertyName, rule = _b.rule; - if (rule.__manuallyAdded__) { - continue; - } - var rules = [[rule]]; - this.validate({ object: object, propertyName: propertyName, rules: rules }); - } - }; - ValidationController.prototype.invokeCallbacks = function (instruction, result) { - if (this.eventCallbacks.length === 0) { - return; - } - var event = new validate_event_1.ValidateEvent(result ? 'validate' : 'reset', this.errors, this.results, instruction || null, result); - for (var i = 0; i < this.eventCallbacks.length; i++) { - this.eventCallbacks[i](event); - } - }; - ValidationController.inject = [validator_1.Validator, property_accessor_parser_1.PropertyAccessorParser]; - return ValidationController; -}()); -exports.ValidationController = ValidationController; diff --git a/dist/commonjs/validation-errors-custom-attribute.js b/dist/commonjs/validation-errors-custom-attribute.js deleted file mode 100644 index e49ad8b9..00000000 --- a/dist/commonjs/validation-errors-custom-attribute.js +++ /dev/null @@ -1,84 +0,0 @@ -"use strict"; -var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -var aurelia_binding_1 = require("aurelia-binding"); -var aurelia_dependency_injection_1 = require("aurelia-dependency-injection"); -var aurelia_templating_1 = require("aurelia-templating"); -var validation_controller_1 = require("./validation-controller"); -var aurelia_pal_1 = require("aurelia-pal"); -var ValidationErrorsCustomAttribute = /** @class */ (function () { - function ValidationErrorsCustomAttribute(boundaryElement, controllerAccessor) { - this.boundaryElement = boundaryElement; - this.controllerAccessor = controllerAccessor; - this.controller = null; - this.errors = []; - this.errorsInternal = []; - } - ValidationErrorsCustomAttribute.inject = function () { return [aurelia_pal_1.DOM.Element, aurelia_dependency_injection_1.Lazy.of(validation_controller_1.ValidationController)]; }; - ValidationErrorsCustomAttribute.prototype.sort = function () { - this.errorsInternal.sort(function (a, b) { - if (a.targets[0] === b.targets[0]) { - return 0; - } - // tslint:disable-next-line:no-bitwise - return a.targets[0].compareDocumentPosition(b.targets[0]) & 2 ? 1 : -1; - }); - }; - ValidationErrorsCustomAttribute.prototype.interestingElements = function (elements) { - var _this = this; - return elements.filter(function (e) { return _this.boundaryElement.contains(e); }); - }; - ValidationErrorsCustomAttribute.prototype.render = function (instruction) { - var _loop_1 = function (result) { - var index = this_1.errorsInternal.findIndex(function (x) { return x.error === result; }); - if (index !== -1) { - this_1.errorsInternal.splice(index, 1); - } - }; - var this_1 = this; - for (var _i = 0, _a = instruction.unrender; _i < _a.length; _i++) { - var result = _a[_i].result; - _loop_1(result); - } - for (var _b = 0, _c = instruction.render; _b < _c.length; _b++) { - var _d = _c[_b], result = _d.result, elements = _d.elements; - if (result.valid) { - continue; - } - var targets = this.interestingElements(elements); - if (targets.length) { - this.errorsInternal.push({ error: result, targets: targets }); - } - } - this.sort(); - this.errors = this.errorsInternal; - }; - ValidationErrorsCustomAttribute.prototype.bind = function () { - if (!this.controller) { - this.controller = this.controllerAccessor(); - } - // this will call render() with the side-effect of updating this.errors - this.controller.addRenderer(this); - }; - ValidationErrorsCustomAttribute.prototype.unbind = function () { - if (this.controller) { - this.controller.removeRenderer(this); - } - }; - __decorate([ - aurelia_templating_1.bindable({ defaultBindingMode: aurelia_binding_1.bindingMode.oneWay }) - ], ValidationErrorsCustomAttribute.prototype, "controller", void 0); - __decorate([ - aurelia_templating_1.bindable({ primaryProperty: true, defaultBindingMode: aurelia_binding_1.bindingMode.twoWay }) - ], ValidationErrorsCustomAttribute.prototype, "errors", void 0); - ValidationErrorsCustomAttribute = __decorate([ - aurelia_templating_1.customAttribute('validation-errors') - ], ValidationErrorsCustomAttribute); - return ValidationErrorsCustomAttribute; -}()); -exports.ValidationErrorsCustomAttribute = ValidationErrorsCustomAttribute; diff --git a/dist/commonjs/validation-renderer-custom-attribute.js b/dist/commonjs/validation-renderer-custom-attribute.js deleted file mode 100644 index 19fb49a2..00000000 --- a/dist/commonjs/validation-renderer-custom-attribute.js +++ /dev/null @@ -1,22 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var validation_controller_1 = require("./validation-controller"); -var ValidationRendererCustomAttribute = /** @class */ (function () { - function ValidationRendererCustomAttribute() { - } - ValidationRendererCustomAttribute.prototype.created = function (view) { - this.container = view.container; - }; - ValidationRendererCustomAttribute.prototype.bind = function () { - this.controller = this.container.get(validation_controller_1.ValidationController); - this.renderer = this.container.get(this.value); - this.controller.addRenderer(this.renderer); - }; - ValidationRendererCustomAttribute.prototype.unbind = function () { - this.controller.removeRenderer(this.renderer); - this.controller = null; - this.renderer = null; - }; - return ValidationRendererCustomAttribute; -}()); -exports.ValidationRendererCustomAttribute = ValidationRendererCustomAttribute; diff --git a/dist/commonjs/validation-renderer.d.ts b/dist/commonjs/validation-renderer.d.ts deleted file mode 100644 index eb430d9d..00000000 --- a/dist/commonjs/validation-renderer.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { ValidateResult } from './validate-result'; -/** - * A result to render (or unrender) and the associated elements (if any) - */ -export interface ResultInstruction { - /** - * The validation result. - */ - result: ValidateResult; - /** - * The associated elements (if any). - */ - elements: Element[]; -} -/** - * Defines which validation results to render and which validation results to unrender. - */ -export interface RenderInstruction { - /** - * The "kind" of render instruction. Either 'validate' or 'reset'. - */ - kind: 'validate' | 'reset'; - /** - * The results to render. - */ - render: ResultInstruction[]; - /** - * The results to unrender. - */ - unrender: ResultInstruction[]; -} -/** - * Renders validation results. - */ -export interface ValidationRenderer { - /** - * Render the validation results. - * @param instruction The render instruction. Defines which results to render and which - * results to unrender. - */ - render(instruction: RenderInstruction): void; -} diff --git a/dist/commonjs/validation-renderer.js b/dist/commonjs/validation-renderer.js deleted file mode 100644 index c8ad2e54..00000000 --- a/dist/commonjs/validation-renderer.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/dist/commonjs/validator.d.ts b/dist/commonjs/validator.d.ts deleted file mode 100644 index 82c045e8..00000000 --- a/dist/commonjs/validator.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ValidateResult } from './validate-result'; -/** - * Validates objects and properties. - */ -export declare abstract class Validator { - /** - * Validates the specified property. - * @param object The object to validate. - * @param propertyName The name of the property to validate. - * @param rules Optional. If unspecified, the implementation should lookup the rules for the - * specified object. This may not be possible for all implementations of this interface. - */ - abstract validateProperty(object: any, propertyName: string, rules?: any): Promise; - /** - * Validates all rules for specified object and it's properties. - * @param object The object to validate. - * @param rules Optional. If unspecified, the implementation should lookup the rules for the - * specified object. This may not be possible for all implementations of this interface. - */ - abstract validateObject(object: any, rules?: any): Promise; - /** - * Determines whether a rule exists in a set of rules. - * @param rules The rules to search. - * @parem rule The rule to find. - */ - abstract ruleExists(rules: any, rule: any): boolean; -} diff --git a/dist/commonjs/validator.js b/dist/commonjs/validator.js deleted file mode 100644 index 85c66f91..00000000 --- a/dist/commonjs/validator.js +++ /dev/null @@ -1,11 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * Validates objects and properties. - */ -var Validator = /** @class */ (function () { - function Validator() { - } - return Validator; -}()); -exports.Validator = Validator; diff --git a/dist/es2015/aurelia-validation.d.ts b/dist/es2015/aurelia-validation.d.ts deleted file mode 100644 index d744ccfb..00000000 --- a/dist/es2015/aurelia-validation.d.ts +++ /dev/null @@ -1,46 +0,0 @@ -export * from './controller-validate-result'; -export * from './get-target-dom-element'; -export * from './property-info'; -export * from './property-accessor-parser'; -export * from './validate-binding-behavior'; -export * from './validate-event'; -export * from './validate-instruction'; -export * from './validate-result'; -export * from './validate-trigger'; -export * from './validation-controller'; -export * from './validation-controller-factory'; -export * from './validation-errors-custom-attribute'; -export * from './validation-renderer-custom-attribute'; -export * from './validation-renderer'; -export * from './validator'; -export * from './implementation/rule'; -export * from './implementation/rules'; -export * from './implementation/standard-validator'; -export * from './implementation/validation-messages'; -export * from './implementation/validation-message-parser'; -export * from './implementation/validation-rules'; -import { Container } from 'aurelia-dependency-injection'; -import { Validator } from './validator'; -/** - * Aurelia Validation Configuration API - */ -export declare class AureliaValidationConfiguration { - private validatorType; - /** - * Use a custom Validator implementation. - */ - customValidator(type: { - new (...args: any[]): Validator; - }): void; - /** - * Applies the configuration. - */ - apply(container: Container): void; -} -/** - * Configures the plugin. - */ -export declare function configure(frameworkConfig: { - container: Container; - globalResources?: (...resources: string[]) => any; -}, callback?: (config: AureliaValidationConfiguration) => void): void; diff --git a/dist/es2015/aurelia-validation.js b/dist/es2015/aurelia-validation.js index 63cb313e..9b95847a 100644 --- a/dist/es2015/aurelia-validation.js +++ b/dist/es2015/aurelia-validation.js @@ -1,66 +1,1647 @@ -// Exports -export * from './get-target-dom-element'; -export * from './property-info'; -export * from './property-accessor-parser'; -export * from './validate-binding-behavior'; -export * from './validate-event'; -export * from './validate-result'; -export * from './validate-trigger'; -export * from './validation-controller'; -export * from './validation-controller-factory'; -export * from './validation-errors-custom-attribute'; -export * from './validation-renderer-custom-attribute'; -export * from './validator'; -export * from './implementation/rules'; -export * from './implementation/standard-validator'; -export * from './implementation/validation-messages'; -export * from './implementation/validation-message-parser'; -export * from './implementation/validation-rules'; -// Configuration -import { PLATFORM } from 'aurelia-pal'; -import { Validator } from './validator'; -import { StandardValidator } from './implementation/standard-validator'; -import { ValidationMessageParser } from './implementation/validation-message-parser'; -import { PropertyAccessorParser } from './property-accessor-parser'; -import { ValidationRules } from './implementation/validation-rules'; -/** - * Aurelia Validation Configuration API - */ -export class AureliaValidationConfiguration { - constructor() { - this.validatorType = StandardValidator; - } - /** - * Use a custom Validator implementation. - */ - customValidator(type) { - this.validatorType = type; - } - /** - * Applies the configuration. - */ - apply(container) { - const validator = container.get(this.validatorType); - container.registerInstance(Validator, validator); - } +import { DOM } from 'aurelia-pal'; +import { AccessMember, AccessScope, AccessKeyed, BindingBehavior, ValueConverter, getContextFor, Parser, bindingMode, LiteralString, Binary, Conditional, LiteralPrimitive, CallMember } from 'aurelia-binding'; +import { Optional, Lazy } from 'aurelia-dependency-injection'; +import { TaskQueue } from 'aurelia-task-queue'; +import { customAttribute, bindable, BindingLanguage, ViewResources } from 'aurelia-templating'; +import { customAttribute as customAttribute$1 } from 'aurelia-framework'; +import { getLogger } from 'aurelia-logging'; + +/** + * Gets the DOM element associated with the data-binding. Most of the time it's + * the binding.target but sometimes binding.target is an aurelia custom element, + * or custom attribute which is a javascript "class" instance, so we need to use + * the controller's container to retrieve the actual DOM element. + */ +function getTargetDOMElement(binding, view) { + const target = binding.target; + // DOM element + if (target instanceof Element) { + return target; + } + // custom element or custom attribute + // tslint:disable-next-line:prefer-const + for (let i = 0, ii = view.controllers.length; i < ii; i++) { + const controller = view.controllers[i]; + if (controller.viewModel === target) { + const element = controller.container.get(DOM.Element); + if (element) { + return element; + } + throw new Error(`Unable to locate target element for "${binding.sourceExpression}".`); + } + } + throw new Error(`Unable to locate target element for "${binding.sourceExpression}".`); } -/** - * Configures the plugin. - */ -export function configure(frameworkConfig, callback) { - // the fluent rule definition API needs the parser to translate messages - // to interpolation expressions. - const messageParser = frameworkConfig.container.get(ValidationMessageParser); - const propertyParser = frameworkConfig.container.get(PropertyAccessorParser); - ValidationRules.initialize(messageParser, propertyParser); - // configure... - const config = new AureliaValidationConfiguration(); - if (callback instanceof Function) { - callback(config); - } - config.apply(frameworkConfig.container); - // globalize the behaviors. - if (frameworkConfig.globalResources) { - frameworkConfig.globalResources(PLATFORM.moduleName('./validate-binding-behavior'), PLATFORM.moduleName('./validation-errors-custom-attribute'), PLATFORM.moduleName('./validation-renderer-custom-attribute')); - } + +function getObject(expression, objectExpression, source) { + const value = objectExpression.evaluate(source, null); + if (value === null || value === undefined || value instanceof Object) { + return value; + } + // tslint:disable-next-line:max-line-length + throw new Error(`The '${objectExpression}' part of '${expression}' evaluates to ${value} instead of an object, null or undefined.`); +} +/** + * Retrieves the object and property name for the specified expression. + * @param expression The expression + * @param source The scope + */ +function getPropertyInfo(expression, source) { + const originalExpression = expression; + while (expression instanceof BindingBehavior || expression instanceof ValueConverter) { + expression = expression.expression; + } + let object; + let propertyName; + if (expression instanceof AccessScope) { + object = getContextFor(expression.name, source, expression.ancestor); + propertyName = expression.name; + } + else if (expression instanceof AccessMember) { + object = getObject(originalExpression, expression.object, source); + propertyName = expression.name; + } + else if (expression instanceof AccessKeyed) { + object = getObject(originalExpression, expression.object, source); + propertyName = expression.key.evaluate(source); + } + else { + throw new Error(`Expression '${originalExpression}' is not compatible with the validate binding-behavior.`); + } + if (object === null || object === undefined) { + return null; + } + return { object, propertyName }; } + +function isString(value) { + return Object.prototype.toString.call(value) === '[object String]'; +} +function isNumber(value) { + return Object.prototype.toString.call(value) === '[object Number]'; +} + +class PropertyAccessorParser { + constructor(parser) { + this.parser = parser; + } + parse(property) { + if (isString(property) || isNumber(property)) { + return property; + } + const accessorText = getAccessorExpression(property.toString()); + const accessor = this.parser.parse(accessorText); + if (accessor instanceof AccessScope + || accessor instanceof AccessMember && accessor.object instanceof AccessScope) { + return accessor.name; + } + throw new Error(`Invalid property expression: "${accessor}"`); + } +} +PropertyAccessorParser.inject = [Parser]; +function getAccessorExpression(fn) { + /* tslint:disable:max-line-length */ + const classic = /^function\s*\([$_\w\d]+\)\s*\{(?:\s*"use strict";)?\s*(?:[$_\w\d.['"\]+;]+)?\s*return\s+[$_\w\d]+\.([$_\w\d]+)\s*;?\s*\}$/; + /* tslint:enable:max-line-length */ + const arrow = /^\(?[$_\w\d]+\)?\s*=>\s*[$_\w\d]+\.([$_\w\d]+)$/; + const match = classic.exec(fn) || arrow.exec(fn); + if (match === null) { + throw new Error(`Unable to parse accessor function:\n${fn}`); + } + return match[1]; +} + +/** + * Validation triggers. + */ +var validateTrigger; +(function (validateTrigger) { + /** + * Manual validation. Use the controller's `validate()` and `reset()` methods + * to validate all bindings. + */ + validateTrigger[validateTrigger["manual"] = 0] = "manual"; + /** + * Validate the binding when the binding's target element fires a DOM "blur" event. + */ + validateTrigger[validateTrigger["blur"] = 1] = "blur"; + /** + * Validate the binding when it updates the model due to a change in the view. + */ + validateTrigger[validateTrigger["change"] = 2] = "change"; + /** + * Validate the binding when the binding's target element fires a DOM "blur" event and + * when it updates the model due to a change in the view. + */ + validateTrigger[validateTrigger["changeOrBlur"] = 3] = "changeOrBlur"; +})(validateTrigger || (validateTrigger = {})); + +/** + * Validates objects and properties. + */ +class Validator { +} + +/** + * The result of validating an individual validation rule. + */ +class ValidateResult { + /** + * @param rule The rule associated with the result. Validator implementation specific. + * @param object The object that was validated. + * @param propertyName The name of the property that was validated. + * @param error The error, if the result is a validation error. + */ + constructor(rule, object, propertyName, valid, message = null) { + this.rule = rule; + this.object = object; + this.propertyName = propertyName; + this.valid = valid; + this.message = message; + this.id = ValidateResult.nextId++; + } + toString() { + return this.valid ? 'Valid.' : this.message; + } +} +ValidateResult.nextId = 0; + +class ValidateEvent { + constructor( + /** + * The type of validate event. Either "validate" or "reset". + */ + type, + /** + * The controller's current array of errors. For an array containing both + * failed rules and passed rules, use the "results" property. + */ + errors, + /** + * The controller's current array of validate results. This + * includes both passed rules and failed rules. For an array of only failed rules, + * use the "errors" property. + */ + results, + /** + * The instruction passed to the "validate" or "reset" event. Will be null when + * the controller's validate/reset method was called with no instruction argument. + */ + instruction, + /** + * In events with type === "validate", this property will contain the result + * of validating the instruction (see "instruction" property). Use the controllerValidateResult + * to access the validate results specific to the call to "validate" + * (as opposed to using the "results" and "errors" properties to access the controller's entire + * set of results/errors). + */ + controllerValidateResult) { + this.type = type; + this.errors = errors; + this.results = results; + this.instruction = instruction; + this.controllerValidateResult = controllerValidateResult; + } +} + +/** + * Orchestrates validation. + * Manages a set of bindings, renderers and objects. + * Exposes the current list of validation results for binding purposes. + */ +class ValidationController { + constructor(validator, propertyParser) { + this.validator = validator; + this.propertyParser = propertyParser; + // Registered bindings (via the validate binding behavior) + this.bindings = new Map(); + // Renderers that have been added to the controller instance. + this.renderers = []; + /** + * Validation results that have been rendered by the controller. + */ + this.results = []; + /** + * Validation errors that have been rendered by the controller. + */ + this.errors = []; + /** + * Whether the controller is currently validating. + */ + this.validating = false; + // Elements related to validation results that have been rendered. + this.elements = new Map(); + // Objects that have been added to the controller instance (entity-style validation). + this.objects = new Map(); + /** + * The trigger that will invoke automatic validation of a property used in a binding. + */ + this.validateTrigger = validateTrigger.blur; + // Promise that resolves when validation has completed. + this.finishValidating = Promise.resolve(); + this.eventCallbacks = []; + } + /** + * Subscribe to controller validate and reset events. These events occur when the + * controller's "validate"" and "reset" methods are called. + * @param callback The callback to be invoked when the controller validates or resets. + */ + subscribe(callback) { + this.eventCallbacks.push(callback); + return { + dispose: () => { + const index = this.eventCallbacks.indexOf(callback); + if (index === -1) { + return; + } + this.eventCallbacks.splice(index, 1); + } + }; + } + /** + * Adds an object to the set of objects that should be validated when validate is called. + * @param object The object. + * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. + */ + addObject(object, rules) { + this.objects.set(object, rules); + } + /** + * Removes an object from the set of objects that should be validated when validate is called. + * @param object The object. + */ + removeObject(object) { + this.objects.delete(object); + this.processResultDelta('reset', this.results.filter(result => result.object === object), []); + } + /** + * Adds and renders an error. + */ + addError(message, object, propertyName = null) { + let resolvedPropertyName; + if (propertyName === null) { + resolvedPropertyName = propertyName; + } + else { + resolvedPropertyName = this.propertyParser.parse(propertyName); + } + const result = new ValidateResult({ __manuallyAdded__: true }, object, resolvedPropertyName, false, message); + this.processResultDelta('validate', [], [result]); + return result; + } + /** + * Removes and unrenders an error. + */ + removeError(result) { + if (this.results.indexOf(result) !== -1) { + this.processResultDelta('reset', [result], []); + } + } + /** + * Adds a renderer. + * @param renderer The renderer. + */ + addRenderer(renderer) { + this.renderers.push(renderer); + renderer.render({ + kind: 'validate', + render: this.results.map(result => ({ result, elements: this.elements.get(result) })), + unrender: [] + }); + } + /** + * Removes a renderer. + * @param renderer The renderer. + */ + removeRenderer(renderer) { + this.renderers.splice(this.renderers.indexOf(renderer), 1); + renderer.render({ + kind: 'reset', + render: [], + unrender: this.results.map(result => ({ result, elements: this.elements.get(result) })) + }); + } + /** + * Registers a binding with the controller. + * @param binding The binding instance. + * @param target The DOM element. + * @param rules (optional) rules associated with the binding. Validator implementation specific. + */ + registerBinding(binding, target, rules) { + this.bindings.set(binding, { target, rules, propertyInfo: null }); + } + /** + * Unregisters a binding with the controller. + * @param binding The binding instance. + */ + unregisterBinding(binding) { + this.resetBinding(binding); + this.bindings.delete(binding); + } + /** + * Interprets the instruction and returns a predicate that will identify + * relevant results in the list of rendered validation results. + */ + getInstructionPredicate(instruction) { + if (instruction) { + const { object, propertyName, rules } = instruction; + let predicate; + if (instruction.propertyName) { + predicate = x => x.object === object && x.propertyName === propertyName; + } + else { + predicate = x => x.object === object; + } + if (rules) { + return x => predicate(x) && this.validator.ruleExists(rules, x.rule); + } + return predicate; + } + else { + return () => true; + } + } + /** + * Validates and renders results. + * @param instruction Optional. Instructions on what to validate. If undefined, all + * objects and bindings will be validated. + */ + validate(instruction) { + // Get a function that will process the validation instruction. + let execute; + if (instruction) { + // tslint:disable-next-line:prefer-const + let { object, propertyName, rules } = instruction; + // if rules were not specified, check the object map. + rules = rules || this.objects.get(object); + // property specified? + if (instruction.propertyName === undefined) { + // validate the specified object. + execute = () => this.validator.validateObject(object, rules); + } + else { + // validate the specified property. + execute = () => this.validator.validateProperty(object, propertyName, rules); + } + } + else { + // validate all objects and bindings. + execute = () => { + const promises = []; + for (const [object, rules] of Array.from(this.objects)) { + promises.push(this.validator.validateObject(object, rules)); + } + for (const [binding, { rules }] of Array.from(this.bindings)) { + const propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + if (!propertyInfo || this.objects.has(propertyInfo.object)) { + continue; + } + promises.push(this.validator.validateProperty(propertyInfo.object, propertyInfo.propertyName, rules)); + } + return Promise.all(promises).then(resultSets => resultSets.reduce((a, b) => a.concat(b), [])); + }; + } + // Wait for any existing validation to finish, execute the instruction, render the results. + this.validating = true; + const returnPromise = this.finishValidating + .then(execute) + .then((newResults) => { + const predicate = this.getInstructionPredicate(instruction); + const oldResults = this.results.filter(predicate); + this.processResultDelta('validate', oldResults, newResults); + if (returnPromise === this.finishValidating) { + this.validating = false; + } + const result = { + instruction, + valid: newResults.find(x => !x.valid) === undefined, + results: newResults + }; + this.invokeCallbacks(instruction, result); + return result; + }) + .catch(exception => { + // recover, to enable subsequent calls to validate() + this.validating = false; + this.finishValidating = Promise.resolve(); + return Promise.reject(exception); + }); + this.finishValidating = returnPromise; + return returnPromise; + } + /** + * Resets any rendered validation results (unrenders). + * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results + * will be unrendered. + */ + reset(instruction) { + const predicate = this.getInstructionPredicate(instruction); + const oldResults = this.results.filter(predicate); + this.processResultDelta('reset', oldResults, []); + this.invokeCallbacks(instruction, null); + } + /** + * Gets the elements associated with an object and propertyName (if any). + */ + getAssociatedElements({ object, propertyName }) { + const elements = []; + for (const [binding, { target }] of Array.from(this.bindings)) { + const propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + if (propertyInfo && propertyInfo.object === object && propertyInfo.propertyName === propertyName) { + elements.push(target); + } + } + return elements; + } + processResultDelta(kind, oldResults, newResults) { + // prepare the instruction. + const instruction = { + kind, + render: [], + unrender: [] + }; + // create a shallow copy of newResults so we can mutate it without causing side-effects. + newResults = newResults.slice(0); + // create unrender instructions from the old results. + for (const oldResult of oldResults) { + // get the elements associated with the old result. + const elements = this.elements.get(oldResult); + // remove the old result from the element map. + this.elements.delete(oldResult); + // create the unrender instruction. + instruction.unrender.push({ result: oldResult, elements }); + // determine if there's a corresponding new result for the old result we are unrendering. + const newResultIndex = newResults.findIndex(x => x.rule === oldResult.rule && x.object === oldResult.object && x.propertyName === oldResult.propertyName); + if (newResultIndex === -1) { + // no corresponding new result... simple remove. + this.results.splice(this.results.indexOf(oldResult), 1); + if (!oldResult.valid) { + this.errors.splice(this.errors.indexOf(oldResult), 1); + } + } + else { + // there is a corresponding new result... + const newResult = newResults.splice(newResultIndex, 1)[0]; + // get the elements that are associated with the new result. + const elements = this.getAssociatedElements(newResult); + this.elements.set(newResult, elements); + // create a render instruction for the new result. + instruction.render.push({ result: newResult, elements }); + // do an in-place replacement of the old result with the new result. + // this ensures any repeats bound to this.results will not thrash. + this.results.splice(this.results.indexOf(oldResult), 1, newResult); + if (!oldResult.valid && newResult.valid) { + this.errors.splice(this.errors.indexOf(oldResult), 1); + } + else if (!oldResult.valid && !newResult.valid) { + this.errors.splice(this.errors.indexOf(oldResult), 1, newResult); + } + else if (!newResult.valid) { + this.errors.push(newResult); + } + } + } + // create render instructions from the remaining new results. + for (const result of newResults) { + const elements = this.getAssociatedElements(result); + instruction.render.push({ result, elements }); + this.elements.set(result, elements); + this.results.push(result); + if (!result.valid) { + this.errors.push(result); + } + } + // render. + for (const renderer of this.renderers) { + renderer.render(instruction); + } + } + /** + * Validates the property associated with a binding. + */ + validateBinding(binding) { + if (!binding.isBound) { + return; + } + const propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + let rules; + const registeredBinding = this.bindings.get(binding); + if (registeredBinding) { + rules = registeredBinding.rules; + registeredBinding.propertyInfo = propertyInfo; + } + if (!propertyInfo) { + return; + } + const { object, propertyName } = propertyInfo; + this.validate({ object, propertyName, rules }); + } + /** + * Resets the results for a property associated with a binding. + */ + resetBinding(binding) { + const registeredBinding = this.bindings.get(binding); + let propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + if (!propertyInfo && registeredBinding) { + propertyInfo = registeredBinding.propertyInfo; + } + if (registeredBinding) { + registeredBinding.propertyInfo = null; + } + if (!propertyInfo) { + return; + } + const { object, propertyName } = propertyInfo; + this.reset({ object, propertyName }); + } + /** + * Changes the controller's validateTrigger. + * @param newTrigger The new validateTrigger + */ + changeTrigger(newTrigger) { + this.validateTrigger = newTrigger; + const bindings = Array.from(this.bindings.keys()); + for (const binding of bindings) { + const source = binding.source; + binding.unbind(); + binding.bind(source); + } + } + /** + * Revalidates the controller's current set of errors. + */ + revalidateErrors() { + for (const { object, propertyName, rule } of this.errors) { + if (rule.__manuallyAdded__) { + continue; + } + const rules = [[rule]]; + this.validate({ object, propertyName, rules }); + } + } + invokeCallbacks(instruction, result) { + if (this.eventCallbacks.length === 0) { + return; + } + const event = new ValidateEvent(result ? 'validate' : 'reset', this.errors, this.results, instruction || null, result); + for (let i = 0; i < this.eventCallbacks.length; i++) { + this.eventCallbacks[i](event); + } + } +} +ValidationController.inject = [Validator, PropertyAccessorParser]; + +/** + * Binding behavior. Indicates the bound property should be validated. + */ +class ValidateBindingBehaviorBase { + constructor(taskQueue) { + this.taskQueue = taskQueue; + } + bind(binding, source, rulesOrController, rules) { + // identify the target element. + const target = getTargetDOMElement(binding, source); + // locate the controller. + let controller; + if (rulesOrController instanceof ValidationController) { + controller = rulesOrController; + } + else { + controller = source.container.get(Optional.of(ValidationController)); + rules = rulesOrController; + } + if (controller === null) { + throw new Error(`A ValidationController has not been registered.`); + } + controller.registerBinding(binding, target, rules); + binding.validationController = controller; + const trigger = this.getValidateTrigger(controller); + // tslint:disable-next-line:no-bitwise + if (trigger & validateTrigger.change) { + binding.vbbUpdateSource = binding.updateSource; + // tslint:disable-next-line:only-arrow-functions + // tslint:disable-next-line:space-before-function-paren + binding.updateSource = function (value) { + this.vbbUpdateSource(value); + this.validationController.validateBinding(this); + }; + } + // tslint:disable-next-line:no-bitwise + if (trigger & validateTrigger.blur) { + binding.validateBlurHandler = () => { + this.taskQueue.queueMicroTask(() => controller.validateBinding(binding)); + }; + binding.validateTarget = target; + target.addEventListener('blur', binding.validateBlurHandler); + } + if (trigger !== validateTrigger.manual) { + binding.standardUpdateTarget = binding.updateTarget; + // tslint:disable-next-line:only-arrow-functions + // tslint:disable-next-line:space-before-function-paren + binding.updateTarget = function (value) { + this.standardUpdateTarget(value); + this.validationController.resetBinding(this); + }; + } + } + unbind(binding) { + // reset the binding to it's original state. + if (binding.vbbUpdateSource) { + binding.updateSource = binding.vbbUpdateSource; + binding.vbbUpdateSource = null; + } + if (binding.standardUpdateTarget) { + binding.updateTarget = binding.standardUpdateTarget; + binding.standardUpdateTarget = null; + } + if (binding.validateBlurHandler) { + binding.validateTarget.removeEventListener('blur', binding.validateBlurHandler); + binding.validateBlurHandler = null; + binding.validateTarget = null; + } + binding.validationController.unregisterBinding(binding); + binding.validationController = null; + } +} + +/** + * Binding behavior. Indicates the bound property should be validated + * when the validate trigger specified by the associated controller's + * validateTrigger property occurs. + */ +class ValidateBindingBehavior extends ValidateBindingBehaviorBase { + getValidateTrigger(controller) { + return controller.validateTrigger; + } +} +ValidateBindingBehavior.inject = [TaskQueue]; +/** + * Binding behavior. Indicates the bound property will be validated + * manually, by calling controller.validate(). No automatic validation + * triggered by data-entry or blur will occur. + */ +class ValidateManuallyBindingBehavior extends ValidateBindingBehaviorBase { + getValidateTrigger() { + return validateTrigger.manual; + } +} +ValidateManuallyBindingBehavior.inject = [TaskQueue]; +/** + * Binding behavior. Indicates the bound property should be validated + * when the associated element blurs. + */ +class ValidateOnBlurBindingBehavior extends ValidateBindingBehaviorBase { + getValidateTrigger() { + return validateTrigger.blur; + } +} +ValidateOnBlurBindingBehavior.inject = [TaskQueue]; +/** + * Binding behavior. Indicates the bound property should be validated + * when the associated element is changed by the user, causing a change + * to the model. + */ +class ValidateOnChangeBindingBehavior extends ValidateBindingBehaviorBase { + getValidateTrigger() { + return validateTrigger.change; + } +} +ValidateOnChangeBindingBehavior.inject = [TaskQueue]; +/** + * Binding behavior. Indicates the bound property should be validated + * when the associated element blurs or is changed by the user, causing + * a change to the model. + */ +class ValidateOnChangeOrBlurBindingBehavior extends ValidateBindingBehaviorBase { + getValidateTrigger() { + return validateTrigger.changeOrBlur; + } +} +ValidateOnChangeOrBlurBindingBehavior.inject = [TaskQueue]; + +/** + * Creates ValidationController instances. + */ +class ValidationControllerFactory { + constructor(container) { + this.container = container; + } + static get(container) { + return new ValidationControllerFactory(container); + } + /** + * Creates a new controller instance. + */ + create(validator) { + if (!validator) { + validator = this.container.get(Validator); + } + const propertyParser = this.container.get(PropertyAccessorParser); + return new ValidationController(validator, propertyParser); + } + /** + * Creates a new controller and registers it in the current element's container so that it's + * available to the validate binding behavior and renderers. + */ + createForCurrentScope(validator) { + const controller = this.create(validator); + this.container.registerInstance(ValidationController, controller); + return controller; + } +} +ValidationControllerFactory['protocol:aurelia:resolver'] = true; + +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at http://www.apache.org/licenses/LICENSE-2.0 + +THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED +WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +MERCHANTABLITY OR NON-INFRINGEMENT. + +See the Apache Version 2.0 License for specific language governing permissions +and limitations under the License. +***************************************************************************** */ + +function __decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +} + +let ValidationErrorsCustomAttribute = class ValidationErrorsCustomAttribute { + constructor(boundaryElement, controllerAccessor) { + this.boundaryElement = boundaryElement; + this.controllerAccessor = controllerAccessor; + this.controller = null; + this.errors = []; + this.errorsInternal = []; + } + static inject() { + return [DOM.Element, Lazy.of(ValidationController)]; + } + sort() { + this.errorsInternal.sort((a, b) => { + if (a.targets[0] === b.targets[0]) { + return 0; + } + // tslint:disable-next-line:no-bitwise + return a.targets[0].compareDocumentPosition(b.targets[0]) & 2 ? 1 : -1; + }); + } + interestingElements(elements) { + return elements.filter(e => this.boundaryElement.contains(e)); + } + render(instruction) { + for (const { result } of instruction.unrender) { + const index = this.errorsInternal.findIndex(x => x.error === result); + if (index !== -1) { + this.errorsInternal.splice(index, 1); + } + } + for (const { result, elements } of instruction.render) { + if (result.valid) { + continue; + } + const targets = this.interestingElements(elements); + if (targets.length) { + this.errorsInternal.push({ error: result, targets }); + } + } + this.sort(); + this.errors = this.errorsInternal; + } + bind() { + if (!this.controller) { + this.controller = this.controllerAccessor(); + } + // this will call render() with the side-effect of updating this.errors + this.controller.addRenderer(this); + } + unbind() { + if (this.controller) { + this.controller.removeRenderer(this); + } + } +}; +__decorate([ + bindable({ defaultBindingMode: bindingMode.oneWay }) +], ValidationErrorsCustomAttribute.prototype, "controller", void 0); +__decorate([ + bindable({ primaryProperty: true, defaultBindingMode: bindingMode.twoWay }) +], ValidationErrorsCustomAttribute.prototype, "errors", void 0); +ValidationErrorsCustomAttribute = __decorate([ + customAttribute('validation-errors') +], ValidationErrorsCustomAttribute); + +let ValidationRendererCustomAttribute = class ValidationRendererCustomAttribute { + created(view) { + this.container = view.container; + } + bind() { + this.controller = this.container.get(ValidationController); + this.renderer = this.container.get(this.value); + this.controller.addRenderer(this.renderer); + } + unbind() { + this.controller.removeRenderer(this.renderer); + this.controller = null; + this.renderer = null; + } +}; +ValidationRendererCustomAttribute = __decorate([ + customAttribute$1('validation-renderer') +], ValidationRendererCustomAttribute); + +/** + * Sets, unsets and retrieves rules on an object or constructor function. + */ +class Rules { + /** + * Applies the rules to a target. + */ + static set(target, rules) { + if (target instanceof Function) { + target = target.prototype; + } + Object.defineProperty(target, Rules.key, { enumerable: false, configurable: false, writable: true, value: rules }); + } + /** + * Removes rules from a target. + */ + static unset(target) { + if (target instanceof Function) { + target = target.prototype; + } + target[Rules.key] = null; + } + /** + * Retrieves the target's rules. + */ + static get(target) { + return target[Rules.key] || null; + } +} +/** + * The name of the property that stores the rules. + */ +Rules.key = '__rules__'; + +// tslint:disable:no-empty +class ExpressionVisitor { + visitChain(chain) { + this.visitArgs(chain.expressions); + } + visitBindingBehavior(behavior) { + behavior.expression.accept(this); + this.visitArgs(behavior.args); + } + visitValueConverter(converter) { + converter.expression.accept(this); + this.visitArgs(converter.args); + } + visitAssign(assign) { + assign.target.accept(this); + assign.value.accept(this); + } + visitConditional(conditional) { + conditional.condition.accept(this); + conditional.yes.accept(this); + conditional.no.accept(this); + } + visitAccessThis(access) { + access.ancestor = access.ancestor; + } + visitAccessScope(access) { + access.name = access.name; + } + visitAccessMember(access) { + access.object.accept(this); + } + visitAccessKeyed(access) { + access.object.accept(this); + access.key.accept(this); + } + visitCallScope(call) { + this.visitArgs(call.args); + } + visitCallFunction(call) { + call.func.accept(this); + this.visitArgs(call.args); + } + visitCallMember(call) { + call.object.accept(this); + this.visitArgs(call.args); + } + visitPrefix(prefix) { + prefix.expression.accept(this); + } + visitBinary(binary) { + binary.left.accept(this); + binary.right.accept(this); + } + visitLiteralPrimitive(literal) { + literal.value = literal.value; + } + visitLiteralArray(literal) { + this.visitArgs(literal.elements); + } + visitLiteralObject(literal) { + this.visitArgs(literal.values); + } + visitLiteralString(literal) { + literal.value = literal.value; + } + visitArgs(args) { + for (let i = 0; i < args.length; i++) { + args[i].accept(this); + } + } +} + +class ValidationMessageParser { + constructor(bindinqLanguage) { + this.bindinqLanguage = bindinqLanguage; + this.emptyStringExpression = new LiteralString(''); + this.nullExpression = new LiteralPrimitive(null); + this.undefinedExpression = new LiteralPrimitive(undefined); + this.cache = {}; + } + parse(message) { + if (this.cache[message] !== undefined) { + return this.cache[message]; + } + const parts = this.bindinqLanguage.parseInterpolation(null, message); + if (parts === null) { + return new LiteralString(message); + } + let expression = new LiteralString(parts[0]); + for (let i = 1; i < parts.length; i += 2) { + expression = new Binary('+', expression, new Binary('+', this.coalesce(parts[i]), new LiteralString(parts[i + 1]))); + } + MessageExpressionValidator.validate(expression, message); + this.cache[message] = expression; + return expression; + } + coalesce(part) { + // part === null || part === undefined ? '' : part + return new Conditional(new Binary('||', new Binary('===', part, this.nullExpression), new Binary('===', part, this.undefinedExpression)), this.emptyStringExpression, new CallMember(part, 'toString', [])); + } +} +ValidationMessageParser.inject = [BindingLanguage]; +class MessageExpressionValidator extends ExpressionVisitor { + constructor(originalMessage) { + super(); + this.originalMessage = originalMessage; + } + static validate(expression, originalMessage) { + const visitor = new MessageExpressionValidator(originalMessage); + expression.accept(visitor); + } + visitAccessScope(access) { + if (access.ancestor !== 0) { + throw new Error('$parent is not permitted in validation message expressions.'); + } + if (['displayName', 'propertyName', 'value', 'object', 'config', 'getDisplayName'].indexOf(access.name) !== -1) { + getLogger('aurelia-validation') + // tslint:disable-next-line:max-line-length + .warn(`Did you mean to use "$${access.name}" instead of "${access.name}" in this validation message template: "${this.originalMessage}"?`); + } + } +} + +/** + * Dictionary of validation messages. [messageKey]: messageExpression + */ +const validationMessages = { + /** + * The default validation message. Used with rules that have no standard message. + */ + default: `\${$displayName} is invalid.`, + required: `\${$displayName} is required.`, + matches: `\${$displayName} is not correctly formatted.`, + email: `\${$displayName} is not a valid email.`, + minLength: `\${$displayName} must be at least \${$config.length} character\${$config.length === 1 ? '' : 's'}.`, + maxLength: `\${$displayName} cannot be longer than \${$config.length} character\${$config.length === 1 ? '' : 's'}.`, + minItems: `\${$displayName} must contain at least \${$config.count} item\${$config.count === 1 ? '' : 's'}.`, + maxItems: `\${$displayName} cannot contain more than \${$config.count} item\${$config.count === 1 ? '' : 's'}.`, + equals: `\${$displayName} must be \${$config.expectedValue}.`, +}; +/** + * Retrieves validation messages and property display names. + */ +class ValidationMessageProvider { + constructor(parser) { + this.parser = parser; + } + /** + * Returns a message binding expression that corresponds to the key. + * @param key The message key. + */ + getMessage(key) { + let message; + if (key in validationMessages) { + message = validationMessages[key]; + } + else { + message = validationMessages['default']; + } + return this.parser.parse(message); + } + /** + * Formulates a property display name using the property name and the configured + * displayName (if provided). + * Override this with your own custom logic. + * @param propertyName The property name. + */ + getDisplayName(propertyName, displayName) { + if (displayName !== null && displayName !== undefined) { + return (displayName instanceof Function) ? displayName() : displayName; + } + // split on upper-case letters. + const words = propertyName.toString().split(/(?=[A-Z])/).join(' '); + // capitalize first letter. + return words.charAt(0).toUpperCase() + words.slice(1); + } +} +ValidationMessageProvider.inject = [ValidationMessageParser]; + +/** + * Validates. + * Responsible for validating objects and properties. + */ +class StandardValidator extends Validator { + constructor(messageProvider, resources) { + super(); + this.messageProvider = messageProvider; + this.lookupFunctions = resources.lookupFunctions; + this.getDisplayName = messageProvider.getDisplayName.bind(messageProvider); + } + /** + * Validates the specified property. + * @param object The object to validate. + * @param propertyName The name of the property to validate. + * @param rules Optional. If unspecified, the rules will be looked up using the metadata + * for the object created by ValidationRules....on(class/object) + */ + validateProperty(object, propertyName, rules) { + return this.validate(object, propertyName, rules || null); + } + /** + * Validates all rules for specified object and it's properties. + * @param object The object to validate. + * @param rules Optional. If unspecified, the rules will be looked up using the metadata + * for the object created by ValidationRules....on(class/object) + */ + validateObject(object, rules) { + return this.validate(object, null, rules || null); + } + /** + * Determines whether a rule exists in a set of rules. + * @param rules The rules to search. + * @parem rule The rule to find. + */ + ruleExists(rules, rule) { + let i = rules.length; + while (i--) { + if (rules[i].indexOf(rule) !== -1) { + return true; + } + } + return false; + } + getMessage(rule, object, value) { + const expression = rule.message || this.messageProvider.getMessage(rule.messageKey); + // tslint:disable-next-line:prefer-const + let { name: propertyName, displayName } = rule.property; + if (propertyName !== null) { + displayName = this.messageProvider.getDisplayName(propertyName, displayName); + } + const overrideContext = { + $displayName: displayName, + $propertyName: propertyName, + $value: value, + $object: object, + $config: rule.config, + // returns the name of a given property, given just the property name (irrespective of the property's displayName) + // split on capital letters, first letter ensured to be capitalized + $getDisplayName: this.getDisplayName + }; + return expression.evaluate({ bindingContext: object, overrideContext }, this.lookupFunctions); + } + validateRuleSequence(object, propertyName, ruleSequence, sequence, results) { + // are we validating all properties or a single property? + const validateAllProperties = propertyName === null || propertyName === undefined; + const rules = ruleSequence[sequence]; + let allValid = true; + // validate each rule. + const promises = []; + for (let i = 0; i < rules.length; i++) { + const rule = rules[i]; + // is the rule related to the property we're validating. + // tslint:disable-next-line:triple-equals | Use loose equality for property keys + if (!validateAllProperties && rule.property.name != propertyName) { + continue; + } + // is this a conditional rule? is the condition met? + if (rule.when && !rule.when(object)) { + continue; + } + // validate. + const value = rule.property.name === null ? object : object[rule.property.name]; + let promiseOrBoolean = rule.condition(value, object); + if (!(promiseOrBoolean instanceof Promise)) { + promiseOrBoolean = Promise.resolve(promiseOrBoolean); + } + promises.push(promiseOrBoolean.then(valid => { + const message = valid ? null : this.getMessage(rule, object, value); + results.push(new ValidateResult(rule, object, rule.property.name, valid, message)); + allValid = allValid && valid; + return valid; + })); + } + return Promise.all(promises) + .then(() => { + sequence++; + if (allValid && sequence < ruleSequence.length) { + return this.validateRuleSequence(object, propertyName, ruleSequence, sequence, results); + } + return results; + }); + } + validate(object, propertyName, rules) { + // rules specified? + if (!rules) { + // no. attempt to locate the rules. + rules = Rules.get(object); + } + // any rules? + if (!rules || rules.length === 0) { + return Promise.resolve([]); + } + return this.validateRuleSequence(object, propertyName, rules, 0, []); + } +} +StandardValidator.inject = [ValidationMessageProvider, ViewResources]; + +/** + * Part of the fluent rule API. Enables customizing property rules. + */ +class FluentRuleCustomizer { + constructor(property, condition, config = {}, fluentEnsure, fluentRules, parsers) { + this.fluentEnsure = fluentEnsure; + this.fluentRules = fluentRules; + this.parsers = parsers; + this.rule = { + property, + condition, + config, + when: null, + messageKey: 'default', + message: null, + sequence: fluentRules.sequence + }; + this.fluentEnsure._addRule(this.rule); + } + /** + * Validate subsequent rules after previously declared rules have + * been validated successfully. Use to postpone validation of costly + * rules until less expensive rules pass validation. + */ + then() { + this.fluentRules.sequence++; + return this; + } + /** + * Specifies the key to use when looking up the rule's validation message. + */ + withMessageKey(key) { + this.rule.messageKey = key; + this.rule.message = null; + return this; + } + /** + * Specifies rule's validation message. + */ + withMessage(message) { + this.rule.messageKey = 'custom'; + this.rule.message = this.parsers.message.parse(message); + return this; + } + /** + * Specifies a condition that must be met before attempting to validate the rule. + * @param condition A function that accepts the object as a parameter and returns true + * or false whether the rule should be evaluated. + */ + when(condition) { + this.rule.when = condition; + return this; + } + /** + * Tags the rule instance, enabling the rule to be found easily + * using ValidationRules.taggedRules(rules, tag) + */ + tag(tag) { + this.rule.tag = tag; + return this; + } + ///// FluentEnsure APIs ///// + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor function. + */ + ensure(subject) { + return this.fluentEnsure.ensure(subject); + } + /** + * Targets an object with validation rules. + */ + ensureObject() { + return this.fluentEnsure.ensureObject(); + } + /** + * Rules that have been defined using the fluent API. + */ + get rules() { + return this.fluentEnsure.rules; + } + /** + * Applies the rules to a class or object, making them discoverable by the StandardValidator. + * @param target A class or object. + */ + on(target) { + return this.fluentEnsure.on(target); + } + ///////// FluentRules APIs ///////// + /** + * Applies an ad-hoc rule function to the ensured property or object. + * @param condition The function to validate the rule. + * Will be called with two arguments, the property value and the object. + * Should return a boolean or a Promise that resolves to a boolean. + */ + satisfies(condition, config) { + return this.fluentRules.satisfies(condition, config); + } + /** + * Applies a rule by name. + * @param name The name of the custom or standard rule. + * @param args The rule's arguments. + */ + satisfiesRule(name, ...args) { + return this.fluentRules.satisfiesRule(name, ...args); + } + /** + * Applies the "required" rule to the property. + * The value cannot be null, undefined or whitespace. + */ + required() { + return this.fluentRules.required(); + } + /** + * Applies the "matches" rule to the property. + * Value must match the specified regular expression. + * null, undefined and empty-string values are considered valid. + */ + matches(regex) { + return this.fluentRules.matches(regex); + } + /** + * Applies the "email" rule to the property. + * null, undefined and empty-string values are considered valid. + */ + email() { + return this.fluentRules.email(); + } + /** + * Applies the "minLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + minLength(length) { + return this.fluentRules.minLength(length); + } + /** + * Applies the "maxLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + maxLength(length) { + return this.fluentRules.maxLength(length); + } + /** + * Applies the "minItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + minItems(count) { + return this.fluentRules.minItems(count); + } + /** + * Applies the "maxItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + maxItems(count) { + return this.fluentRules.maxItems(count); + } + /** + * Applies the "equals" validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + equals(expectedValue) { + return this.fluentRules.equals(expectedValue); + } +} +/** + * Part of the fluent rule API. Enables applying rules to properties and objects. + */ +class FluentRules { + constructor(fluentEnsure, parsers, property) { + this.fluentEnsure = fluentEnsure; + this.parsers = parsers; + this.property = property; + /** + * Current rule sequence number. Used to postpone evaluation of rules until rules + * with lower sequence number have successfully validated. The "then" fluent API method + * manages this property, there's usually no need to set it directly. + */ + this.sequence = 0; + } + /** + * Sets the display name of the ensured property. + */ + displayName(name) { + this.property.displayName = name; + return this; + } + /** + * Applies an ad-hoc rule function to the ensured property or object. + * @param condition The function to validate the rule. + * Will be called with two arguments, the property value and the object. + * Should return a boolean or a Promise that resolves to a boolean. + */ + satisfies(condition, config) { + return new FluentRuleCustomizer(this.property, condition, config, this.fluentEnsure, this, this.parsers); + } + /** + * Applies a rule by name. + * @param name The name of the custom or standard rule. + * @param args The rule's arguments. + */ + satisfiesRule(name, ...args) { + let rule = FluentRules.customRules[name]; + if (!rule) { + // standard rule? + rule = this[name]; + if (rule instanceof Function) { + return rule.call(this, ...args); + } + throw new Error(`Rule with name "${name}" does not exist.`); + } + const config = rule.argsToConfig ? rule.argsToConfig(...args) : undefined; + return this.satisfies((value, obj) => rule.condition.call(this, value, obj, ...args), config) + .withMessageKey(name); + } + /** + * Applies the "required" rule to the property. + * The value cannot be null, undefined or whitespace. + */ + required() { + return this.satisfies(value => value !== null + && value !== undefined + && !(isString(value) && !/\S/.test(value))).withMessageKey('required'); + } + /** + * Applies the "matches" rule to the property. + * Value must match the specified regular expression. + * null, undefined and empty-string values are considered valid. + */ + matches(regex) { + return this.satisfies(value => value === null || value === undefined || value.length === 0 || regex.test(value)) + .withMessageKey('matches'); + } + /** + * Applies the "email" rule to the property. + * null, undefined and empty-string values are considered valid. + */ + email() { + // regex from https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address + /* tslint:disable:max-line-length */ + return this.matches(/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/) + /* tslint:enable:max-line-length */ + .withMessageKey('email'); + } + /** + * Applies the "minLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + minLength(length) { + return this.satisfies((value) => value === null || value === undefined || value.length === 0 || value.length >= length, { length }) + .withMessageKey('minLength'); + } + /** + * Applies the "maxLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + maxLength(length) { + return this.satisfies((value) => value === null || value === undefined || value.length === 0 || value.length <= length, { length }) + .withMessageKey('maxLength'); + } + /** + * Applies the "minItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + minItems(count) { + return this.satisfies((value) => value === null || value === undefined || value.length >= count, { count }) + .withMessageKey('minItems'); + } + /** + * Applies the "maxItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + maxItems(count) { + return this.satisfies((value) => value === null || value === undefined || value.length <= count, { count }) + .withMessageKey('maxItems'); + } + /** + * Applies the "equals" validation rule to the property. + * null and undefined values are considered valid. + */ + equals(expectedValue) { + return this.satisfies(value => value === null || value === undefined || value === '' || value === expectedValue, { expectedValue }) + .withMessageKey('equals'); + } +} +FluentRules.customRules = {}; +/** + * Part of the fluent rule API. Enables targeting properties and objects with rules. + */ +class FluentEnsure { + constructor(parsers) { + this.parsers = parsers; + /** + * Rules that have been defined using the fluent API. + */ + this.rules = []; + } + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor + * function. + */ + ensure(property) { + this.assertInitialized(); + const name = this.parsers.property.parse(property); + const fluentRules = new FluentRules(this, this.parsers, { name, displayName: null }); + return this.mergeRules(fluentRules, name); + } + /** + * Targets an object with validation rules. + */ + ensureObject() { + this.assertInitialized(); + const fluentRules = new FluentRules(this, this.parsers, { name: null, displayName: null }); + return this.mergeRules(fluentRules, null); + } + /** + * Applies the rules to a class or object, making them discoverable by the StandardValidator. + * @param target A class or object. + */ + on(target) { + Rules.set(target, this.rules); + return this; + } + /** + * Adds a rule definition to the sequenced ruleset. + * @internal + */ + _addRule(rule) { + while (this.rules.length < rule.sequence + 1) { + this.rules.push([]); + } + this.rules[rule.sequence].push(rule); + } + assertInitialized() { + if (this.parsers) { + return; + } + throw new Error(`Did you forget to add ".plugin('aurelia-validation')" to your main.js?`); + } + mergeRules(fluentRules, propertyName) { + // tslint:disable-next-line:triple-equals | Use loose equality for property keys + const existingRules = this.rules.find(r => r.length > 0 && r[0].property.name == propertyName); + if (existingRules) { + const rule = existingRules[existingRules.length - 1]; + fluentRules.sequence = rule.sequence; + if (rule.property.displayName !== null) { + fluentRules = fluentRules.displayName(rule.property.displayName); + } + } + return fluentRules; + } +} +/** + * Fluent rule definition API. + */ +class ValidationRules { + static initialize(messageParser, propertyParser) { + this.parsers = { + message: messageParser, + property: propertyParser + }; + } + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor function. + */ + static ensure(property) { + return new FluentEnsure(ValidationRules.parsers).ensure(property); + } + /** + * Targets an object with validation rules. + */ + static ensureObject() { + return new FluentEnsure(ValidationRules.parsers).ensureObject(); + } + /** + * Defines a custom rule. + * @param name The name of the custom rule. Also serves as the message key. + * @param condition The rule function. + * @param message The message expression + * @param argsToConfig A function that maps the rule's arguments to a "config" + * object that can be used when evaluating the message expression. + */ + static customRule(name, condition, message, argsToConfig) { + validationMessages[name] = message; + FluentRules.customRules[name] = { condition, argsToConfig }; + } + /** + * Returns rules with the matching tag. + * @param rules The rules to search. + * @param tag The tag to search for. + */ + static taggedRules(rules, tag) { + return rules.map(x => x.filter(r => r.tag === tag)); + } + /** + * Returns rules that have no tag. + * @param rules The rules to search. + */ + static untaggedRules(rules) { + return rules.map(x => x.filter(r => r.tag === undefined)); + } + /** + * Removes the rules from a class or object. + * @param target A class or object. + */ + static off(target) { + Rules.unset(target); + } +} + +// Exports +/** + * Aurelia Validation Configuration API + */ +class AureliaValidationConfiguration { + constructor() { + this.validatorType = StandardValidator; + } + /** + * Use a custom Validator implementation. + */ + customValidator(type) { + this.validatorType = type; + } + /** + * Applies the configuration. + */ + apply(container) { + const validator = container.get(this.validatorType); + container.registerInstance(Validator, validator); + } +} +/** + * Configures the plugin. + */ +function configure( +// tslint:disable-next-line:ban-types +frameworkConfig, callback) { + // the fluent rule definition API needs the parser to translate messages + // to interpolation expressions. + const messageParser = frameworkConfig.container.get(ValidationMessageParser); + const propertyParser = frameworkConfig.container.get(PropertyAccessorParser); + ValidationRules.initialize(messageParser, propertyParser); + // configure... + const config = new AureliaValidationConfiguration(); + if (callback instanceof Function) { + callback(config); + } + config.apply(frameworkConfig.container); + // globalize the behaviors. + if (frameworkConfig.globalResources) { + frameworkConfig.globalResources(ValidateBindingBehavior, ValidateManuallyBindingBehavior, ValidateOnBlurBindingBehavior, ValidateOnChangeBindingBehavior, ValidateOnChangeOrBlurBindingBehavior, ValidationErrorsCustomAttribute, ValidationRendererCustomAttribute); + } +} + +export { AureliaValidationConfiguration, configure, getTargetDOMElement, getPropertyInfo, PropertyAccessorParser, getAccessorExpression, ValidateBindingBehavior, ValidateManuallyBindingBehavior, ValidateOnBlurBindingBehavior, ValidateOnChangeBindingBehavior, ValidateOnChangeOrBlurBindingBehavior, ValidateEvent, ValidateResult, validateTrigger, ValidationController, ValidationControllerFactory, ValidationErrorsCustomAttribute, ValidationRendererCustomAttribute, Validator, Rules, StandardValidator, validationMessages, ValidationMessageProvider, ValidationMessageParser, MessageExpressionValidator, FluentRuleCustomizer, FluentRules, FluentEnsure, ValidationRules }; diff --git a/dist/es2015/controller-validate-result.js b/dist/es2015/controller-validate-result.js deleted file mode 100644 index e69de29b..00000000 diff --git a/dist/es2015/get-target-dom-element.js b/dist/es2015/get-target-dom-element.js deleted file mode 100644 index 2b976f87..00000000 --- a/dist/es2015/get-target-dom-element.js +++ /dev/null @@ -1,27 +0,0 @@ -import { DOM } from 'aurelia-pal'; -/** - * Gets the DOM element associated with the data-binding. Most of the time it's - * the binding.target but sometimes binding.target is an aurelia custom element, - * or custom attribute which is a javascript "class" instance, so we need to use - * the controller's container to retrieve the actual DOM element. - */ -export function getTargetDOMElement(binding, view) { - const target = binding.target; - // DOM element - if (target instanceof Element) { - return target; - } - // custom element or custom attribute - // tslint:disable-next-line:prefer-const - for (let i = 0, ii = view.controllers.length; i < ii; i++) { - const controller = view.controllers[i]; - if (controller.viewModel === target) { - const element = controller.container.get(DOM.Element); - if (element) { - return element; - } - throw new Error(`Unable to locate target element for "${binding.sourceExpression}".`); - } - } - throw new Error(`Unable to locate target element for "${binding.sourceExpression}".`); -} diff --git a/dist/es2015/implementation/expression-visitor.d.ts b/dist/es2015/implementation/expression-visitor.d.ts deleted file mode 100644 index 47769fae..00000000 --- a/dist/es2015/implementation/expression-visitor.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { ValueConverter, Conditional, AccessMember, AccessKeyed, CallMember, BindingBehavior, Binary } from 'aurelia-binding'; -export declare type Chain = any; -export declare type Assign = any; -export declare type AccessThis = any; -export declare type AccessScope = any; -export declare type CallScope = any; -export declare type CallFunction = any; -export declare type PrefixNot = any; -export declare type LiteralPrimitive = any; -export declare type LiteralArray = any; -export declare type LiteralObject = any; -export declare type LiteralString = any; -export declare class ExpressionVisitor { - visitChain(chain: Chain): void; - visitBindingBehavior(behavior: BindingBehavior): void; - visitValueConverter(converter: ValueConverter): void; - visitAssign(assign: Assign): void; - visitConditional(conditional: Conditional): void; - visitAccessThis(access: AccessThis): void; - visitAccessScope(access: AccessScope): void; - visitAccessMember(access: AccessMember): void; - visitAccessKeyed(access: AccessKeyed): void; - visitCallScope(call: CallScope): void; - visitCallFunction(call: CallFunction): void; - visitCallMember(call: CallMember): void; - visitPrefix(prefix: PrefixNot): void; - visitBinary(binary: Binary): void; - visitLiteralPrimitive(literal: LiteralPrimitive): void; - visitLiteralArray(literal: LiteralArray): void; - visitLiteralObject(literal: LiteralObject): void; - visitLiteralString(literal: LiteralString): void; - private visitArgs(args); -} diff --git a/dist/es2015/implementation/expression-visitor.js b/dist/es2015/implementation/expression-visitor.js deleted file mode 100644 index 656c6d0e..00000000 --- a/dist/es2015/implementation/expression-visitor.js +++ /dev/null @@ -1,71 +0,0 @@ -// tslint:disable:no-empty -export class ExpressionVisitor { - visitChain(chain) { - this.visitArgs(chain.expressions); - } - visitBindingBehavior(behavior) { - behavior.expression.accept(this); - this.visitArgs(behavior.args); - } - visitValueConverter(converter) { - converter.expression.accept(this); - this.visitArgs(converter.args); - } - visitAssign(assign) { - assign.target.accept(this); - assign.value.accept(this); - } - visitConditional(conditional) { - conditional.condition.accept(this); - conditional.yes.accept(this); - conditional.no.accept(this); - } - visitAccessThis(access) { - access.ancestor = access.ancestor; - } - visitAccessScope(access) { - access.name = access.name; - } - visitAccessMember(access) { - access.object.accept(this); - } - visitAccessKeyed(access) { - access.object.accept(this); - access.key.accept(this); - } - visitCallScope(call) { - this.visitArgs(call.args); - } - visitCallFunction(call) { - call.func.accept(this); - this.visitArgs(call.args); - } - visitCallMember(call) { - call.object.accept(this); - this.visitArgs(call.args); - } - visitPrefix(prefix) { - prefix.expression.accept(this); - } - visitBinary(binary) { - binary.left.accept(this); - binary.right.accept(this); - } - visitLiteralPrimitive(literal) { - literal.value = literal.value; - } - visitLiteralArray(literal) { - this.visitArgs(literal.elements); - } - visitLiteralObject(literal) { - this.visitArgs(literal.values); - } - visitLiteralString(literal) { - literal.value = literal.value; - } - visitArgs(args) { - for (let i = 0; i < args.length; i++) { - args[i].accept(this); - } - } -} diff --git a/dist/es2015/implementation/rule.js b/dist/es2015/implementation/rule.js deleted file mode 100644 index e69de29b..00000000 diff --git a/dist/es2015/implementation/rules.js b/dist/es2015/implementation/rules.js deleted file mode 100644 index db8977e5..00000000 --- a/dist/es2015/implementation/rules.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Sets, unsets and retrieves rules on an object or constructor function. - */ -export class Rules { - /** - * Applies the rules to a target. - */ - static set(target, rules) { - if (target instanceof Function) { - target = target.prototype; - } - Object.defineProperty(target, Rules.key, { enumerable: false, configurable: false, writable: true, value: rules }); - } - /** - * Removes rules from a target. - */ - static unset(target) { - if (target instanceof Function) { - target = target.prototype; - } - target[Rules.key] = null; - } - /** - * Retrieves the target's rules. - */ - static get(target) { - return target[Rules.key] || null; - } -} -/** - * The name of the property that stores the rules. - */ -Rules.key = '__rules__'; diff --git a/dist/es2015/implementation/standard-validator.js b/dist/es2015/implementation/standard-validator.js deleted file mode 100644 index a6b3714a..00000000 --- a/dist/es2015/implementation/standard-validator.js +++ /dev/null @@ -1,122 +0,0 @@ -import { ViewResources } from 'aurelia-templating'; -import { Validator } from '../validator'; -import { ValidateResult } from '../validate-result'; -import { Rules } from './rules'; -import { ValidationMessageProvider } from './validation-messages'; -/** - * Validates. - * Responsible for validating objects and properties. - */ -export class StandardValidator extends Validator { - constructor(messageProvider, resources) { - super(); - this.messageProvider = messageProvider; - this.lookupFunctions = resources.lookupFunctions; - this.getDisplayName = messageProvider.getDisplayName.bind(messageProvider); - } - /** - * Validates the specified property. - * @param object The object to validate. - * @param propertyName The name of the property to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - validateProperty(object, propertyName, rules) { - return this.validate(object, propertyName, rules || null); - } - /** - * Validates all rules for specified object and it's properties. - * @param object The object to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - validateObject(object, rules) { - return this.validate(object, null, rules || null); - } - /** - * Determines whether a rule exists in a set of rules. - * @param rules The rules to search. - * @parem rule The rule to find. - */ - ruleExists(rules, rule) { - let i = rules.length; - while (i--) { - if (rules[i].indexOf(rule) !== -1) { - return true; - } - } - return false; - } - getMessage(rule, object, value) { - const expression = rule.message || this.messageProvider.getMessage(rule.messageKey); - // tslint:disable-next-line:prefer-const - let { name: propertyName, displayName } = rule.property; - if (propertyName !== null) { - displayName = this.messageProvider.getDisplayName(propertyName, displayName); - } - const overrideContext = { - $displayName: displayName, - $propertyName: propertyName, - $value: value, - $object: object, - $config: rule.config, - // returns the name of a given property, given just the property name (irrespective of the property's displayName) - // split on capital letters, first letter ensured to be capitalized - $getDisplayName: this.getDisplayName - }; - return expression.evaluate({ bindingContext: object, overrideContext }, this.lookupFunctions); - } - validateRuleSequence(object, propertyName, ruleSequence, sequence, results) { - // are we validating all properties or a single property? - const validateAllProperties = propertyName === null || propertyName === undefined; - const rules = ruleSequence[sequence]; - let allValid = true; - // validate each rule. - const promises = []; - for (let i = 0; i < rules.length; i++) { - const rule = rules[i]; - // is the rule related to the property we're validating. - // tslint:disable-next-line:triple-equals | Use loose equality for property keys - if (!validateAllProperties && rule.property.name != propertyName) { - continue; - } - // is this a conditional rule? is the condition met? - if (rule.when && !rule.when(object)) { - continue; - } - // validate. - const value = rule.property.name === null ? object : object[rule.property.name]; - let promiseOrBoolean = rule.condition(value, object); - if (!(promiseOrBoolean instanceof Promise)) { - promiseOrBoolean = Promise.resolve(promiseOrBoolean); - } - promises.push(promiseOrBoolean.then(valid => { - const message = valid ? null : this.getMessage(rule, object, value); - results.push(new ValidateResult(rule, object, rule.property.name, valid, message)); - allValid = allValid && valid; - return valid; - })); - } - return Promise.all(promises) - .then(() => { - sequence++; - if (allValid && sequence < ruleSequence.length) { - return this.validateRuleSequence(object, propertyName, ruleSequence, sequence, results); - } - return results; - }); - } - validate(object, propertyName, rules) { - // rules specified? - if (!rules) { - // no. attempt to locate the rules. - rules = Rules.get(object); - } - // any rules? - if (!rules || rules.length === 0) { - return Promise.resolve([]); - } - return this.validateRuleSequence(object, propertyName, rules, 0, []); - } -} -StandardValidator.inject = [ValidationMessageProvider, ViewResources]; diff --git a/dist/es2015/implementation/validation-message-parser.d.ts b/dist/es2015/implementation/validation-message-parser.d.ts deleted file mode 100644 index 39d288c0..00000000 --- a/dist/es2015/implementation/validation-message-parser.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Expression, AccessScope } from 'aurelia-binding'; -import { BindingLanguage } from 'aurelia-templating'; -import { ExpressionVisitor } from './expression-visitor'; -export declare class ValidationMessageParser { - private bindinqLanguage; - static inject: (typeof BindingLanguage)[]; - private emptyStringExpression; - private nullExpression; - private undefinedExpression; - private cache; - constructor(bindinqLanguage: BindingLanguage); - parse(message: string): Expression; - private coalesce(part); -} -export declare class MessageExpressionValidator extends ExpressionVisitor { - private originalMessage; - static validate(expression: Expression, originalMessage: string): void; - constructor(originalMessage: string); - visitAccessScope(access: AccessScope): void; -} diff --git a/dist/es2015/implementation/validation-message-parser.js b/dist/es2015/implementation/validation-message-parser.js deleted file mode 100644 index dd93ce70..00000000 --- a/dist/es2015/implementation/validation-message-parser.js +++ /dev/null @@ -1,53 +0,0 @@ -import { LiteralString, Binary, Conditional, LiteralPrimitive, CallMember } from 'aurelia-binding'; -import { BindingLanguage } from 'aurelia-templating'; -import * as LogManager from 'aurelia-logging'; -import { ExpressionVisitor } from './expression-visitor'; -export class ValidationMessageParser { - constructor(bindinqLanguage) { - this.bindinqLanguage = bindinqLanguage; - this.emptyStringExpression = new LiteralString(''); - this.nullExpression = new LiteralPrimitive(null); - this.undefinedExpression = new LiteralPrimitive(undefined); - this.cache = {}; - } - parse(message) { - if (this.cache[message] !== undefined) { - return this.cache[message]; - } - const parts = this.bindinqLanguage.parseInterpolation(null, message); - if (parts === null) { - return new LiteralString(message); - } - let expression = new LiteralString(parts[0]); - for (let i = 1; i < parts.length; i += 2) { - expression = new Binary('+', expression, new Binary('+', this.coalesce(parts[i]), new LiteralString(parts[i + 1]))); - } - MessageExpressionValidator.validate(expression, message); - this.cache[message] = expression; - return expression; - } - coalesce(part) { - // part === null || part === undefined ? '' : part - return new Conditional(new Binary('||', new Binary('===', part, this.nullExpression), new Binary('===', part, this.undefinedExpression)), this.emptyStringExpression, new CallMember(part, 'toString', [])); - } -} -ValidationMessageParser.inject = [BindingLanguage]; -export class MessageExpressionValidator extends ExpressionVisitor { - constructor(originalMessage) { - super(); - this.originalMessage = originalMessage; - } - static validate(expression, originalMessage) { - const visitor = new MessageExpressionValidator(originalMessage); - expression.accept(visitor); - } - visitAccessScope(access) { - if (access.ancestor !== 0) { - throw new Error('$parent is not permitted in validation message expressions.'); - } - if (['displayName', 'propertyName', 'value', 'object', 'config', 'getDisplayName'].indexOf(access.name) !== -1) { - LogManager.getLogger('aurelia-validation') - .warn(`Did you mean to use "$${access.name}" instead of "${access.name}" in this validation message template: "${this.originalMessage}"?`); - } - } -} diff --git a/dist/es2015/implementation/validation-messages.d.ts b/dist/es2015/implementation/validation-messages.d.ts deleted file mode 100644 index eb4cb9d4..00000000 --- a/dist/es2015/implementation/validation-messages.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Expression } from 'aurelia-binding'; -import { ValidationMessageParser } from './validation-message-parser'; -export interface ValidationMessages { - [key: string]: string; -} -/** - * Dictionary of validation messages. [messageKey]: messageExpression - */ -export declare const validationMessages: ValidationMessages; -/** - * Retrieves validation messages and property display names. - */ -export declare class ValidationMessageProvider { - parser: ValidationMessageParser; - static inject: (typeof ValidationMessageParser)[]; - constructor(parser: ValidationMessageParser); - /** - * Returns a message binding expression that corresponds to the key. - * @param key The message key. - */ - getMessage(key: string): Expression; - /** - * Formulates a property display name using the property name and the configured - * displayName (if provided). - * Override this with your own custom logic. - * @param propertyName The property name. - */ - getDisplayName(propertyName: string | number, displayName?: string | null | (() => string)): string; -} diff --git a/dist/es2015/implementation/validation-messages.js b/dist/es2015/implementation/validation-messages.js deleted file mode 100644 index d64acf32..00000000 --- a/dist/es2015/implementation/validation-messages.js +++ /dev/null @@ -1,56 +0,0 @@ -import { ValidationMessageParser } from './validation-message-parser'; -/** - * Dictionary of validation messages. [messageKey]: messageExpression - */ -export const validationMessages = { - /** - * The default validation message. Used with rules that have no standard message. - */ - default: `\${$displayName} is invalid.`, - required: `\${$displayName} is required.`, - matches: `\${$displayName} is not correctly formatted.`, - email: `\${$displayName} is not a valid email.`, - minLength: `\${$displayName} must be at least \${$config.length} character\${$config.length === 1 ? '' : 's'}.`, - maxLength: `\${$displayName} cannot be longer than \${$config.length} character\${$config.length === 1 ? '' : 's'}.`, - minItems: `\${$displayName} must contain at least \${$config.count} item\${$config.count === 1 ? '' : 's'}.`, - maxItems: `\${$displayName} cannot contain more than \${$config.count} item\${$config.count === 1 ? '' : 's'}.`, - equals: `\${$displayName} must be \${$config.expectedValue}.`, -}; -/** - * Retrieves validation messages and property display names. - */ -export class ValidationMessageProvider { - constructor(parser) { - this.parser = parser; - } - /** - * Returns a message binding expression that corresponds to the key. - * @param key The message key. - */ - getMessage(key) { - let message; - if (key in validationMessages) { - message = validationMessages[key]; - } - else { - message = validationMessages['default']; - } - return this.parser.parse(message); - } - /** - * Formulates a property display name using the property name and the configured - * displayName (if provided). - * Override this with your own custom logic. - * @param propertyName The property name. - */ - getDisplayName(propertyName, displayName) { - if (displayName !== null && displayName !== undefined) { - return (displayName instanceof Function) ? displayName() : displayName; - } - // split on upper-case letters. - const words = propertyName.toString().split(/(?=[A-Z])/).join(' '); - // capitalize first letter. - return words.charAt(0).toUpperCase() + words.slice(1); - } -} -ValidationMessageProvider.inject = [ValidationMessageParser]; diff --git a/dist/es2015/implementation/validation-rules.d.ts b/dist/es2015/implementation/validation-rules.d.ts deleted file mode 100644 index 995b2a8a..00000000 --- a/dist/es2015/implementation/validation-rules.d.ts +++ /dev/null @@ -1,262 +0,0 @@ -import { Rule, RuleProperty, ValidationDisplayNameAccessor } from './rule'; -import { ValidationMessageParser } from './validation-message-parser'; -import { PropertyAccessorParser, PropertyAccessor } from '../property-accessor-parser'; -/** - * Part of the fluent rule API. Enables customizing property rules. - */ -export declare class FluentRuleCustomizer { - private fluentEnsure; - private fluentRules; - private parsers; - private rule; - constructor(property: RuleProperty, condition: (value: TValue, object?: TObject) => boolean | Promise, config: object | undefined, fluentEnsure: FluentEnsure, fluentRules: FluentRules, parsers: Parsers); - /** - * Validate subsequent rules after previously declared rules have - * been validated successfully. Use to postpone validation of costly - * rules until less expensive rules pass validation. - */ - then(): this; - /** - * Specifies the key to use when looking up the rule's validation message. - */ - withMessageKey(key: string): this; - /** - * Specifies rule's validation message. - */ - withMessage(message: string): this; - /** - * Specifies a condition that must be met before attempting to validate the rule. - * @param condition A function that accepts the object as a parameter and returns true - * or false whether the rule should be evaluated. - */ - when(condition: (object: TObject) => boolean): this; - /** - * Tags the rule instance, enabling the rule to be found easily - * using ValidationRules.taggedRules(rules, tag) - */ - tag(tag: string): this; - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - ensure(subject: string | ((model: TObject) => TValue2)): FluentRules; - /** - * Targets an object with validation rules. - */ - ensureObject(): FluentRules; - /** - * Rules that have been defined using the fluent API. - */ - readonly rules: Rule[][]; - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - on(target: any): FluentEnsure; - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - satisfies(condition: (value: TValue, object: TObject) => boolean | Promise, config?: object): FluentRuleCustomizer; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - satisfiesRule(name: string, ...args: any[]): FluentRuleCustomizer; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - required(): FluentRuleCustomizer; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - matches(regex: RegExp): FluentRuleCustomizer; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - email(): FluentRuleCustomizer; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - minLength(length: number): FluentRuleCustomizer; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - maxLength(length: number): FluentRuleCustomizer; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - minItems(count: number): FluentRuleCustomizer; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - maxItems(count: number): FluentRuleCustomizer; - /** - * Applies the "equals" validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - equals(expectedValue: TValue): FluentRuleCustomizer; -} -/** - * Part of the fluent rule API. Enables applying rules to properties and objects. - */ -export declare class FluentRules { - private fluentEnsure; - private parsers; - private property; - static customRules: { - [name: string]: { - condition: (value: any, object?: any, ...fluentArgs: any[]) => boolean | Promise; - argsToConfig?: (...args: any[]) => any; - }; - }; - /** - * Current rule sequence number. Used to postpone evaluation of rules until rules - * with lower sequence number have successfully validated. The "then" fluent API method - * manages this property, there's usually no need to set it directly. - */ - sequence: number; - constructor(fluentEnsure: FluentEnsure, parsers: Parsers, property: RuleProperty); - /** - * Sets the display name of the ensured property. - */ - displayName(name: string | ValidationDisplayNameAccessor | null): this; - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - satisfies(condition: (value: TValue, object?: TObject) => boolean | Promise, config?: object): FluentRuleCustomizer; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - satisfiesRule(name: string, ...args: any[]): FluentRuleCustomizer; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - required(): FluentRuleCustomizer; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - matches(regex: RegExp): FluentRuleCustomizer; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - email(): FluentRuleCustomizer; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - minLength(length: number): FluentRuleCustomizer; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - maxLength(length: number): FluentRuleCustomizer; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - minItems(count: number): FluentRuleCustomizer; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - maxItems(count: number): FluentRuleCustomizer; - /** - * Applies the "equals" validation rule to the property. - * null and undefined values are considered valid. - */ - equals(expectedValue: TValue): FluentRuleCustomizer; -} -/** - * Part of the fluent rule API. Enables targeting properties and objects with rules. - */ -export declare class FluentEnsure { - private parsers; - /** - * Rules that have been defined using the fluent API. - */ - rules: Rule[][]; - constructor(parsers: Parsers); - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor - * function. - */ - ensure(property: string | number | PropertyAccessor): FluentRules; - /** - * Targets an object with validation rules. - */ - ensureObject(): FluentRules; - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - on(target: any): this; - private assertInitialized(); - private mergeRules(fluentRules, propertyName); -} -/** - * Fluent rule definition API. - */ -export declare class ValidationRules { - private static parsers; - static initialize(messageParser: ValidationMessageParser, propertyParser: PropertyAccessorParser): void; - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - static ensure(property: string | number | PropertyAccessor): FluentRules; - /** - * Targets an object with validation rules. - */ - static ensureObject(): FluentRules; - /** - * Defines a custom rule. - * @param name The name of the custom rule. Also serves as the message key. - * @param condition The rule function. - * @param message The message expression - * @param argsToConfig A function that maps the rule's arguments to a "config" - * object that can be used when evaluating the message expression. - */ - static customRule(name: string, condition: (value: any, object?: any, ...args: any[]) => boolean | Promise, message: string, argsToConfig?: (...args: any[]) => any): void; - /** - * Returns rules with the matching tag. - * @param rules The rules to search. - * @param tag The tag to search for. - */ - static taggedRules(rules: Rule[][], tag: string): Rule[][]; - /** - * Returns rules that have no tag. - * @param rules The rules to search. - */ - static untaggedRules(rules: Rule[][]): Rule[][]; - /** - * Removes the rules from a class or object. - * @param target A class or object. - */ - static off(target: any): void; -} -export interface Parsers { - message: ValidationMessageParser; - property: PropertyAccessorParser; -} diff --git a/dist/es2015/implementation/validation-rules.js b/dist/es2015/implementation/validation-rules.js deleted file mode 100644 index a099896f..00000000 --- a/dist/es2015/implementation/validation-rules.js +++ /dev/null @@ -1,412 +0,0 @@ -import { Rules } from './rules'; -import { validationMessages } from './validation-messages'; -import { isString } from '../util'; -/** - * Part of the fluent rule API. Enables customizing property rules. - */ -export class FluentRuleCustomizer { - constructor(property, condition, config = {}, fluentEnsure, fluentRules, parsers) { - this.fluentEnsure = fluentEnsure; - this.fluentRules = fluentRules; - this.parsers = parsers; - this.rule = { - property, - condition, - config, - when: null, - messageKey: 'default', - message: null, - sequence: fluentRules.sequence - }; - this.fluentEnsure._addRule(this.rule); - } - /** - * Validate subsequent rules after previously declared rules have - * been validated successfully. Use to postpone validation of costly - * rules until less expensive rules pass validation. - */ - then() { - this.fluentRules.sequence++; - return this; - } - /** - * Specifies the key to use when looking up the rule's validation message. - */ - withMessageKey(key) { - this.rule.messageKey = key; - this.rule.message = null; - return this; - } - /** - * Specifies rule's validation message. - */ - withMessage(message) { - this.rule.messageKey = 'custom'; - this.rule.message = this.parsers.message.parse(message); - return this; - } - /** - * Specifies a condition that must be met before attempting to validate the rule. - * @param condition A function that accepts the object as a parameter and returns true - * or false whether the rule should be evaluated. - */ - when(condition) { - this.rule.when = condition; - return this; - } - /** - * Tags the rule instance, enabling the rule to be found easily - * using ValidationRules.taggedRules(rules, tag) - */ - tag(tag) { - this.rule.tag = tag; - return this; - } - ///// FluentEnsure APIs ///// - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - ensure(subject) { - return this.fluentEnsure.ensure(subject); - } - /** - * Targets an object with validation rules. - */ - ensureObject() { - return this.fluentEnsure.ensureObject(); - } - /** - * Rules that have been defined using the fluent API. - */ - get rules() { - return this.fluentEnsure.rules; - } - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - on(target) { - return this.fluentEnsure.on(target); - } - ///////// FluentRules APIs ///////// - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - satisfies(condition, config) { - return this.fluentRules.satisfies(condition, config); - } - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - satisfiesRule(name, ...args) { - return this.fluentRules.satisfiesRule(name, ...args); - } - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - required() { - return this.fluentRules.required(); - } - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - matches(regex) { - return this.fluentRules.matches(regex); - } - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - email() { - return this.fluentRules.email(); - } - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - minLength(length) { - return this.fluentRules.minLength(length); - } - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - maxLength(length) { - return this.fluentRules.maxLength(length); - } - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - minItems(count) { - return this.fluentRules.minItems(count); - } - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - maxItems(count) { - return this.fluentRules.maxItems(count); - } - /** - * Applies the "equals" validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - equals(expectedValue) { - return this.fluentRules.equals(expectedValue); - } -} -/** - * Part of the fluent rule API. Enables applying rules to properties and objects. - */ -export class FluentRules { - constructor(fluentEnsure, parsers, property) { - this.fluentEnsure = fluentEnsure; - this.parsers = parsers; - this.property = property; - /** - * Current rule sequence number. Used to postpone evaluation of rules until rules - * with lower sequence number have successfully validated. The "then" fluent API method - * manages this property, there's usually no need to set it directly. - */ - this.sequence = 0; - } - /** - * Sets the display name of the ensured property. - */ - displayName(name) { - this.property.displayName = name; - return this; - } - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - satisfies(condition, config) { - return new FluentRuleCustomizer(this.property, condition, config, this.fluentEnsure, this, this.parsers); - } - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - satisfiesRule(name, ...args) { - let rule = FluentRules.customRules[name]; - if (!rule) { - // standard rule? - rule = this[name]; - if (rule instanceof Function) { - return rule.call(this, ...args); - } - throw new Error(`Rule with name "${name}" does not exist.`); - } - const config = rule.argsToConfig ? rule.argsToConfig(...args) : undefined; - return this.satisfies((value, obj) => rule.condition.call(this, value, obj, ...args), config) - .withMessageKey(name); - } - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - required() { - return this.satisfies(value => value !== null - && value !== undefined - && !(isString(value) && !/\S/.test(value))).withMessageKey('required'); - } - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - matches(regex) { - return this.satisfies(value => value === null || value === undefined || value.length === 0 || regex.test(value)) - .withMessageKey('matches'); - } - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - email() { - // regex from https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address - /* tslint:disable:max-line-length */ - return this.matches(/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/) - .withMessageKey('email'); - } - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - minLength(length) { - return this.satisfies((value) => value === null || value === undefined || value.length === 0 || value.length >= length, { length }) - .withMessageKey('minLength'); - } - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - maxLength(length) { - return this.satisfies((value) => value === null || value === undefined || value.length === 0 || value.length <= length, { length }) - .withMessageKey('maxLength'); - } - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - minItems(count) { - return this.satisfies((value) => value === null || value === undefined || value.length >= count, { count }) - .withMessageKey('minItems'); - } - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - maxItems(count) { - return this.satisfies((value) => value === null || value === undefined || value.length <= count, { count }) - .withMessageKey('maxItems'); - } - /** - * Applies the "equals" validation rule to the property. - * null and undefined values are considered valid. - */ - equals(expectedValue) { - return this.satisfies(value => value === null || value === undefined || value === '' || value === expectedValue, { expectedValue }) - .withMessageKey('equals'); - } -} -FluentRules.customRules = {}; -/** - * Part of the fluent rule API. Enables targeting properties and objects with rules. - */ -export class FluentEnsure { - constructor(parsers) { - this.parsers = parsers; - /** - * Rules that have been defined using the fluent API. - */ - this.rules = []; - } - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor - * function. - */ - ensure(property) { - this.assertInitialized(); - const name = this.parsers.property.parse(property); - const fluentRules = new FluentRules(this, this.parsers, { name, displayName: null }); - return this.mergeRules(fluentRules, name); - } - /** - * Targets an object with validation rules. - */ - ensureObject() { - this.assertInitialized(); - const fluentRules = new FluentRules(this, this.parsers, { name: null, displayName: null }); - return this.mergeRules(fluentRules, null); - } - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - on(target) { - Rules.set(target, this.rules); - return this; - } - /** - * Adds a rule definition to the sequenced ruleset. - * @internal - */ - _addRule(rule) { - while (this.rules.length < rule.sequence + 1) { - this.rules.push([]); - } - this.rules[rule.sequence].push(rule); - } - assertInitialized() { - if (this.parsers) { - return; - } - throw new Error(`Did you forget to add ".plugin('aurelia-validation')" to your main.js?`); - } - mergeRules(fluentRules, propertyName) { - // tslint:disable-next-line:triple-equals | Use loose equality for property keys - const existingRules = this.rules.find(r => r.length > 0 && r[0].property.name == propertyName); - if (existingRules) { - const rule = existingRules[existingRules.length - 1]; - fluentRules.sequence = rule.sequence; - if (rule.property.displayName !== null) { - fluentRules = fluentRules.displayName(rule.property.displayName); - } - } - return fluentRules; - } -} -/** - * Fluent rule definition API. - */ -export class ValidationRules { - static initialize(messageParser, propertyParser) { - this.parsers = { - message: messageParser, - property: propertyParser - }; - } - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - static ensure(property) { - return new FluentEnsure(ValidationRules.parsers).ensure(property); - } - /** - * Targets an object with validation rules. - */ - static ensureObject() { - return new FluentEnsure(ValidationRules.parsers).ensureObject(); - } - /** - * Defines a custom rule. - * @param name The name of the custom rule. Also serves as the message key. - * @param condition The rule function. - * @param message The message expression - * @param argsToConfig A function that maps the rule's arguments to a "config" - * object that can be used when evaluating the message expression. - */ - static customRule(name, condition, message, argsToConfig) { - validationMessages[name] = message; - FluentRules.customRules[name] = { condition, argsToConfig }; - } - /** - * Returns rules with the matching tag. - * @param rules The rules to search. - * @param tag The tag to search for. - */ - static taggedRules(rules, tag) { - return rules.map(x => x.filter(r => r.tag === tag)); - } - /** - * Returns rules that have no tag. - * @param rules The rules to search. - */ - static untaggedRules(rules) { - return rules.map(x => x.filter(r => r.tag === undefined)); - } - /** - * Removes the rules from a class or object. - * @param target A class or object. - */ - static off(target) { - Rules.unset(target); - } -} diff --git a/dist/es2015/property-accessor-parser.d.ts b/dist/es2015/property-accessor-parser.d.ts deleted file mode 100644 index ba64614b..00000000 --- a/dist/es2015/property-accessor-parser.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Parser } from 'aurelia-binding'; -export declare type PropertyAccessor = (object: TObject) => TValue; -export declare class PropertyAccessorParser { - private parser; - static inject: (typeof Parser)[]; - constructor(parser: Parser); - parse(property: string | number | PropertyAccessor): string | number; -} -export declare function getAccessorExpression(fn: string): string; diff --git a/dist/es2015/property-accessor-parser.js b/dist/es2015/property-accessor-parser.js deleted file mode 100644 index 7ed019fa..00000000 --- a/dist/es2015/property-accessor-parser.js +++ /dev/null @@ -1,31 +0,0 @@ -import { Parser, AccessMember, AccessScope } from 'aurelia-binding'; -import { isString, isNumber } from './util'; -export class PropertyAccessorParser { - constructor(parser) { - this.parser = parser; - } - parse(property) { - if (isString(property) || isNumber(property)) { - return property; - } - const accessorText = getAccessorExpression(property.toString()); - const accessor = this.parser.parse(accessorText); - if (accessor instanceof AccessScope - || accessor instanceof AccessMember && accessor.object instanceof AccessScope) { - return accessor.name; - } - throw new Error(`Invalid property expression: "${accessor}"`); - } -} -PropertyAccessorParser.inject = [Parser]; -export function getAccessorExpression(fn) { - /* tslint:disable:max-line-length */ - const classic = /^function\s*\([$_\w\d]+\)\s*\{(?:\s*"use strict";)?\s*(?:[$_\w\d.['"\]+;]+)?\s*return\s+[$_\w\d]+\.([$_\w\d]+)\s*;?\s*\}$/; - /* tslint:enable:max-line-length */ - const arrow = /^\(?[$_\w\d]+\)?\s*=>\s*[$_\w\d]+\.([$_\w\d]+)$/; - const match = classic.exec(fn) || arrow.exec(fn); - if (match === null) { - throw new Error(`Unable to parse accessor function:\n${fn}`); - } - return match[1]; -} diff --git a/dist/es2015/property-info.js b/dist/es2015/property-info.js deleted file mode 100644 index 031b4665..00000000 --- a/dist/es2015/property-info.js +++ /dev/null @@ -1,41 +0,0 @@ -import { AccessMember, AccessScope, AccessKeyed, BindingBehavior, ValueConverter, getContextFor } from 'aurelia-binding'; -function getObject(expression, objectExpression, source) { - const value = objectExpression.evaluate(source, null); - if (value === null || value === undefined || value instanceof Object) { - return value; - } - // tslint:disable-next-line:max-line-length - throw new Error(`The '${objectExpression}' part of '${expression}' evaluates to ${value} instead of an object, null or undefined.`); -} -/** - * Retrieves the object and property name for the specified expression. - * @param expression The expression - * @param source The scope - */ -export function getPropertyInfo(expression, source) { - const originalExpression = expression; - while (expression instanceof BindingBehavior || expression instanceof ValueConverter) { - expression = expression.expression; - } - let object; - let propertyName; - if (expression instanceof AccessScope) { - object = getContextFor(expression.name, source, expression.ancestor); - propertyName = expression.name; - } - else if (expression instanceof AccessMember) { - object = getObject(originalExpression, expression.object, source); - propertyName = expression.name; - } - else if (expression instanceof AccessKeyed) { - object = getObject(originalExpression, expression.object, source); - propertyName = expression.key.evaluate(source); - } - else { - throw new Error(`Expression '${originalExpression}' is not compatible with the validate binding-behavior.`); - } - if (object === null || object === undefined) { - return null; - } - return { object, propertyName }; -} diff --git a/dist/es2015/util.d.ts b/dist/es2015/util.d.ts deleted file mode 100644 index f6873f03..00000000 --- a/dist/es2015/util.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export declare function isString(value: any): boolean; -export declare function isNumber(value: any): boolean; diff --git a/dist/es2015/util.js b/dist/es2015/util.js deleted file mode 100644 index 8b4ad402..00000000 --- a/dist/es2015/util.js +++ /dev/null @@ -1,6 +0,0 @@ -export function isString(value) { - return Object.prototype.toString.call(value) === '[object String]'; -} -export function isNumber(value) { - return Object.prototype.toString.call(value) === '[object Number]'; -} diff --git a/dist/es2015/validate-binding-behavior-base.d.ts b/dist/es2015/validate-binding-behavior-base.d.ts deleted file mode 100644 index 971c8e83..00000000 --- a/dist/es2015/validate-binding-behavior-base.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { TaskQueue } from 'aurelia-task-queue'; -import { ValidationController } from './validation-controller'; -import { validateTrigger } from './validate-trigger'; -/** - * Binding behavior. Indicates the bound property should be validated. - */ -export declare abstract class ValidateBindingBehaviorBase { - private taskQueue; - constructor(taskQueue: TaskQueue); - protected abstract getValidateTrigger(controller: ValidationController): validateTrigger; - bind(binding: any, source: any, rulesOrController?: ValidationController | any, rules?: any): void; - unbind(binding: any): void; -} diff --git a/dist/es2015/validate-binding-behavior-base.js b/dist/es2015/validate-binding-behavior-base.js deleted file mode 100644 index b35e5805..00000000 --- a/dist/es2015/validate-binding-behavior-base.js +++ /dev/null @@ -1,76 +0,0 @@ -import { Optional } from 'aurelia-dependency-injection'; -import { ValidationController } from './validation-controller'; -import { validateTrigger } from './validate-trigger'; -import { getTargetDOMElement } from './get-target-dom-element'; -/** - * Binding behavior. Indicates the bound property should be validated. - */ -export class ValidateBindingBehaviorBase { - constructor(taskQueue) { - this.taskQueue = taskQueue; - } - bind(binding, source, rulesOrController, rules) { - // identify the target element. - const target = getTargetDOMElement(binding, source); - // locate the controller. - let controller; - if (rulesOrController instanceof ValidationController) { - controller = rulesOrController; - } - else { - controller = source.container.get(Optional.of(ValidationController)); - rules = rulesOrController; - } - if (controller === null) { - throw new Error(`A ValidationController has not been registered.`); - } - controller.registerBinding(binding, target, rules); - binding.validationController = controller; - const trigger = this.getValidateTrigger(controller); - // tslint:disable-next-line:no-bitwise - if (trigger & validateTrigger.change) { - binding.vbbUpdateSource = binding.updateSource; - // tslint:disable-next-line:only-arrow-functions - // tslint:disable-next-line:space-before-function-paren - binding.updateSource = function (value) { - this.vbbUpdateSource(value); - this.validationController.validateBinding(this); - }; - } - // tslint:disable-next-line:no-bitwise - if (trigger & validateTrigger.blur) { - binding.validateBlurHandler = () => { - this.taskQueue.queueMicroTask(() => controller.validateBinding(binding)); - }; - binding.validateTarget = target; - target.addEventListener('blur', binding.validateBlurHandler); - } - if (trigger !== validateTrigger.manual) { - binding.standardUpdateTarget = binding.updateTarget; - // tslint:disable-next-line:only-arrow-functions - // tslint:disable-next-line:space-before-function-paren - binding.updateTarget = function (value) { - this.standardUpdateTarget(value); - this.validationController.resetBinding(this); - }; - } - } - unbind(binding) { - // reset the binding to it's original state. - if (binding.vbbUpdateSource) { - binding.updateSource = binding.vbbUpdateSource; - binding.vbbUpdateSource = null; - } - if (binding.standardUpdateTarget) { - binding.updateTarget = binding.standardUpdateTarget; - binding.standardUpdateTarget = null; - } - if (binding.validateBlurHandler) { - binding.validateTarget.removeEventListener('blur', binding.validateBlurHandler); - binding.validateBlurHandler = null; - binding.validateTarget = null; - } - binding.validationController.unregisterBinding(binding); - binding.validationController = null; - } -} diff --git a/dist/es2015/validate-binding-behavior.js b/dist/es2015/validate-binding-behavior.js deleted file mode 100644 index 318d227a..00000000 --- a/dist/es2015/validate-binding-behavior.js +++ /dev/null @@ -1,57 +0,0 @@ -import { TaskQueue } from 'aurelia-task-queue'; -import { validateTrigger } from './validate-trigger'; -import { ValidateBindingBehaviorBase } from './validate-binding-behavior-base'; -/** - * Binding behavior. Indicates the bound property should be validated - * when the validate trigger specified by the associated controller's - * validateTrigger property occurs. - */ -export class ValidateBindingBehavior extends ValidateBindingBehaviorBase { - getValidateTrigger(controller) { - return controller.validateTrigger; - } -} -ValidateBindingBehavior.inject = [TaskQueue]; -/** - * Binding behavior. Indicates the bound property will be validated - * manually, by calling controller.validate(). No automatic validation - * triggered by data-entry or blur will occur. - */ -export class ValidateManuallyBindingBehavior extends ValidateBindingBehaviorBase { - getValidateTrigger() { - return validateTrigger.manual; - } -} -ValidateManuallyBindingBehavior.inject = [TaskQueue]; -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs. - */ -export class ValidateOnBlurBindingBehavior extends ValidateBindingBehaviorBase { - getValidateTrigger() { - return validateTrigger.blur; - } -} -ValidateOnBlurBindingBehavior.inject = [TaskQueue]; -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element is changed by the user, causing a change - * to the model. - */ -export class ValidateOnChangeBindingBehavior extends ValidateBindingBehaviorBase { - getValidateTrigger() { - return validateTrigger.change; - } -} -ValidateOnChangeBindingBehavior.inject = [TaskQueue]; -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs or is changed by the user, causing - * a change to the model. - */ -export class ValidateOnChangeOrBlurBindingBehavior extends ValidateBindingBehaviorBase { - getValidateTrigger() { - return validateTrigger.changeOrBlur; - } -} -ValidateOnChangeOrBlurBindingBehavior.inject = [TaskQueue]; diff --git a/dist/es2015/validate-event.js b/dist/es2015/validate-event.js deleted file mode 100644 index e6c5d57b..00000000 --- a/dist/es2015/validate-event.js +++ /dev/null @@ -1,37 +0,0 @@ -export class ValidateEvent { - constructor( - /** - * The type of validate event. Either "validate" or "reset". - */ - type, - /** - * The controller's current array of errors. For an array containing both - * failed rules and passed rules, use the "results" property. - */ - errors, - /** - * The controller's current array of validate results. This - * includes both passed rules and failed rules. For an array of only failed rules, - * use the "errors" property. - */ - results, - /** - * The instruction passed to the "validate" or "reset" event. Will be null when - * the controller's validate/reset method was called with no instruction argument. - */ - instruction, - /** - * In events with type === "validate", this property will contain the result - * of validating the instruction (see "instruction" property). Use the controllerValidateResult - * to access the validate results specific to the call to "validate" - * (as opposed to using the "results" and "errors" properties to access the controller's entire - * set of results/errors). - */ - controllerValidateResult) { - this.type = type; - this.errors = errors; - this.results = results; - this.instruction = instruction; - this.controllerValidateResult = controllerValidateResult; - } -} diff --git a/dist/es2015/validate-instruction.d.ts b/dist/es2015/validate-instruction.d.ts deleted file mode 100644 index 2f792a70..00000000 --- a/dist/es2015/validate-instruction.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Instructions for the validation controller's validate method. - */ -export interface ValidateInstruction { - /** - * The object to validate. - */ - object: any; - /** - * The property to validate. Optional. - */ - propertyName?: any; - /** - * The rules to validate. Optional. - */ - rules?: any; -} diff --git a/dist/es2015/validate-instruction.js b/dist/es2015/validate-instruction.js deleted file mode 100644 index e69de29b..00000000 diff --git a/dist/es2015/validate-result.d.ts b/dist/es2015/validate-result.d.ts deleted file mode 100644 index 91d79995..00000000 --- a/dist/es2015/validate-result.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * The result of validating an individual validation rule. - */ -export declare class ValidateResult { - rule: any; - object: any; - propertyName: string | number | null; - valid: boolean; - message: string | null; - private static nextId; - /** - * A number that uniquely identifies the result instance. - */ - id: number; - /** - * @param rule The rule associated with the result. Validator implementation specific. - * @param object The object that was validated. - * @param propertyName The name of the property that was validated. - * @param error The error, if the result is a validation error. - */ - constructor(rule: any, object: any, propertyName: string | number | null, valid: boolean, message?: string | null); - toString(): string | null; -} diff --git a/dist/es2015/validate-result.js b/dist/es2015/validate-result.js deleted file mode 100644 index 37e90f42..00000000 --- a/dist/es2015/validate-result.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * The result of validating an individual validation rule. - */ -export class ValidateResult { - /** - * @param rule The rule associated with the result. Validator implementation specific. - * @param object The object that was validated. - * @param propertyName The name of the property that was validated. - * @param error The error, if the result is a validation error. - */ - constructor(rule, object, propertyName, valid, message = null) { - this.rule = rule; - this.object = object; - this.propertyName = propertyName; - this.valid = valid; - this.message = message; - this.id = ValidateResult.nextId++; - } - toString() { - return this.valid ? 'Valid.' : this.message; - } -} -ValidateResult.nextId = 0; diff --git a/dist/es2015/validate-trigger.d.ts b/dist/es2015/validate-trigger.d.ts deleted file mode 100644 index 43e76851..00000000 --- a/dist/es2015/validate-trigger.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Validation triggers. - */ -export declare enum validateTrigger { - /** - * Manual validation. Use the controller's `validate()` and `reset()` methods - * to validate all bindings. - */ - manual = 0, - /** - * Validate the binding when the binding's target element fires a DOM "blur" event. - */ - blur = 1, - /** - * Validate the binding when it updates the model due to a change in the view. - */ - change = 2, - /** - * Validate the binding when the binding's target element fires a DOM "blur" event and - * when it updates the model due to a change in the view. - */ - changeOrBlur = 3, -} diff --git a/dist/es2015/validate-trigger.js b/dist/es2015/validate-trigger.js deleted file mode 100644 index c00b9e21..00000000 --- a/dist/es2015/validate-trigger.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Validation triggers. - */ -export var validateTrigger; -(function (validateTrigger) { - /** - * Manual validation. Use the controller's `validate()` and `reset()` methods - * to validate all bindings. - */ - validateTrigger[validateTrigger["manual"] = 0] = "manual"; - /** - * Validate the binding when the binding's target element fires a DOM "blur" event. - */ - validateTrigger[validateTrigger["blur"] = 1] = "blur"; - /** - * Validate the binding when it updates the model due to a change in the view. - */ - validateTrigger[validateTrigger["change"] = 2] = "change"; - /** - * Validate the binding when the binding's target element fires a DOM "blur" event and - * when it updates the model due to a change in the view. - */ - validateTrigger[validateTrigger["changeOrBlur"] = 3] = "changeOrBlur"; -})(validateTrigger || (validateTrigger = {})); diff --git a/dist/es2015/validation-controller-factory.js b/dist/es2015/validation-controller-factory.js deleted file mode 100644 index b2e86933..00000000 --- a/dist/es2015/validation-controller-factory.js +++ /dev/null @@ -1,34 +0,0 @@ -import { ValidationController } from './validation-controller'; -import { Validator } from './validator'; -import { PropertyAccessorParser } from './property-accessor-parser'; -/** - * Creates ValidationController instances. - */ -export class ValidationControllerFactory { - constructor(container) { - this.container = container; - } - static get(container) { - return new ValidationControllerFactory(container); - } - /** - * Creates a new controller instance. - */ - create(validator) { - if (!validator) { - validator = this.container.get(Validator); - } - const propertyParser = this.container.get(PropertyAccessorParser); - return new ValidationController(validator, propertyParser); - } - /** - * Creates a new controller and registers it in the current element's container so that it's - * available to the validate binding behavior and renderers. - */ - createForCurrentScope(validator) { - const controller = this.create(validator); - this.container.registerInstance(ValidationController, controller); - return controller; - } -} -ValidationControllerFactory['protocol:aurelia:resolver'] = true; diff --git a/dist/es2015/validation-controller.d.ts b/dist/es2015/validation-controller.d.ts deleted file mode 100644 index 7f208d49..00000000 --- a/dist/es2015/validation-controller.d.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { Binding } from 'aurelia-binding'; -import { Validator } from './validator'; -import { validateTrigger } from './validate-trigger'; -import { ValidationRenderer } from './validation-renderer'; -import { ValidateResult } from './validate-result'; -import { ValidateInstruction } from './validate-instruction'; -import { ControllerValidateResult } from './controller-validate-result'; -import { PropertyAccessorParser, PropertyAccessor } from './property-accessor-parser'; -import { ValidateEvent } from './validate-event'; -/** - * Orchestrates validation. - * Manages a set of bindings, renderers and objects. - * Exposes the current list of validation results for binding purposes. - */ -export declare class ValidationController { - private validator; - private propertyParser; - static inject: (typeof PropertyAccessorParser | typeof Validator)[]; - private bindings; - private renderers; - /** - * Validation results that have been rendered by the controller. - */ - private results; - /** - * Validation errors that have been rendered by the controller. - */ - errors: ValidateResult[]; - /** - * Whether the controller is currently validating. - */ - validating: boolean; - private elements; - private objects; - /** - * The trigger that will invoke automatic validation of a property used in a binding. - */ - validateTrigger: validateTrigger; - private finishValidating; - private eventCallbacks; - constructor(validator: Validator, propertyParser: PropertyAccessorParser); - /** - * Subscribe to controller validate and reset events. These events occur when the - * controller's "validate"" and "reset" methods are called. - * @param callback The callback to be invoked when the controller validates or resets. - */ - subscribe(callback: (event: ValidateEvent) => void): { - dispose: () => void; - }; - /** - * Adds an object to the set of objects that should be validated when validate is called. - * @param object The object. - * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. - */ - addObject(object: any, rules?: any): void; - /** - * Removes an object from the set of objects that should be validated when validate is called. - * @param object The object. - */ - removeObject(object: any): void; - /** - * Adds and renders an error. - */ - addError(message: string, object: TObject, propertyName?: string | PropertyAccessor | null): ValidateResult; - /** - * Removes and unrenders an error. - */ - removeError(result: ValidateResult): void; - /** - * Adds a renderer. - * @param renderer The renderer. - */ - addRenderer(renderer: ValidationRenderer): void; - /** - * Removes a renderer. - * @param renderer The renderer. - */ - removeRenderer(renderer: ValidationRenderer): void; - /** - * Registers a binding with the controller. - * @param binding The binding instance. - * @param target The DOM element. - * @param rules (optional) rules associated with the binding. Validator implementation specific. - */ - registerBinding(binding: Binding, target: Element, rules?: any): void; - /** - * Unregisters a binding with the controller. - * @param binding The binding instance. - */ - unregisterBinding(binding: Binding): void; - /** - * Interprets the instruction and returns a predicate that will identify - * relevant results in the list of rendered validation results. - */ - private getInstructionPredicate(instruction?); - /** - * Validates and renders results. - * @param instruction Optional. Instructions on what to validate. If undefined, all - * objects and bindings will be validated. - */ - validate(instruction?: ValidateInstruction): Promise; - /** - * Resets any rendered validation results (unrenders). - * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results - * will be unrendered. - */ - reset(instruction?: ValidateInstruction): void; - /** - * Gets the elements associated with an object and propertyName (if any). - */ - private getAssociatedElements({object, propertyName}); - private processResultDelta(kind, oldResults, newResults); - /** - * Validates the property associated with a binding. - */ - validateBinding(binding: Binding): void; - /** - * Resets the results for a property associated with a binding. - */ - resetBinding(binding: Binding): void; - /** - * Changes the controller's validateTrigger. - * @param newTrigger The new validateTrigger - */ - changeTrigger(newTrigger: validateTrigger): void; - /** - * Revalidates the controller's current set of errors. - */ - revalidateErrors(): void; - private invokeCallbacks(instruction, result); -} diff --git a/dist/es2015/validation-controller.js b/dist/es2015/validation-controller.js deleted file mode 100644 index 2428a303..00000000 --- a/dist/es2015/validation-controller.js +++ /dev/null @@ -1,392 +0,0 @@ -import { Validator } from './validator'; -import { validateTrigger } from './validate-trigger'; -import { getPropertyInfo } from './property-info'; -import { ValidateResult } from './validate-result'; -import { PropertyAccessorParser } from './property-accessor-parser'; -import { ValidateEvent } from './validate-event'; -/** - * Orchestrates validation. - * Manages a set of bindings, renderers and objects. - * Exposes the current list of validation results for binding purposes. - */ -export class ValidationController { - constructor(validator, propertyParser) { - this.validator = validator; - this.propertyParser = propertyParser; - // Registered bindings (via the validate binding behavior) - this.bindings = new Map(); - // Renderers that have been added to the controller instance. - this.renderers = []; - /** - * Validation results that have been rendered by the controller. - */ - this.results = []; - /** - * Validation errors that have been rendered by the controller. - */ - this.errors = []; - /** - * Whether the controller is currently validating. - */ - this.validating = false; - // Elements related to validation results that have been rendered. - this.elements = new Map(); - // Objects that have been added to the controller instance (entity-style validation). - this.objects = new Map(); - /** - * The trigger that will invoke automatic validation of a property used in a binding. - */ - this.validateTrigger = validateTrigger.blur; - // Promise that resolves when validation has completed. - this.finishValidating = Promise.resolve(); - this.eventCallbacks = []; - } - /** - * Subscribe to controller validate and reset events. These events occur when the - * controller's "validate"" and "reset" methods are called. - * @param callback The callback to be invoked when the controller validates or resets. - */ - subscribe(callback) { - this.eventCallbacks.push(callback); - return { - dispose: () => { - const index = this.eventCallbacks.indexOf(callback); - if (index === -1) { - return; - } - this.eventCallbacks.splice(index, 1); - } - }; - } - /** - * Adds an object to the set of objects that should be validated when validate is called. - * @param object The object. - * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. - */ - addObject(object, rules) { - this.objects.set(object, rules); - } - /** - * Removes an object from the set of objects that should be validated when validate is called. - * @param object The object. - */ - removeObject(object) { - this.objects.delete(object); - this.processResultDelta('reset', this.results.filter(result => result.object === object), []); - } - /** - * Adds and renders an error. - */ - addError(message, object, propertyName = null) { - let resolvedPropertyName; - if (propertyName === null) { - resolvedPropertyName = propertyName; - } - else { - resolvedPropertyName = this.propertyParser.parse(propertyName); - } - const result = new ValidateResult({ __manuallyAdded__: true }, object, resolvedPropertyName, false, message); - this.processResultDelta('validate', [], [result]); - return result; - } - /** - * Removes and unrenders an error. - */ - removeError(result) { - if (this.results.indexOf(result) !== -1) { - this.processResultDelta('reset', [result], []); - } - } - /** - * Adds a renderer. - * @param renderer The renderer. - */ - addRenderer(renderer) { - this.renderers.push(renderer); - renderer.render({ - kind: 'validate', - render: this.results.map(result => ({ result, elements: this.elements.get(result) })), - unrender: [] - }); - } - /** - * Removes a renderer. - * @param renderer The renderer. - */ - removeRenderer(renderer) { - this.renderers.splice(this.renderers.indexOf(renderer), 1); - renderer.render({ - kind: 'reset', - render: [], - unrender: this.results.map(result => ({ result, elements: this.elements.get(result) })) - }); - } - /** - * Registers a binding with the controller. - * @param binding The binding instance. - * @param target The DOM element. - * @param rules (optional) rules associated with the binding. Validator implementation specific. - */ - registerBinding(binding, target, rules) { - this.bindings.set(binding, { target, rules, propertyInfo: null }); - } - /** - * Unregisters a binding with the controller. - * @param binding The binding instance. - */ - unregisterBinding(binding) { - this.resetBinding(binding); - this.bindings.delete(binding); - } - /** - * Interprets the instruction and returns a predicate that will identify - * relevant results in the list of rendered validation results. - */ - getInstructionPredicate(instruction) { - if (instruction) { - const { object, propertyName, rules } = instruction; - let predicate; - if (instruction.propertyName) { - predicate = x => x.object === object && x.propertyName === propertyName; - } - else { - predicate = x => x.object === object; - } - if (rules) { - return x => predicate(x) && this.validator.ruleExists(rules, x.rule); - } - return predicate; - } - else { - return () => true; - } - } - /** - * Validates and renders results. - * @param instruction Optional. Instructions on what to validate. If undefined, all - * objects and bindings will be validated. - */ - validate(instruction) { - // Get a function that will process the validation instruction. - let execute; - if (instruction) { - // tslint:disable-next-line:prefer-const - let { object, propertyName, rules } = instruction; - // if rules were not specified, check the object map. - rules = rules || this.objects.get(object); - // property specified? - if (instruction.propertyName === undefined) { - // validate the specified object. - execute = () => this.validator.validateObject(object, rules); - } - else { - // validate the specified property. - execute = () => this.validator.validateProperty(object, propertyName, rules); - } - } - else { - // validate all objects and bindings. - execute = () => { - const promises = []; - for (const [object, rules] of Array.from(this.objects)) { - promises.push(this.validator.validateObject(object, rules)); - } - for (const [binding, { rules }] of Array.from(this.bindings)) { - const propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); - if (!propertyInfo || this.objects.has(propertyInfo.object)) { - continue; - } - promises.push(this.validator.validateProperty(propertyInfo.object, propertyInfo.propertyName, rules)); - } - return Promise.all(promises).then(resultSets => resultSets.reduce((a, b) => a.concat(b), [])); - }; - } - // Wait for any existing validation to finish, execute the instruction, render the results. - this.validating = true; - const returnPromise = this.finishValidating - .then(execute) - .then((newResults) => { - const predicate = this.getInstructionPredicate(instruction); - const oldResults = this.results.filter(predicate); - this.processResultDelta('validate', oldResults, newResults); - if (returnPromise === this.finishValidating) { - this.validating = false; - } - const result = { - instruction, - valid: newResults.find(x => !x.valid) === undefined, - results: newResults - }; - this.invokeCallbacks(instruction, result); - return result; - }) - .catch(exception => { - // recover, to enable subsequent calls to validate() - this.validating = false; - this.finishValidating = Promise.resolve(); - return Promise.reject(exception); - }); - this.finishValidating = returnPromise; - return returnPromise; - } - /** - * Resets any rendered validation results (unrenders). - * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results - * will be unrendered. - */ - reset(instruction) { - const predicate = this.getInstructionPredicate(instruction); - const oldResults = this.results.filter(predicate); - this.processResultDelta('reset', oldResults, []); - this.invokeCallbacks(instruction, null); - } - /** - * Gets the elements associated with an object and propertyName (if any). - */ - getAssociatedElements({ object, propertyName }) { - const elements = []; - for (const [binding, { target }] of Array.from(this.bindings)) { - const propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); - if (propertyInfo && propertyInfo.object === object && propertyInfo.propertyName === propertyName) { - elements.push(target); - } - } - return elements; - } - processResultDelta(kind, oldResults, newResults) { - // prepare the instruction. - const instruction = { - kind, - render: [], - unrender: [] - }; - // create a shallow copy of newResults so we can mutate it without causing side-effects. - newResults = newResults.slice(0); - // create unrender instructions from the old results. - for (const oldResult of oldResults) { - // get the elements associated with the old result. - const elements = this.elements.get(oldResult); - // remove the old result from the element map. - this.elements.delete(oldResult); - // create the unrender instruction. - instruction.unrender.push({ result: oldResult, elements }); - // determine if there's a corresponding new result for the old result we are unrendering. - const newResultIndex = newResults.findIndex(x => x.rule === oldResult.rule && x.object === oldResult.object && x.propertyName === oldResult.propertyName); - if (newResultIndex === -1) { - // no corresponding new result... simple remove. - this.results.splice(this.results.indexOf(oldResult), 1); - if (!oldResult.valid) { - this.errors.splice(this.errors.indexOf(oldResult), 1); - } - } - else { - // there is a corresponding new result... - const newResult = newResults.splice(newResultIndex, 1)[0]; - // get the elements that are associated with the new result. - const elements = this.getAssociatedElements(newResult); - this.elements.set(newResult, elements); - // create a render instruction for the new result. - instruction.render.push({ result: newResult, elements }); - // do an in-place replacement of the old result with the new result. - // this ensures any repeats bound to this.results will not thrash. - this.results.splice(this.results.indexOf(oldResult), 1, newResult); - if (!oldResult.valid && newResult.valid) { - this.errors.splice(this.errors.indexOf(oldResult), 1); - } - else if (!oldResult.valid && !newResult.valid) { - this.errors.splice(this.errors.indexOf(oldResult), 1, newResult); - } - else if (!newResult.valid) { - this.errors.push(newResult); - } - } - } - // create render instructions from the remaining new results. - for (const result of newResults) { - const elements = this.getAssociatedElements(result); - instruction.render.push({ result, elements }); - this.elements.set(result, elements); - this.results.push(result); - if (!result.valid) { - this.errors.push(result); - } - } - // render. - for (const renderer of this.renderers) { - renderer.render(instruction); - } - } - /** - * Validates the property associated with a binding. - */ - validateBinding(binding) { - if (!binding.isBound) { - return; - } - const propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); - let rules; - const registeredBinding = this.bindings.get(binding); - if (registeredBinding) { - rules = registeredBinding.rules; - registeredBinding.propertyInfo = propertyInfo; - } - if (!propertyInfo) { - return; - } - const { object, propertyName } = propertyInfo; - this.validate({ object, propertyName, rules }); - } - /** - * Resets the results for a property associated with a binding. - */ - resetBinding(binding) { - const registeredBinding = this.bindings.get(binding); - let propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); - if (!propertyInfo && registeredBinding) { - propertyInfo = registeredBinding.propertyInfo; - } - if (registeredBinding) { - registeredBinding.propertyInfo = null; - } - if (!propertyInfo) { - return; - } - const { object, propertyName } = propertyInfo; - this.reset({ object, propertyName }); - } - /** - * Changes the controller's validateTrigger. - * @param newTrigger The new validateTrigger - */ - changeTrigger(newTrigger) { - this.validateTrigger = newTrigger; - const bindings = Array.from(this.bindings.keys()); - for (const binding of bindings) { - const source = binding.source; - binding.unbind(); - binding.bind(source); - } - } - /** - * Revalidates the controller's current set of errors. - */ - revalidateErrors() { - for (const { object, propertyName, rule } of this.errors) { - if (rule.__manuallyAdded__) { - continue; - } - const rules = [[rule]]; - this.validate({ object, propertyName, rules }); - } - } - invokeCallbacks(instruction, result) { - if (this.eventCallbacks.length === 0) { - return; - } - const event = new ValidateEvent(result ? 'validate' : 'reset', this.errors, this.results, instruction || null, result); - for (let i = 0; i < this.eventCallbacks.length; i++) { - this.eventCallbacks[i](event); - } - } -} -ValidationController.inject = [Validator, PropertyAccessorParser]; diff --git a/dist/es2015/validation-errors-custom-attribute.d.ts b/dist/es2015/validation-errors-custom-attribute.d.ts deleted file mode 100644 index 056e08ea..00000000 --- a/dist/es2015/validation-errors-custom-attribute.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Lazy } from 'aurelia-dependency-injection'; -import { ValidationController } from './validation-controller'; -import { ValidateResult } from './validate-result'; -import { ValidationRenderer, RenderInstruction } from './validation-renderer'; -export interface RenderedError { - error: ValidateResult; - targets: Element[]; -} -export declare class ValidationErrorsCustomAttribute implements ValidationRenderer { - private boundaryElement; - private controllerAccessor; - static inject(): ({ - new (): Element; - prototype: Element; - } | Lazy)[]; - controller: ValidationController | null; - errors: RenderedError[]; - private errorsInternal; - constructor(boundaryElement: Element, controllerAccessor: () => ValidationController); - sort(): void; - interestingElements(elements: Element[]): Element[]; - render(instruction: RenderInstruction): void; - bind(): void; - unbind(): void; -} diff --git a/dist/es2015/validation-errors-custom-attribute.js b/dist/es2015/validation-errors-custom-attribute.js deleted file mode 100644 index c6af963f..00000000 --- a/dist/es2015/validation-errors-custom-attribute.js +++ /dev/null @@ -1,74 +0,0 @@ -var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -}; -import { bindingMode } from 'aurelia-binding'; -import { Lazy } from 'aurelia-dependency-injection'; -import { customAttribute, bindable } from 'aurelia-templating'; -import { ValidationController } from './validation-controller'; -import { DOM } from 'aurelia-pal'; -let ValidationErrorsCustomAttribute = class ValidationErrorsCustomAttribute { - constructor(boundaryElement, controllerAccessor) { - this.boundaryElement = boundaryElement; - this.controllerAccessor = controllerAccessor; - this.controller = null; - this.errors = []; - this.errorsInternal = []; - } - static inject() { return [DOM.Element, Lazy.of(ValidationController)]; } - sort() { - this.errorsInternal.sort((a, b) => { - if (a.targets[0] === b.targets[0]) { - return 0; - } - // tslint:disable-next-line:no-bitwise - return a.targets[0].compareDocumentPosition(b.targets[0]) & 2 ? 1 : -1; - }); - } - interestingElements(elements) { - return elements.filter(e => this.boundaryElement.contains(e)); - } - render(instruction) { - for (const { result } of instruction.unrender) { - const index = this.errorsInternal.findIndex(x => x.error === result); - if (index !== -1) { - this.errorsInternal.splice(index, 1); - } - } - for (const { result, elements } of instruction.render) { - if (result.valid) { - continue; - } - const targets = this.interestingElements(elements); - if (targets.length) { - this.errorsInternal.push({ error: result, targets }); - } - } - this.sort(); - this.errors = this.errorsInternal; - } - bind() { - if (!this.controller) { - this.controller = this.controllerAccessor(); - } - // this will call render() with the side-effect of updating this.errors - this.controller.addRenderer(this); - } - unbind() { - if (this.controller) { - this.controller.removeRenderer(this); - } - } -}; -__decorate([ - bindable({ defaultBindingMode: bindingMode.oneWay }) -], ValidationErrorsCustomAttribute.prototype, "controller", void 0); -__decorate([ - bindable({ primaryProperty: true, defaultBindingMode: bindingMode.twoWay }) -], ValidationErrorsCustomAttribute.prototype, "errors", void 0); -ValidationErrorsCustomAttribute = __decorate([ - customAttribute('validation-errors') -], ValidationErrorsCustomAttribute); -export { ValidationErrorsCustomAttribute }; diff --git a/dist/es2015/validation-renderer-custom-attribute.d.ts b/dist/es2015/validation-renderer-custom-attribute.d.ts deleted file mode 100644 index 9f48614e..00000000 --- a/dist/es2015/validation-renderer-custom-attribute.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export declare class ValidationRendererCustomAttribute { - private container; - private controller; - private value; - private renderer; - created(view: any): void; - bind(): void; - unbind(): void; -} diff --git a/dist/es2015/validation-renderer-custom-attribute.js b/dist/es2015/validation-renderer-custom-attribute.js deleted file mode 100644 index 83b6c5d4..00000000 --- a/dist/es2015/validation-renderer-custom-attribute.js +++ /dev/null @@ -1,16 +0,0 @@ -import { ValidationController } from './validation-controller'; -export class ValidationRendererCustomAttribute { - created(view) { - this.container = view.container; - } - bind() { - this.controller = this.container.get(ValidationController); - this.renderer = this.container.get(this.value); - this.controller.addRenderer(this.renderer); - } - unbind() { - this.controller.removeRenderer(this.renderer); - this.controller = null; - this.renderer = null; - } -} diff --git a/dist/es2015/validation-renderer.js b/dist/es2015/validation-renderer.js deleted file mode 100644 index e69de29b..00000000 diff --git a/dist/es2015/validator.js b/dist/es2015/validator.js deleted file mode 100644 index 2fd07a54..00000000 --- a/dist/es2015/validator.js +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Validates objects and properties. - */ -export class Validator { -} diff --git a/dist/es2017/aurelia-validation.d.ts b/dist/es2017/aurelia-validation.d.ts deleted file mode 100644 index d744ccfb..00000000 --- a/dist/es2017/aurelia-validation.d.ts +++ /dev/null @@ -1,46 +0,0 @@ -export * from './controller-validate-result'; -export * from './get-target-dom-element'; -export * from './property-info'; -export * from './property-accessor-parser'; -export * from './validate-binding-behavior'; -export * from './validate-event'; -export * from './validate-instruction'; -export * from './validate-result'; -export * from './validate-trigger'; -export * from './validation-controller'; -export * from './validation-controller-factory'; -export * from './validation-errors-custom-attribute'; -export * from './validation-renderer-custom-attribute'; -export * from './validation-renderer'; -export * from './validator'; -export * from './implementation/rule'; -export * from './implementation/rules'; -export * from './implementation/standard-validator'; -export * from './implementation/validation-messages'; -export * from './implementation/validation-message-parser'; -export * from './implementation/validation-rules'; -import { Container } from 'aurelia-dependency-injection'; -import { Validator } from './validator'; -/** - * Aurelia Validation Configuration API - */ -export declare class AureliaValidationConfiguration { - private validatorType; - /** - * Use a custom Validator implementation. - */ - customValidator(type: { - new (...args: any[]): Validator; - }): void; - /** - * Applies the configuration. - */ - apply(container: Container): void; -} -/** - * Configures the plugin. - */ -export declare function configure(frameworkConfig: { - container: Container; - globalResources?: (...resources: string[]) => any; -}, callback?: (config: AureliaValidationConfiguration) => void): void; diff --git a/dist/es2017/aurelia-validation.js b/dist/es2017/aurelia-validation.js index 63cb313e..9b95847a 100644 --- a/dist/es2017/aurelia-validation.js +++ b/dist/es2017/aurelia-validation.js @@ -1,66 +1,1647 @@ -// Exports -export * from './get-target-dom-element'; -export * from './property-info'; -export * from './property-accessor-parser'; -export * from './validate-binding-behavior'; -export * from './validate-event'; -export * from './validate-result'; -export * from './validate-trigger'; -export * from './validation-controller'; -export * from './validation-controller-factory'; -export * from './validation-errors-custom-attribute'; -export * from './validation-renderer-custom-attribute'; -export * from './validator'; -export * from './implementation/rules'; -export * from './implementation/standard-validator'; -export * from './implementation/validation-messages'; -export * from './implementation/validation-message-parser'; -export * from './implementation/validation-rules'; -// Configuration -import { PLATFORM } from 'aurelia-pal'; -import { Validator } from './validator'; -import { StandardValidator } from './implementation/standard-validator'; -import { ValidationMessageParser } from './implementation/validation-message-parser'; -import { PropertyAccessorParser } from './property-accessor-parser'; -import { ValidationRules } from './implementation/validation-rules'; -/** - * Aurelia Validation Configuration API - */ -export class AureliaValidationConfiguration { - constructor() { - this.validatorType = StandardValidator; - } - /** - * Use a custom Validator implementation. - */ - customValidator(type) { - this.validatorType = type; - } - /** - * Applies the configuration. - */ - apply(container) { - const validator = container.get(this.validatorType); - container.registerInstance(Validator, validator); - } +import { DOM } from 'aurelia-pal'; +import { AccessMember, AccessScope, AccessKeyed, BindingBehavior, ValueConverter, getContextFor, Parser, bindingMode, LiteralString, Binary, Conditional, LiteralPrimitive, CallMember } from 'aurelia-binding'; +import { Optional, Lazy } from 'aurelia-dependency-injection'; +import { TaskQueue } from 'aurelia-task-queue'; +import { customAttribute, bindable, BindingLanguage, ViewResources } from 'aurelia-templating'; +import { customAttribute as customAttribute$1 } from 'aurelia-framework'; +import { getLogger } from 'aurelia-logging'; + +/** + * Gets the DOM element associated with the data-binding. Most of the time it's + * the binding.target but sometimes binding.target is an aurelia custom element, + * or custom attribute which is a javascript "class" instance, so we need to use + * the controller's container to retrieve the actual DOM element. + */ +function getTargetDOMElement(binding, view) { + const target = binding.target; + // DOM element + if (target instanceof Element) { + return target; + } + // custom element or custom attribute + // tslint:disable-next-line:prefer-const + for (let i = 0, ii = view.controllers.length; i < ii; i++) { + const controller = view.controllers[i]; + if (controller.viewModel === target) { + const element = controller.container.get(DOM.Element); + if (element) { + return element; + } + throw new Error(`Unable to locate target element for "${binding.sourceExpression}".`); + } + } + throw new Error(`Unable to locate target element for "${binding.sourceExpression}".`); } -/** - * Configures the plugin. - */ -export function configure(frameworkConfig, callback) { - // the fluent rule definition API needs the parser to translate messages - // to interpolation expressions. - const messageParser = frameworkConfig.container.get(ValidationMessageParser); - const propertyParser = frameworkConfig.container.get(PropertyAccessorParser); - ValidationRules.initialize(messageParser, propertyParser); - // configure... - const config = new AureliaValidationConfiguration(); - if (callback instanceof Function) { - callback(config); - } - config.apply(frameworkConfig.container); - // globalize the behaviors. - if (frameworkConfig.globalResources) { - frameworkConfig.globalResources(PLATFORM.moduleName('./validate-binding-behavior'), PLATFORM.moduleName('./validation-errors-custom-attribute'), PLATFORM.moduleName('./validation-renderer-custom-attribute')); - } + +function getObject(expression, objectExpression, source) { + const value = objectExpression.evaluate(source, null); + if (value === null || value === undefined || value instanceof Object) { + return value; + } + // tslint:disable-next-line:max-line-length + throw new Error(`The '${objectExpression}' part of '${expression}' evaluates to ${value} instead of an object, null or undefined.`); +} +/** + * Retrieves the object and property name for the specified expression. + * @param expression The expression + * @param source The scope + */ +function getPropertyInfo(expression, source) { + const originalExpression = expression; + while (expression instanceof BindingBehavior || expression instanceof ValueConverter) { + expression = expression.expression; + } + let object; + let propertyName; + if (expression instanceof AccessScope) { + object = getContextFor(expression.name, source, expression.ancestor); + propertyName = expression.name; + } + else if (expression instanceof AccessMember) { + object = getObject(originalExpression, expression.object, source); + propertyName = expression.name; + } + else if (expression instanceof AccessKeyed) { + object = getObject(originalExpression, expression.object, source); + propertyName = expression.key.evaluate(source); + } + else { + throw new Error(`Expression '${originalExpression}' is not compatible with the validate binding-behavior.`); + } + if (object === null || object === undefined) { + return null; + } + return { object, propertyName }; } + +function isString(value) { + return Object.prototype.toString.call(value) === '[object String]'; +} +function isNumber(value) { + return Object.prototype.toString.call(value) === '[object Number]'; +} + +class PropertyAccessorParser { + constructor(parser) { + this.parser = parser; + } + parse(property) { + if (isString(property) || isNumber(property)) { + return property; + } + const accessorText = getAccessorExpression(property.toString()); + const accessor = this.parser.parse(accessorText); + if (accessor instanceof AccessScope + || accessor instanceof AccessMember && accessor.object instanceof AccessScope) { + return accessor.name; + } + throw new Error(`Invalid property expression: "${accessor}"`); + } +} +PropertyAccessorParser.inject = [Parser]; +function getAccessorExpression(fn) { + /* tslint:disable:max-line-length */ + const classic = /^function\s*\([$_\w\d]+\)\s*\{(?:\s*"use strict";)?\s*(?:[$_\w\d.['"\]+;]+)?\s*return\s+[$_\w\d]+\.([$_\w\d]+)\s*;?\s*\}$/; + /* tslint:enable:max-line-length */ + const arrow = /^\(?[$_\w\d]+\)?\s*=>\s*[$_\w\d]+\.([$_\w\d]+)$/; + const match = classic.exec(fn) || arrow.exec(fn); + if (match === null) { + throw new Error(`Unable to parse accessor function:\n${fn}`); + } + return match[1]; +} + +/** + * Validation triggers. + */ +var validateTrigger; +(function (validateTrigger) { + /** + * Manual validation. Use the controller's `validate()` and `reset()` methods + * to validate all bindings. + */ + validateTrigger[validateTrigger["manual"] = 0] = "manual"; + /** + * Validate the binding when the binding's target element fires a DOM "blur" event. + */ + validateTrigger[validateTrigger["blur"] = 1] = "blur"; + /** + * Validate the binding when it updates the model due to a change in the view. + */ + validateTrigger[validateTrigger["change"] = 2] = "change"; + /** + * Validate the binding when the binding's target element fires a DOM "blur" event and + * when it updates the model due to a change in the view. + */ + validateTrigger[validateTrigger["changeOrBlur"] = 3] = "changeOrBlur"; +})(validateTrigger || (validateTrigger = {})); + +/** + * Validates objects and properties. + */ +class Validator { +} + +/** + * The result of validating an individual validation rule. + */ +class ValidateResult { + /** + * @param rule The rule associated with the result. Validator implementation specific. + * @param object The object that was validated. + * @param propertyName The name of the property that was validated. + * @param error The error, if the result is a validation error. + */ + constructor(rule, object, propertyName, valid, message = null) { + this.rule = rule; + this.object = object; + this.propertyName = propertyName; + this.valid = valid; + this.message = message; + this.id = ValidateResult.nextId++; + } + toString() { + return this.valid ? 'Valid.' : this.message; + } +} +ValidateResult.nextId = 0; + +class ValidateEvent { + constructor( + /** + * The type of validate event. Either "validate" or "reset". + */ + type, + /** + * The controller's current array of errors. For an array containing both + * failed rules and passed rules, use the "results" property. + */ + errors, + /** + * The controller's current array of validate results. This + * includes both passed rules and failed rules. For an array of only failed rules, + * use the "errors" property. + */ + results, + /** + * The instruction passed to the "validate" or "reset" event. Will be null when + * the controller's validate/reset method was called with no instruction argument. + */ + instruction, + /** + * In events with type === "validate", this property will contain the result + * of validating the instruction (see "instruction" property). Use the controllerValidateResult + * to access the validate results specific to the call to "validate" + * (as opposed to using the "results" and "errors" properties to access the controller's entire + * set of results/errors). + */ + controllerValidateResult) { + this.type = type; + this.errors = errors; + this.results = results; + this.instruction = instruction; + this.controllerValidateResult = controllerValidateResult; + } +} + +/** + * Orchestrates validation. + * Manages a set of bindings, renderers and objects. + * Exposes the current list of validation results for binding purposes. + */ +class ValidationController { + constructor(validator, propertyParser) { + this.validator = validator; + this.propertyParser = propertyParser; + // Registered bindings (via the validate binding behavior) + this.bindings = new Map(); + // Renderers that have been added to the controller instance. + this.renderers = []; + /** + * Validation results that have been rendered by the controller. + */ + this.results = []; + /** + * Validation errors that have been rendered by the controller. + */ + this.errors = []; + /** + * Whether the controller is currently validating. + */ + this.validating = false; + // Elements related to validation results that have been rendered. + this.elements = new Map(); + // Objects that have been added to the controller instance (entity-style validation). + this.objects = new Map(); + /** + * The trigger that will invoke automatic validation of a property used in a binding. + */ + this.validateTrigger = validateTrigger.blur; + // Promise that resolves when validation has completed. + this.finishValidating = Promise.resolve(); + this.eventCallbacks = []; + } + /** + * Subscribe to controller validate and reset events. These events occur when the + * controller's "validate"" and "reset" methods are called. + * @param callback The callback to be invoked when the controller validates or resets. + */ + subscribe(callback) { + this.eventCallbacks.push(callback); + return { + dispose: () => { + const index = this.eventCallbacks.indexOf(callback); + if (index === -1) { + return; + } + this.eventCallbacks.splice(index, 1); + } + }; + } + /** + * Adds an object to the set of objects that should be validated when validate is called. + * @param object The object. + * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. + */ + addObject(object, rules) { + this.objects.set(object, rules); + } + /** + * Removes an object from the set of objects that should be validated when validate is called. + * @param object The object. + */ + removeObject(object) { + this.objects.delete(object); + this.processResultDelta('reset', this.results.filter(result => result.object === object), []); + } + /** + * Adds and renders an error. + */ + addError(message, object, propertyName = null) { + let resolvedPropertyName; + if (propertyName === null) { + resolvedPropertyName = propertyName; + } + else { + resolvedPropertyName = this.propertyParser.parse(propertyName); + } + const result = new ValidateResult({ __manuallyAdded__: true }, object, resolvedPropertyName, false, message); + this.processResultDelta('validate', [], [result]); + return result; + } + /** + * Removes and unrenders an error. + */ + removeError(result) { + if (this.results.indexOf(result) !== -1) { + this.processResultDelta('reset', [result], []); + } + } + /** + * Adds a renderer. + * @param renderer The renderer. + */ + addRenderer(renderer) { + this.renderers.push(renderer); + renderer.render({ + kind: 'validate', + render: this.results.map(result => ({ result, elements: this.elements.get(result) })), + unrender: [] + }); + } + /** + * Removes a renderer. + * @param renderer The renderer. + */ + removeRenderer(renderer) { + this.renderers.splice(this.renderers.indexOf(renderer), 1); + renderer.render({ + kind: 'reset', + render: [], + unrender: this.results.map(result => ({ result, elements: this.elements.get(result) })) + }); + } + /** + * Registers a binding with the controller. + * @param binding The binding instance. + * @param target The DOM element. + * @param rules (optional) rules associated with the binding. Validator implementation specific. + */ + registerBinding(binding, target, rules) { + this.bindings.set(binding, { target, rules, propertyInfo: null }); + } + /** + * Unregisters a binding with the controller. + * @param binding The binding instance. + */ + unregisterBinding(binding) { + this.resetBinding(binding); + this.bindings.delete(binding); + } + /** + * Interprets the instruction and returns a predicate that will identify + * relevant results in the list of rendered validation results. + */ + getInstructionPredicate(instruction) { + if (instruction) { + const { object, propertyName, rules } = instruction; + let predicate; + if (instruction.propertyName) { + predicate = x => x.object === object && x.propertyName === propertyName; + } + else { + predicate = x => x.object === object; + } + if (rules) { + return x => predicate(x) && this.validator.ruleExists(rules, x.rule); + } + return predicate; + } + else { + return () => true; + } + } + /** + * Validates and renders results. + * @param instruction Optional. Instructions on what to validate. If undefined, all + * objects and bindings will be validated. + */ + validate(instruction) { + // Get a function that will process the validation instruction. + let execute; + if (instruction) { + // tslint:disable-next-line:prefer-const + let { object, propertyName, rules } = instruction; + // if rules were not specified, check the object map. + rules = rules || this.objects.get(object); + // property specified? + if (instruction.propertyName === undefined) { + // validate the specified object. + execute = () => this.validator.validateObject(object, rules); + } + else { + // validate the specified property. + execute = () => this.validator.validateProperty(object, propertyName, rules); + } + } + else { + // validate all objects and bindings. + execute = () => { + const promises = []; + for (const [object, rules] of Array.from(this.objects)) { + promises.push(this.validator.validateObject(object, rules)); + } + for (const [binding, { rules }] of Array.from(this.bindings)) { + const propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + if (!propertyInfo || this.objects.has(propertyInfo.object)) { + continue; + } + promises.push(this.validator.validateProperty(propertyInfo.object, propertyInfo.propertyName, rules)); + } + return Promise.all(promises).then(resultSets => resultSets.reduce((a, b) => a.concat(b), [])); + }; + } + // Wait for any existing validation to finish, execute the instruction, render the results. + this.validating = true; + const returnPromise = this.finishValidating + .then(execute) + .then((newResults) => { + const predicate = this.getInstructionPredicate(instruction); + const oldResults = this.results.filter(predicate); + this.processResultDelta('validate', oldResults, newResults); + if (returnPromise === this.finishValidating) { + this.validating = false; + } + const result = { + instruction, + valid: newResults.find(x => !x.valid) === undefined, + results: newResults + }; + this.invokeCallbacks(instruction, result); + return result; + }) + .catch(exception => { + // recover, to enable subsequent calls to validate() + this.validating = false; + this.finishValidating = Promise.resolve(); + return Promise.reject(exception); + }); + this.finishValidating = returnPromise; + return returnPromise; + } + /** + * Resets any rendered validation results (unrenders). + * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results + * will be unrendered. + */ + reset(instruction) { + const predicate = this.getInstructionPredicate(instruction); + const oldResults = this.results.filter(predicate); + this.processResultDelta('reset', oldResults, []); + this.invokeCallbacks(instruction, null); + } + /** + * Gets the elements associated with an object and propertyName (if any). + */ + getAssociatedElements({ object, propertyName }) { + const elements = []; + for (const [binding, { target }] of Array.from(this.bindings)) { + const propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + if (propertyInfo && propertyInfo.object === object && propertyInfo.propertyName === propertyName) { + elements.push(target); + } + } + return elements; + } + processResultDelta(kind, oldResults, newResults) { + // prepare the instruction. + const instruction = { + kind, + render: [], + unrender: [] + }; + // create a shallow copy of newResults so we can mutate it without causing side-effects. + newResults = newResults.slice(0); + // create unrender instructions from the old results. + for (const oldResult of oldResults) { + // get the elements associated with the old result. + const elements = this.elements.get(oldResult); + // remove the old result from the element map. + this.elements.delete(oldResult); + // create the unrender instruction. + instruction.unrender.push({ result: oldResult, elements }); + // determine if there's a corresponding new result for the old result we are unrendering. + const newResultIndex = newResults.findIndex(x => x.rule === oldResult.rule && x.object === oldResult.object && x.propertyName === oldResult.propertyName); + if (newResultIndex === -1) { + // no corresponding new result... simple remove. + this.results.splice(this.results.indexOf(oldResult), 1); + if (!oldResult.valid) { + this.errors.splice(this.errors.indexOf(oldResult), 1); + } + } + else { + // there is a corresponding new result... + const newResult = newResults.splice(newResultIndex, 1)[0]; + // get the elements that are associated with the new result. + const elements = this.getAssociatedElements(newResult); + this.elements.set(newResult, elements); + // create a render instruction for the new result. + instruction.render.push({ result: newResult, elements }); + // do an in-place replacement of the old result with the new result. + // this ensures any repeats bound to this.results will not thrash. + this.results.splice(this.results.indexOf(oldResult), 1, newResult); + if (!oldResult.valid && newResult.valid) { + this.errors.splice(this.errors.indexOf(oldResult), 1); + } + else if (!oldResult.valid && !newResult.valid) { + this.errors.splice(this.errors.indexOf(oldResult), 1, newResult); + } + else if (!newResult.valid) { + this.errors.push(newResult); + } + } + } + // create render instructions from the remaining new results. + for (const result of newResults) { + const elements = this.getAssociatedElements(result); + instruction.render.push({ result, elements }); + this.elements.set(result, elements); + this.results.push(result); + if (!result.valid) { + this.errors.push(result); + } + } + // render. + for (const renderer of this.renderers) { + renderer.render(instruction); + } + } + /** + * Validates the property associated with a binding. + */ + validateBinding(binding) { + if (!binding.isBound) { + return; + } + const propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + let rules; + const registeredBinding = this.bindings.get(binding); + if (registeredBinding) { + rules = registeredBinding.rules; + registeredBinding.propertyInfo = propertyInfo; + } + if (!propertyInfo) { + return; + } + const { object, propertyName } = propertyInfo; + this.validate({ object, propertyName, rules }); + } + /** + * Resets the results for a property associated with a binding. + */ + resetBinding(binding) { + const registeredBinding = this.bindings.get(binding); + let propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + if (!propertyInfo && registeredBinding) { + propertyInfo = registeredBinding.propertyInfo; + } + if (registeredBinding) { + registeredBinding.propertyInfo = null; + } + if (!propertyInfo) { + return; + } + const { object, propertyName } = propertyInfo; + this.reset({ object, propertyName }); + } + /** + * Changes the controller's validateTrigger. + * @param newTrigger The new validateTrigger + */ + changeTrigger(newTrigger) { + this.validateTrigger = newTrigger; + const bindings = Array.from(this.bindings.keys()); + for (const binding of bindings) { + const source = binding.source; + binding.unbind(); + binding.bind(source); + } + } + /** + * Revalidates the controller's current set of errors. + */ + revalidateErrors() { + for (const { object, propertyName, rule } of this.errors) { + if (rule.__manuallyAdded__) { + continue; + } + const rules = [[rule]]; + this.validate({ object, propertyName, rules }); + } + } + invokeCallbacks(instruction, result) { + if (this.eventCallbacks.length === 0) { + return; + } + const event = new ValidateEvent(result ? 'validate' : 'reset', this.errors, this.results, instruction || null, result); + for (let i = 0; i < this.eventCallbacks.length; i++) { + this.eventCallbacks[i](event); + } + } +} +ValidationController.inject = [Validator, PropertyAccessorParser]; + +/** + * Binding behavior. Indicates the bound property should be validated. + */ +class ValidateBindingBehaviorBase { + constructor(taskQueue) { + this.taskQueue = taskQueue; + } + bind(binding, source, rulesOrController, rules) { + // identify the target element. + const target = getTargetDOMElement(binding, source); + // locate the controller. + let controller; + if (rulesOrController instanceof ValidationController) { + controller = rulesOrController; + } + else { + controller = source.container.get(Optional.of(ValidationController)); + rules = rulesOrController; + } + if (controller === null) { + throw new Error(`A ValidationController has not been registered.`); + } + controller.registerBinding(binding, target, rules); + binding.validationController = controller; + const trigger = this.getValidateTrigger(controller); + // tslint:disable-next-line:no-bitwise + if (trigger & validateTrigger.change) { + binding.vbbUpdateSource = binding.updateSource; + // tslint:disable-next-line:only-arrow-functions + // tslint:disable-next-line:space-before-function-paren + binding.updateSource = function (value) { + this.vbbUpdateSource(value); + this.validationController.validateBinding(this); + }; + } + // tslint:disable-next-line:no-bitwise + if (trigger & validateTrigger.blur) { + binding.validateBlurHandler = () => { + this.taskQueue.queueMicroTask(() => controller.validateBinding(binding)); + }; + binding.validateTarget = target; + target.addEventListener('blur', binding.validateBlurHandler); + } + if (trigger !== validateTrigger.manual) { + binding.standardUpdateTarget = binding.updateTarget; + // tslint:disable-next-line:only-arrow-functions + // tslint:disable-next-line:space-before-function-paren + binding.updateTarget = function (value) { + this.standardUpdateTarget(value); + this.validationController.resetBinding(this); + }; + } + } + unbind(binding) { + // reset the binding to it's original state. + if (binding.vbbUpdateSource) { + binding.updateSource = binding.vbbUpdateSource; + binding.vbbUpdateSource = null; + } + if (binding.standardUpdateTarget) { + binding.updateTarget = binding.standardUpdateTarget; + binding.standardUpdateTarget = null; + } + if (binding.validateBlurHandler) { + binding.validateTarget.removeEventListener('blur', binding.validateBlurHandler); + binding.validateBlurHandler = null; + binding.validateTarget = null; + } + binding.validationController.unregisterBinding(binding); + binding.validationController = null; + } +} + +/** + * Binding behavior. Indicates the bound property should be validated + * when the validate trigger specified by the associated controller's + * validateTrigger property occurs. + */ +class ValidateBindingBehavior extends ValidateBindingBehaviorBase { + getValidateTrigger(controller) { + return controller.validateTrigger; + } +} +ValidateBindingBehavior.inject = [TaskQueue]; +/** + * Binding behavior. Indicates the bound property will be validated + * manually, by calling controller.validate(). No automatic validation + * triggered by data-entry or blur will occur. + */ +class ValidateManuallyBindingBehavior extends ValidateBindingBehaviorBase { + getValidateTrigger() { + return validateTrigger.manual; + } +} +ValidateManuallyBindingBehavior.inject = [TaskQueue]; +/** + * Binding behavior. Indicates the bound property should be validated + * when the associated element blurs. + */ +class ValidateOnBlurBindingBehavior extends ValidateBindingBehaviorBase { + getValidateTrigger() { + return validateTrigger.blur; + } +} +ValidateOnBlurBindingBehavior.inject = [TaskQueue]; +/** + * Binding behavior. Indicates the bound property should be validated + * when the associated element is changed by the user, causing a change + * to the model. + */ +class ValidateOnChangeBindingBehavior extends ValidateBindingBehaviorBase { + getValidateTrigger() { + return validateTrigger.change; + } +} +ValidateOnChangeBindingBehavior.inject = [TaskQueue]; +/** + * Binding behavior. Indicates the bound property should be validated + * when the associated element blurs or is changed by the user, causing + * a change to the model. + */ +class ValidateOnChangeOrBlurBindingBehavior extends ValidateBindingBehaviorBase { + getValidateTrigger() { + return validateTrigger.changeOrBlur; + } +} +ValidateOnChangeOrBlurBindingBehavior.inject = [TaskQueue]; + +/** + * Creates ValidationController instances. + */ +class ValidationControllerFactory { + constructor(container) { + this.container = container; + } + static get(container) { + return new ValidationControllerFactory(container); + } + /** + * Creates a new controller instance. + */ + create(validator) { + if (!validator) { + validator = this.container.get(Validator); + } + const propertyParser = this.container.get(PropertyAccessorParser); + return new ValidationController(validator, propertyParser); + } + /** + * Creates a new controller and registers it in the current element's container so that it's + * available to the validate binding behavior and renderers. + */ + createForCurrentScope(validator) { + const controller = this.create(validator); + this.container.registerInstance(ValidationController, controller); + return controller; + } +} +ValidationControllerFactory['protocol:aurelia:resolver'] = true; + +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at http://www.apache.org/licenses/LICENSE-2.0 + +THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED +WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +MERCHANTABLITY OR NON-INFRINGEMENT. + +See the Apache Version 2.0 License for specific language governing permissions +and limitations under the License. +***************************************************************************** */ + +function __decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +} + +let ValidationErrorsCustomAttribute = class ValidationErrorsCustomAttribute { + constructor(boundaryElement, controllerAccessor) { + this.boundaryElement = boundaryElement; + this.controllerAccessor = controllerAccessor; + this.controller = null; + this.errors = []; + this.errorsInternal = []; + } + static inject() { + return [DOM.Element, Lazy.of(ValidationController)]; + } + sort() { + this.errorsInternal.sort((a, b) => { + if (a.targets[0] === b.targets[0]) { + return 0; + } + // tslint:disable-next-line:no-bitwise + return a.targets[0].compareDocumentPosition(b.targets[0]) & 2 ? 1 : -1; + }); + } + interestingElements(elements) { + return elements.filter(e => this.boundaryElement.contains(e)); + } + render(instruction) { + for (const { result } of instruction.unrender) { + const index = this.errorsInternal.findIndex(x => x.error === result); + if (index !== -1) { + this.errorsInternal.splice(index, 1); + } + } + for (const { result, elements } of instruction.render) { + if (result.valid) { + continue; + } + const targets = this.interestingElements(elements); + if (targets.length) { + this.errorsInternal.push({ error: result, targets }); + } + } + this.sort(); + this.errors = this.errorsInternal; + } + bind() { + if (!this.controller) { + this.controller = this.controllerAccessor(); + } + // this will call render() with the side-effect of updating this.errors + this.controller.addRenderer(this); + } + unbind() { + if (this.controller) { + this.controller.removeRenderer(this); + } + } +}; +__decorate([ + bindable({ defaultBindingMode: bindingMode.oneWay }) +], ValidationErrorsCustomAttribute.prototype, "controller", void 0); +__decorate([ + bindable({ primaryProperty: true, defaultBindingMode: bindingMode.twoWay }) +], ValidationErrorsCustomAttribute.prototype, "errors", void 0); +ValidationErrorsCustomAttribute = __decorate([ + customAttribute('validation-errors') +], ValidationErrorsCustomAttribute); + +let ValidationRendererCustomAttribute = class ValidationRendererCustomAttribute { + created(view) { + this.container = view.container; + } + bind() { + this.controller = this.container.get(ValidationController); + this.renderer = this.container.get(this.value); + this.controller.addRenderer(this.renderer); + } + unbind() { + this.controller.removeRenderer(this.renderer); + this.controller = null; + this.renderer = null; + } +}; +ValidationRendererCustomAttribute = __decorate([ + customAttribute$1('validation-renderer') +], ValidationRendererCustomAttribute); + +/** + * Sets, unsets and retrieves rules on an object or constructor function. + */ +class Rules { + /** + * Applies the rules to a target. + */ + static set(target, rules) { + if (target instanceof Function) { + target = target.prototype; + } + Object.defineProperty(target, Rules.key, { enumerable: false, configurable: false, writable: true, value: rules }); + } + /** + * Removes rules from a target. + */ + static unset(target) { + if (target instanceof Function) { + target = target.prototype; + } + target[Rules.key] = null; + } + /** + * Retrieves the target's rules. + */ + static get(target) { + return target[Rules.key] || null; + } +} +/** + * The name of the property that stores the rules. + */ +Rules.key = '__rules__'; + +// tslint:disable:no-empty +class ExpressionVisitor { + visitChain(chain) { + this.visitArgs(chain.expressions); + } + visitBindingBehavior(behavior) { + behavior.expression.accept(this); + this.visitArgs(behavior.args); + } + visitValueConverter(converter) { + converter.expression.accept(this); + this.visitArgs(converter.args); + } + visitAssign(assign) { + assign.target.accept(this); + assign.value.accept(this); + } + visitConditional(conditional) { + conditional.condition.accept(this); + conditional.yes.accept(this); + conditional.no.accept(this); + } + visitAccessThis(access) { + access.ancestor = access.ancestor; + } + visitAccessScope(access) { + access.name = access.name; + } + visitAccessMember(access) { + access.object.accept(this); + } + visitAccessKeyed(access) { + access.object.accept(this); + access.key.accept(this); + } + visitCallScope(call) { + this.visitArgs(call.args); + } + visitCallFunction(call) { + call.func.accept(this); + this.visitArgs(call.args); + } + visitCallMember(call) { + call.object.accept(this); + this.visitArgs(call.args); + } + visitPrefix(prefix) { + prefix.expression.accept(this); + } + visitBinary(binary) { + binary.left.accept(this); + binary.right.accept(this); + } + visitLiteralPrimitive(literal) { + literal.value = literal.value; + } + visitLiteralArray(literal) { + this.visitArgs(literal.elements); + } + visitLiteralObject(literal) { + this.visitArgs(literal.values); + } + visitLiteralString(literal) { + literal.value = literal.value; + } + visitArgs(args) { + for (let i = 0; i < args.length; i++) { + args[i].accept(this); + } + } +} + +class ValidationMessageParser { + constructor(bindinqLanguage) { + this.bindinqLanguage = bindinqLanguage; + this.emptyStringExpression = new LiteralString(''); + this.nullExpression = new LiteralPrimitive(null); + this.undefinedExpression = new LiteralPrimitive(undefined); + this.cache = {}; + } + parse(message) { + if (this.cache[message] !== undefined) { + return this.cache[message]; + } + const parts = this.bindinqLanguage.parseInterpolation(null, message); + if (parts === null) { + return new LiteralString(message); + } + let expression = new LiteralString(parts[0]); + for (let i = 1; i < parts.length; i += 2) { + expression = new Binary('+', expression, new Binary('+', this.coalesce(parts[i]), new LiteralString(parts[i + 1]))); + } + MessageExpressionValidator.validate(expression, message); + this.cache[message] = expression; + return expression; + } + coalesce(part) { + // part === null || part === undefined ? '' : part + return new Conditional(new Binary('||', new Binary('===', part, this.nullExpression), new Binary('===', part, this.undefinedExpression)), this.emptyStringExpression, new CallMember(part, 'toString', [])); + } +} +ValidationMessageParser.inject = [BindingLanguage]; +class MessageExpressionValidator extends ExpressionVisitor { + constructor(originalMessage) { + super(); + this.originalMessage = originalMessage; + } + static validate(expression, originalMessage) { + const visitor = new MessageExpressionValidator(originalMessage); + expression.accept(visitor); + } + visitAccessScope(access) { + if (access.ancestor !== 0) { + throw new Error('$parent is not permitted in validation message expressions.'); + } + if (['displayName', 'propertyName', 'value', 'object', 'config', 'getDisplayName'].indexOf(access.name) !== -1) { + getLogger('aurelia-validation') + // tslint:disable-next-line:max-line-length + .warn(`Did you mean to use "$${access.name}" instead of "${access.name}" in this validation message template: "${this.originalMessage}"?`); + } + } +} + +/** + * Dictionary of validation messages. [messageKey]: messageExpression + */ +const validationMessages = { + /** + * The default validation message. Used with rules that have no standard message. + */ + default: `\${$displayName} is invalid.`, + required: `\${$displayName} is required.`, + matches: `\${$displayName} is not correctly formatted.`, + email: `\${$displayName} is not a valid email.`, + minLength: `\${$displayName} must be at least \${$config.length} character\${$config.length === 1 ? '' : 's'}.`, + maxLength: `\${$displayName} cannot be longer than \${$config.length} character\${$config.length === 1 ? '' : 's'}.`, + minItems: `\${$displayName} must contain at least \${$config.count} item\${$config.count === 1 ? '' : 's'}.`, + maxItems: `\${$displayName} cannot contain more than \${$config.count} item\${$config.count === 1 ? '' : 's'}.`, + equals: `\${$displayName} must be \${$config.expectedValue}.`, +}; +/** + * Retrieves validation messages and property display names. + */ +class ValidationMessageProvider { + constructor(parser) { + this.parser = parser; + } + /** + * Returns a message binding expression that corresponds to the key. + * @param key The message key. + */ + getMessage(key) { + let message; + if (key in validationMessages) { + message = validationMessages[key]; + } + else { + message = validationMessages['default']; + } + return this.parser.parse(message); + } + /** + * Formulates a property display name using the property name and the configured + * displayName (if provided). + * Override this with your own custom logic. + * @param propertyName The property name. + */ + getDisplayName(propertyName, displayName) { + if (displayName !== null && displayName !== undefined) { + return (displayName instanceof Function) ? displayName() : displayName; + } + // split on upper-case letters. + const words = propertyName.toString().split(/(?=[A-Z])/).join(' '); + // capitalize first letter. + return words.charAt(0).toUpperCase() + words.slice(1); + } +} +ValidationMessageProvider.inject = [ValidationMessageParser]; + +/** + * Validates. + * Responsible for validating objects and properties. + */ +class StandardValidator extends Validator { + constructor(messageProvider, resources) { + super(); + this.messageProvider = messageProvider; + this.lookupFunctions = resources.lookupFunctions; + this.getDisplayName = messageProvider.getDisplayName.bind(messageProvider); + } + /** + * Validates the specified property. + * @param object The object to validate. + * @param propertyName The name of the property to validate. + * @param rules Optional. If unspecified, the rules will be looked up using the metadata + * for the object created by ValidationRules....on(class/object) + */ + validateProperty(object, propertyName, rules) { + return this.validate(object, propertyName, rules || null); + } + /** + * Validates all rules for specified object and it's properties. + * @param object The object to validate. + * @param rules Optional. If unspecified, the rules will be looked up using the metadata + * for the object created by ValidationRules....on(class/object) + */ + validateObject(object, rules) { + return this.validate(object, null, rules || null); + } + /** + * Determines whether a rule exists in a set of rules. + * @param rules The rules to search. + * @parem rule The rule to find. + */ + ruleExists(rules, rule) { + let i = rules.length; + while (i--) { + if (rules[i].indexOf(rule) !== -1) { + return true; + } + } + return false; + } + getMessage(rule, object, value) { + const expression = rule.message || this.messageProvider.getMessage(rule.messageKey); + // tslint:disable-next-line:prefer-const + let { name: propertyName, displayName } = rule.property; + if (propertyName !== null) { + displayName = this.messageProvider.getDisplayName(propertyName, displayName); + } + const overrideContext = { + $displayName: displayName, + $propertyName: propertyName, + $value: value, + $object: object, + $config: rule.config, + // returns the name of a given property, given just the property name (irrespective of the property's displayName) + // split on capital letters, first letter ensured to be capitalized + $getDisplayName: this.getDisplayName + }; + return expression.evaluate({ bindingContext: object, overrideContext }, this.lookupFunctions); + } + validateRuleSequence(object, propertyName, ruleSequence, sequence, results) { + // are we validating all properties or a single property? + const validateAllProperties = propertyName === null || propertyName === undefined; + const rules = ruleSequence[sequence]; + let allValid = true; + // validate each rule. + const promises = []; + for (let i = 0; i < rules.length; i++) { + const rule = rules[i]; + // is the rule related to the property we're validating. + // tslint:disable-next-line:triple-equals | Use loose equality for property keys + if (!validateAllProperties && rule.property.name != propertyName) { + continue; + } + // is this a conditional rule? is the condition met? + if (rule.when && !rule.when(object)) { + continue; + } + // validate. + const value = rule.property.name === null ? object : object[rule.property.name]; + let promiseOrBoolean = rule.condition(value, object); + if (!(promiseOrBoolean instanceof Promise)) { + promiseOrBoolean = Promise.resolve(promiseOrBoolean); + } + promises.push(promiseOrBoolean.then(valid => { + const message = valid ? null : this.getMessage(rule, object, value); + results.push(new ValidateResult(rule, object, rule.property.name, valid, message)); + allValid = allValid && valid; + return valid; + })); + } + return Promise.all(promises) + .then(() => { + sequence++; + if (allValid && sequence < ruleSequence.length) { + return this.validateRuleSequence(object, propertyName, ruleSequence, sequence, results); + } + return results; + }); + } + validate(object, propertyName, rules) { + // rules specified? + if (!rules) { + // no. attempt to locate the rules. + rules = Rules.get(object); + } + // any rules? + if (!rules || rules.length === 0) { + return Promise.resolve([]); + } + return this.validateRuleSequence(object, propertyName, rules, 0, []); + } +} +StandardValidator.inject = [ValidationMessageProvider, ViewResources]; + +/** + * Part of the fluent rule API. Enables customizing property rules. + */ +class FluentRuleCustomizer { + constructor(property, condition, config = {}, fluentEnsure, fluentRules, parsers) { + this.fluentEnsure = fluentEnsure; + this.fluentRules = fluentRules; + this.parsers = parsers; + this.rule = { + property, + condition, + config, + when: null, + messageKey: 'default', + message: null, + sequence: fluentRules.sequence + }; + this.fluentEnsure._addRule(this.rule); + } + /** + * Validate subsequent rules after previously declared rules have + * been validated successfully. Use to postpone validation of costly + * rules until less expensive rules pass validation. + */ + then() { + this.fluentRules.sequence++; + return this; + } + /** + * Specifies the key to use when looking up the rule's validation message. + */ + withMessageKey(key) { + this.rule.messageKey = key; + this.rule.message = null; + return this; + } + /** + * Specifies rule's validation message. + */ + withMessage(message) { + this.rule.messageKey = 'custom'; + this.rule.message = this.parsers.message.parse(message); + return this; + } + /** + * Specifies a condition that must be met before attempting to validate the rule. + * @param condition A function that accepts the object as a parameter and returns true + * or false whether the rule should be evaluated. + */ + when(condition) { + this.rule.when = condition; + return this; + } + /** + * Tags the rule instance, enabling the rule to be found easily + * using ValidationRules.taggedRules(rules, tag) + */ + tag(tag) { + this.rule.tag = tag; + return this; + } + ///// FluentEnsure APIs ///// + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor function. + */ + ensure(subject) { + return this.fluentEnsure.ensure(subject); + } + /** + * Targets an object with validation rules. + */ + ensureObject() { + return this.fluentEnsure.ensureObject(); + } + /** + * Rules that have been defined using the fluent API. + */ + get rules() { + return this.fluentEnsure.rules; + } + /** + * Applies the rules to a class or object, making them discoverable by the StandardValidator. + * @param target A class or object. + */ + on(target) { + return this.fluentEnsure.on(target); + } + ///////// FluentRules APIs ///////// + /** + * Applies an ad-hoc rule function to the ensured property or object. + * @param condition The function to validate the rule. + * Will be called with two arguments, the property value and the object. + * Should return a boolean or a Promise that resolves to a boolean. + */ + satisfies(condition, config) { + return this.fluentRules.satisfies(condition, config); + } + /** + * Applies a rule by name. + * @param name The name of the custom or standard rule. + * @param args The rule's arguments. + */ + satisfiesRule(name, ...args) { + return this.fluentRules.satisfiesRule(name, ...args); + } + /** + * Applies the "required" rule to the property. + * The value cannot be null, undefined or whitespace. + */ + required() { + return this.fluentRules.required(); + } + /** + * Applies the "matches" rule to the property. + * Value must match the specified regular expression. + * null, undefined and empty-string values are considered valid. + */ + matches(regex) { + return this.fluentRules.matches(regex); + } + /** + * Applies the "email" rule to the property. + * null, undefined and empty-string values are considered valid. + */ + email() { + return this.fluentRules.email(); + } + /** + * Applies the "minLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + minLength(length) { + return this.fluentRules.minLength(length); + } + /** + * Applies the "maxLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + maxLength(length) { + return this.fluentRules.maxLength(length); + } + /** + * Applies the "minItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + minItems(count) { + return this.fluentRules.minItems(count); + } + /** + * Applies the "maxItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + maxItems(count) { + return this.fluentRules.maxItems(count); + } + /** + * Applies the "equals" validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + equals(expectedValue) { + return this.fluentRules.equals(expectedValue); + } +} +/** + * Part of the fluent rule API. Enables applying rules to properties and objects. + */ +class FluentRules { + constructor(fluentEnsure, parsers, property) { + this.fluentEnsure = fluentEnsure; + this.parsers = parsers; + this.property = property; + /** + * Current rule sequence number. Used to postpone evaluation of rules until rules + * with lower sequence number have successfully validated. The "then" fluent API method + * manages this property, there's usually no need to set it directly. + */ + this.sequence = 0; + } + /** + * Sets the display name of the ensured property. + */ + displayName(name) { + this.property.displayName = name; + return this; + } + /** + * Applies an ad-hoc rule function to the ensured property or object. + * @param condition The function to validate the rule. + * Will be called with two arguments, the property value and the object. + * Should return a boolean or a Promise that resolves to a boolean. + */ + satisfies(condition, config) { + return new FluentRuleCustomizer(this.property, condition, config, this.fluentEnsure, this, this.parsers); + } + /** + * Applies a rule by name. + * @param name The name of the custom or standard rule. + * @param args The rule's arguments. + */ + satisfiesRule(name, ...args) { + let rule = FluentRules.customRules[name]; + if (!rule) { + // standard rule? + rule = this[name]; + if (rule instanceof Function) { + return rule.call(this, ...args); + } + throw new Error(`Rule with name "${name}" does not exist.`); + } + const config = rule.argsToConfig ? rule.argsToConfig(...args) : undefined; + return this.satisfies((value, obj) => rule.condition.call(this, value, obj, ...args), config) + .withMessageKey(name); + } + /** + * Applies the "required" rule to the property. + * The value cannot be null, undefined or whitespace. + */ + required() { + return this.satisfies(value => value !== null + && value !== undefined + && !(isString(value) && !/\S/.test(value))).withMessageKey('required'); + } + /** + * Applies the "matches" rule to the property. + * Value must match the specified regular expression. + * null, undefined and empty-string values are considered valid. + */ + matches(regex) { + return this.satisfies(value => value === null || value === undefined || value.length === 0 || regex.test(value)) + .withMessageKey('matches'); + } + /** + * Applies the "email" rule to the property. + * null, undefined and empty-string values are considered valid. + */ + email() { + // regex from https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address + /* tslint:disable:max-line-length */ + return this.matches(/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/) + /* tslint:enable:max-line-length */ + .withMessageKey('email'); + } + /** + * Applies the "minLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + minLength(length) { + return this.satisfies((value) => value === null || value === undefined || value.length === 0 || value.length >= length, { length }) + .withMessageKey('minLength'); + } + /** + * Applies the "maxLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + maxLength(length) { + return this.satisfies((value) => value === null || value === undefined || value.length === 0 || value.length <= length, { length }) + .withMessageKey('maxLength'); + } + /** + * Applies the "minItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + minItems(count) { + return this.satisfies((value) => value === null || value === undefined || value.length >= count, { count }) + .withMessageKey('minItems'); + } + /** + * Applies the "maxItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + maxItems(count) { + return this.satisfies((value) => value === null || value === undefined || value.length <= count, { count }) + .withMessageKey('maxItems'); + } + /** + * Applies the "equals" validation rule to the property. + * null and undefined values are considered valid. + */ + equals(expectedValue) { + return this.satisfies(value => value === null || value === undefined || value === '' || value === expectedValue, { expectedValue }) + .withMessageKey('equals'); + } +} +FluentRules.customRules = {}; +/** + * Part of the fluent rule API. Enables targeting properties and objects with rules. + */ +class FluentEnsure { + constructor(parsers) { + this.parsers = parsers; + /** + * Rules that have been defined using the fluent API. + */ + this.rules = []; + } + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor + * function. + */ + ensure(property) { + this.assertInitialized(); + const name = this.parsers.property.parse(property); + const fluentRules = new FluentRules(this, this.parsers, { name, displayName: null }); + return this.mergeRules(fluentRules, name); + } + /** + * Targets an object with validation rules. + */ + ensureObject() { + this.assertInitialized(); + const fluentRules = new FluentRules(this, this.parsers, { name: null, displayName: null }); + return this.mergeRules(fluentRules, null); + } + /** + * Applies the rules to a class or object, making them discoverable by the StandardValidator. + * @param target A class or object. + */ + on(target) { + Rules.set(target, this.rules); + return this; + } + /** + * Adds a rule definition to the sequenced ruleset. + * @internal + */ + _addRule(rule) { + while (this.rules.length < rule.sequence + 1) { + this.rules.push([]); + } + this.rules[rule.sequence].push(rule); + } + assertInitialized() { + if (this.parsers) { + return; + } + throw new Error(`Did you forget to add ".plugin('aurelia-validation')" to your main.js?`); + } + mergeRules(fluentRules, propertyName) { + // tslint:disable-next-line:triple-equals | Use loose equality for property keys + const existingRules = this.rules.find(r => r.length > 0 && r[0].property.name == propertyName); + if (existingRules) { + const rule = existingRules[existingRules.length - 1]; + fluentRules.sequence = rule.sequence; + if (rule.property.displayName !== null) { + fluentRules = fluentRules.displayName(rule.property.displayName); + } + } + return fluentRules; + } +} +/** + * Fluent rule definition API. + */ +class ValidationRules { + static initialize(messageParser, propertyParser) { + this.parsers = { + message: messageParser, + property: propertyParser + }; + } + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor function. + */ + static ensure(property) { + return new FluentEnsure(ValidationRules.parsers).ensure(property); + } + /** + * Targets an object with validation rules. + */ + static ensureObject() { + return new FluentEnsure(ValidationRules.parsers).ensureObject(); + } + /** + * Defines a custom rule. + * @param name The name of the custom rule. Also serves as the message key. + * @param condition The rule function. + * @param message The message expression + * @param argsToConfig A function that maps the rule's arguments to a "config" + * object that can be used when evaluating the message expression. + */ + static customRule(name, condition, message, argsToConfig) { + validationMessages[name] = message; + FluentRules.customRules[name] = { condition, argsToConfig }; + } + /** + * Returns rules with the matching tag. + * @param rules The rules to search. + * @param tag The tag to search for. + */ + static taggedRules(rules, tag) { + return rules.map(x => x.filter(r => r.tag === tag)); + } + /** + * Returns rules that have no tag. + * @param rules The rules to search. + */ + static untaggedRules(rules) { + return rules.map(x => x.filter(r => r.tag === undefined)); + } + /** + * Removes the rules from a class or object. + * @param target A class or object. + */ + static off(target) { + Rules.unset(target); + } +} + +// Exports +/** + * Aurelia Validation Configuration API + */ +class AureliaValidationConfiguration { + constructor() { + this.validatorType = StandardValidator; + } + /** + * Use a custom Validator implementation. + */ + customValidator(type) { + this.validatorType = type; + } + /** + * Applies the configuration. + */ + apply(container) { + const validator = container.get(this.validatorType); + container.registerInstance(Validator, validator); + } +} +/** + * Configures the plugin. + */ +function configure( +// tslint:disable-next-line:ban-types +frameworkConfig, callback) { + // the fluent rule definition API needs the parser to translate messages + // to interpolation expressions. + const messageParser = frameworkConfig.container.get(ValidationMessageParser); + const propertyParser = frameworkConfig.container.get(PropertyAccessorParser); + ValidationRules.initialize(messageParser, propertyParser); + // configure... + const config = new AureliaValidationConfiguration(); + if (callback instanceof Function) { + callback(config); + } + config.apply(frameworkConfig.container); + // globalize the behaviors. + if (frameworkConfig.globalResources) { + frameworkConfig.globalResources(ValidateBindingBehavior, ValidateManuallyBindingBehavior, ValidateOnBlurBindingBehavior, ValidateOnChangeBindingBehavior, ValidateOnChangeOrBlurBindingBehavior, ValidationErrorsCustomAttribute, ValidationRendererCustomAttribute); + } +} + +export { AureliaValidationConfiguration, configure, getTargetDOMElement, getPropertyInfo, PropertyAccessorParser, getAccessorExpression, ValidateBindingBehavior, ValidateManuallyBindingBehavior, ValidateOnBlurBindingBehavior, ValidateOnChangeBindingBehavior, ValidateOnChangeOrBlurBindingBehavior, ValidateEvent, ValidateResult, validateTrigger, ValidationController, ValidationControllerFactory, ValidationErrorsCustomAttribute, ValidationRendererCustomAttribute, Validator, Rules, StandardValidator, validationMessages, ValidationMessageProvider, ValidationMessageParser, MessageExpressionValidator, FluentRuleCustomizer, FluentRules, FluentEnsure, ValidationRules }; diff --git a/dist/es2017/controller-validate-result.d.ts b/dist/es2017/controller-validate-result.d.ts deleted file mode 100644 index 5f814ed0..00000000 --- a/dist/es2017/controller-validate-result.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { ValidateResult } from './validate-result'; -import { ValidateInstruction } from './validate-instruction'; -/** - * The result of a call to the validation controller's validate method. - */ -export interface ControllerValidateResult { - /** - * Whether validation passed. - */ - valid: boolean; - /** - * The validation result of every rule that was evaluated. - */ - results: ValidateResult[]; - /** - * The instruction passed to the controller's validate method. - */ - instruction?: ValidateInstruction; -} diff --git a/dist/es2017/controller-validate-result.js b/dist/es2017/controller-validate-result.js deleted file mode 100644 index e69de29b..00000000 diff --git a/dist/es2017/get-target-dom-element.d.ts b/dist/es2017/get-target-dom-element.d.ts deleted file mode 100644 index 314fc952..00000000 --- a/dist/es2017/get-target-dom-element.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Gets the DOM element associated with the data-binding. Most of the time it's - * the binding.target but sometimes binding.target is an aurelia custom element, - * or custom attribute which is a javascript "class" instance, so we need to use - * the controller's container to retrieve the actual DOM element. - */ -export declare function getTargetDOMElement(binding: any, view: any): Element; diff --git a/dist/es2017/get-target-dom-element.js b/dist/es2017/get-target-dom-element.js deleted file mode 100644 index 2b976f87..00000000 --- a/dist/es2017/get-target-dom-element.js +++ /dev/null @@ -1,27 +0,0 @@ -import { DOM } from 'aurelia-pal'; -/** - * Gets the DOM element associated with the data-binding. Most of the time it's - * the binding.target but sometimes binding.target is an aurelia custom element, - * or custom attribute which is a javascript "class" instance, so we need to use - * the controller's container to retrieve the actual DOM element. - */ -export function getTargetDOMElement(binding, view) { - const target = binding.target; - // DOM element - if (target instanceof Element) { - return target; - } - // custom element or custom attribute - // tslint:disable-next-line:prefer-const - for (let i = 0, ii = view.controllers.length; i < ii; i++) { - const controller = view.controllers[i]; - if (controller.viewModel === target) { - const element = controller.container.get(DOM.Element); - if (element) { - return element; - } - throw new Error(`Unable to locate target element for "${binding.sourceExpression}".`); - } - } - throw new Error(`Unable to locate target element for "${binding.sourceExpression}".`); -} diff --git a/dist/es2017/implementation/expression-visitor.d.ts b/dist/es2017/implementation/expression-visitor.d.ts deleted file mode 100644 index 47769fae..00000000 --- a/dist/es2017/implementation/expression-visitor.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { ValueConverter, Conditional, AccessMember, AccessKeyed, CallMember, BindingBehavior, Binary } from 'aurelia-binding'; -export declare type Chain = any; -export declare type Assign = any; -export declare type AccessThis = any; -export declare type AccessScope = any; -export declare type CallScope = any; -export declare type CallFunction = any; -export declare type PrefixNot = any; -export declare type LiteralPrimitive = any; -export declare type LiteralArray = any; -export declare type LiteralObject = any; -export declare type LiteralString = any; -export declare class ExpressionVisitor { - visitChain(chain: Chain): void; - visitBindingBehavior(behavior: BindingBehavior): void; - visitValueConverter(converter: ValueConverter): void; - visitAssign(assign: Assign): void; - visitConditional(conditional: Conditional): void; - visitAccessThis(access: AccessThis): void; - visitAccessScope(access: AccessScope): void; - visitAccessMember(access: AccessMember): void; - visitAccessKeyed(access: AccessKeyed): void; - visitCallScope(call: CallScope): void; - visitCallFunction(call: CallFunction): void; - visitCallMember(call: CallMember): void; - visitPrefix(prefix: PrefixNot): void; - visitBinary(binary: Binary): void; - visitLiteralPrimitive(literal: LiteralPrimitive): void; - visitLiteralArray(literal: LiteralArray): void; - visitLiteralObject(literal: LiteralObject): void; - visitLiteralString(literal: LiteralString): void; - private visitArgs(args); -} diff --git a/dist/es2017/implementation/expression-visitor.js b/dist/es2017/implementation/expression-visitor.js deleted file mode 100644 index 656c6d0e..00000000 --- a/dist/es2017/implementation/expression-visitor.js +++ /dev/null @@ -1,71 +0,0 @@ -// tslint:disable:no-empty -export class ExpressionVisitor { - visitChain(chain) { - this.visitArgs(chain.expressions); - } - visitBindingBehavior(behavior) { - behavior.expression.accept(this); - this.visitArgs(behavior.args); - } - visitValueConverter(converter) { - converter.expression.accept(this); - this.visitArgs(converter.args); - } - visitAssign(assign) { - assign.target.accept(this); - assign.value.accept(this); - } - visitConditional(conditional) { - conditional.condition.accept(this); - conditional.yes.accept(this); - conditional.no.accept(this); - } - visitAccessThis(access) { - access.ancestor = access.ancestor; - } - visitAccessScope(access) { - access.name = access.name; - } - visitAccessMember(access) { - access.object.accept(this); - } - visitAccessKeyed(access) { - access.object.accept(this); - access.key.accept(this); - } - visitCallScope(call) { - this.visitArgs(call.args); - } - visitCallFunction(call) { - call.func.accept(this); - this.visitArgs(call.args); - } - visitCallMember(call) { - call.object.accept(this); - this.visitArgs(call.args); - } - visitPrefix(prefix) { - prefix.expression.accept(this); - } - visitBinary(binary) { - binary.left.accept(this); - binary.right.accept(this); - } - visitLiteralPrimitive(literal) { - literal.value = literal.value; - } - visitLiteralArray(literal) { - this.visitArgs(literal.elements); - } - visitLiteralObject(literal) { - this.visitArgs(literal.values); - } - visitLiteralString(literal) { - literal.value = literal.value; - } - visitArgs(args) { - for (let i = 0; i < args.length; i++) { - args[i].accept(this); - } - } -} diff --git a/dist/es2017/implementation/rule.d.ts b/dist/es2017/implementation/rule.d.ts deleted file mode 100644 index ffbb7b21..00000000 --- a/dist/es2017/implementation/rule.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Expression } from 'aurelia-binding'; -export declare type ValidationDisplayNameAccessor = () => string; -/** - * Information related to a property that is the subject of validation. - */ -export interface RuleProperty { - /** - * The property name. null indicates the rule targets the object itself. - */ - name: string | number | null; - /** - * The displayName of the property (or object). - */ - displayName: string | ValidationDisplayNameAccessor | null; -} -/** - * A rule definition. Associations a rule with a property or object. - */ -export interface Rule { - property: RuleProperty; - condition: (value: TValue, object?: TObject) => boolean | Promise; - config: object; - when: ((object: TObject) => boolean) | null; - messageKey: string; - message: Expression | null; - sequence: number; - tag?: string; -} diff --git a/dist/es2017/implementation/rule.js b/dist/es2017/implementation/rule.js deleted file mode 100644 index e69de29b..00000000 diff --git a/dist/es2017/implementation/rules.d.ts b/dist/es2017/implementation/rules.d.ts deleted file mode 100644 index 30947f6f..00000000 --- a/dist/es2017/implementation/rules.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Rule } from './rule'; -/** - * Sets, unsets and retrieves rules on an object or constructor function. - */ -export declare class Rules { - /** - * The name of the property that stores the rules. - */ - private static key; - /** - * Applies the rules to a target. - */ - static set(target: any, rules: Rule[][]): void; - /** - * Removes rules from a target. - */ - static unset(target: any): void; - /** - * Retrieves the target's rules. - */ - static get(target: any): Rule[][] | null; -} diff --git a/dist/es2017/implementation/rules.js b/dist/es2017/implementation/rules.js deleted file mode 100644 index db8977e5..00000000 --- a/dist/es2017/implementation/rules.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Sets, unsets and retrieves rules on an object or constructor function. - */ -export class Rules { - /** - * Applies the rules to a target. - */ - static set(target, rules) { - if (target instanceof Function) { - target = target.prototype; - } - Object.defineProperty(target, Rules.key, { enumerable: false, configurable: false, writable: true, value: rules }); - } - /** - * Removes rules from a target. - */ - static unset(target) { - if (target instanceof Function) { - target = target.prototype; - } - target[Rules.key] = null; - } - /** - * Retrieves the target's rules. - */ - static get(target) { - return target[Rules.key] || null; - } -} -/** - * The name of the property that stores the rules. - */ -Rules.key = '__rules__'; diff --git a/dist/es2017/implementation/standard-validator.d.ts b/dist/es2017/implementation/standard-validator.d.ts deleted file mode 100644 index c47a7d2e..00000000 --- a/dist/es2017/implementation/standard-validator.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { ViewResources } from 'aurelia-templating'; -import { Validator } from '../validator'; -import { ValidateResult } from '../validate-result'; -import { Rule } from './rule'; -import { ValidationMessageProvider } from './validation-messages'; -/** - * Validates. - * Responsible for validating objects and properties. - */ -export declare class StandardValidator extends Validator { - static inject: (typeof ViewResources | typeof ValidationMessageProvider)[]; - private messageProvider; - private lookupFunctions; - private getDisplayName; - constructor(messageProvider: ValidationMessageProvider, resources: ViewResources); - /** - * Validates the specified property. - * @param object The object to validate. - * @param propertyName The name of the property to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - validateProperty(object: any, propertyName: string | number, rules?: any): Promise; - /** - * Validates all rules for specified object and it's properties. - * @param object The object to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - validateObject(object: any, rules?: any): Promise; - /** - * Determines whether a rule exists in a set of rules. - * @param rules The rules to search. - * @parem rule The rule to find. - */ - ruleExists(rules: Rule[][], rule: Rule): boolean; - private getMessage(rule, object, value); - private validateRuleSequence(object, propertyName, ruleSequence, sequence, results); - private validate(object, propertyName, rules); -} diff --git a/dist/es2017/implementation/standard-validator.js b/dist/es2017/implementation/standard-validator.js deleted file mode 100644 index a6b3714a..00000000 --- a/dist/es2017/implementation/standard-validator.js +++ /dev/null @@ -1,122 +0,0 @@ -import { ViewResources } from 'aurelia-templating'; -import { Validator } from '../validator'; -import { ValidateResult } from '../validate-result'; -import { Rules } from './rules'; -import { ValidationMessageProvider } from './validation-messages'; -/** - * Validates. - * Responsible for validating objects and properties. - */ -export class StandardValidator extends Validator { - constructor(messageProvider, resources) { - super(); - this.messageProvider = messageProvider; - this.lookupFunctions = resources.lookupFunctions; - this.getDisplayName = messageProvider.getDisplayName.bind(messageProvider); - } - /** - * Validates the specified property. - * @param object The object to validate. - * @param propertyName The name of the property to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - validateProperty(object, propertyName, rules) { - return this.validate(object, propertyName, rules || null); - } - /** - * Validates all rules for specified object and it's properties. - * @param object The object to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - validateObject(object, rules) { - return this.validate(object, null, rules || null); - } - /** - * Determines whether a rule exists in a set of rules. - * @param rules The rules to search. - * @parem rule The rule to find. - */ - ruleExists(rules, rule) { - let i = rules.length; - while (i--) { - if (rules[i].indexOf(rule) !== -1) { - return true; - } - } - return false; - } - getMessage(rule, object, value) { - const expression = rule.message || this.messageProvider.getMessage(rule.messageKey); - // tslint:disable-next-line:prefer-const - let { name: propertyName, displayName } = rule.property; - if (propertyName !== null) { - displayName = this.messageProvider.getDisplayName(propertyName, displayName); - } - const overrideContext = { - $displayName: displayName, - $propertyName: propertyName, - $value: value, - $object: object, - $config: rule.config, - // returns the name of a given property, given just the property name (irrespective of the property's displayName) - // split on capital letters, first letter ensured to be capitalized - $getDisplayName: this.getDisplayName - }; - return expression.evaluate({ bindingContext: object, overrideContext }, this.lookupFunctions); - } - validateRuleSequence(object, propertyName, ruleSequence, sequence, results) { - // are we validating all properties or a single property? - const validateAllProperties = propertyName === null || propertyName === undefined; - const rules = ruleSequence[sequence]; - let allValid = true; - // validate each rule. - const promises = []; - for (let i = 0; i < rules.length; i++) { - const rule = rules[i]; - // is the rule related to the property we're validating. - // tslint:disable-next-line:triple-equals | Use loose equality for property keys - if (!validateAllProperties && rule.property.name != propertyName) { - continue; - } - // is this a conditional rule? is the condition met? - if (rule.when && !rule.when(object)) { - continue; - } - // validate. - const value = rule.property.name === null ? object : object[rule.property.name]; - let promiseOrBoolean = rule.condition(value, object); - if (!(promiseOrBoolean instanceof Promise)) { - promiseOrBoolean = Promise.resolve(promiseOrBoolean); - } - promises.push(promiseOrBoolean.then(valid => { - const message = valid ? null : this.getMessage(rule, object, value); - results.push(new ValidateResult(rule, object, rule.property.name, valid, message)); - allValid = allValid && valid; - return valid; - })); - } - return Promise.all(promises) - .then(() => { - sequence++; - if (allValid && sequence < ruleSequence.length) { - return this.validateRuleSequence(object, propertyName, ruleSequence, sequence, results); - } - return results; - }); - } - validate(object, propertyName, rules) { - // rules specified? - if (!rules) { - // no. attempt to locate the rules. - rules = Rules.get(object); - } - // any rules? - if (!rules || rules.length === 0) { - return Promise.resolve([]); - } - return this.validateRuleSequence(object, propertyName, rules, 0, []); - } -} -StandardValidator.inject = [ValidationMessageProvider, ViewResources]; diff --git a/dist/es2017/implementation/validation-message-parser.d.ts b/dist/es2017/implementation/validation-message-parser.d.ts deleted file mode 100644 index 39d288c0..00000000 --- a/dist/es2017/implementation/validation-message-parser.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Expression, AccessScope } from 'aurelia-binding'; -import { BindingLanguage } from 'aurelia-templating'; -import { ExpressionVisitor } from './expression-visitor'; -export declare class ValidationMessageParser { - private bindinqLanguage; - static inject: (typeof BindingLanguage)[]; - private emptyStringExpression; - private nullExpression; - private undefinedExpression; - private cache; - constructor(bindinqLanguage: BindingLanguage); - parse(message: string): Expression; - private coalesce(part); -} -export declare class MessageExpressionValidator extends ExpressionVisitor { - private originalMessage; - static validate(expression: Expression, originalMessage: string): void; - constructor(originalMessage: string); - visitAccessScope(access: AccessScope): void; -} diff --git a/dist/es2017/implementation/validation-message-parser.js b/dist/es2017/implementation/validation-message-parser.js deleted file mode 100644 index dd93ce70..00000000 --- a/dist/es2017/implementation/validation-message-parser.js +++ /dev/null @@ -1,53 +0,0 @@ -import { LiteralString, Binary, Conditional, LiteralPrimitive, CallMember } from 'aurelia-binding'; -import { BindingLanguage } from 'aurelia-templating'; -import * as LogManager from 'aurelia-logging'; -import { ExpressionVisitor } from './expression-visitor'; -export class ValidationMessageParser { - constructor(bindinqLanguage) { - this.bindinqLanguage = bindinqLanguage; - this.emptyStringExpression = new LiteralString(''); - this.nullExpression = new LiteralPrimitive(null); - this.undefinedExpression = new LiteralPrimitive(undefined); - this.cache = {}; - } - parse(message) { - if (this.cache[message] !== undefined) { - return this.cache[message]; - } - const parts = this.bindinqLanguage.parseInterpolation(null, message); - if (parts === null) { - return new LiteralString(message); - } - let expression = new LiteralString(parts[0]); - for (let i = 1; i < parts.length; i += 2) { - expression = new Binary('+', expression, new Binary('+', this.coalesce(parts[i]), new LiteralString(parts[i + 1]))); - } - MessageExpressionValidator.validate(expression, message); - this.cache[message] = expression; - return expression; - } - coalesce(part) { - // part === null || part === undefined ? '' : part - return new Conditional(new Binary('||', new Binary('===', part, this.nullExpression), new Binary('===', part, this.undefinedExpression)), this.emptyStringExpression, new CallMember(part, 'toString', [])); - } -} -ValidationMessageParser.inject = [BindingLanguage]; -export class MessageExpressionValidator extends ExpressionVisitor { - constructor(originalMessage) { - super(); - this.originalMessage = originalMessage; - } - static validate(expression, originalMessage) { - const visitor = new MessageExpressionValidator(originalMessage); - expression.accept(visitor); - } - visitAccessScope(access) { - if (access.ancestor !== 0) { - throw new Error('$parent is not permitted in validation message expressions.'); - } - if (['displayName', 'propertyName', 'value', 'object', 'config', 'getDisplayName'].indexOf(access.name) !== -1) { - LogManager.getLogger('aurelia-validation') - .warn(`Did you mean to use "$${access.name}" instead of "${access.name}" in this validation message template: "${this.originalMessage}"?`); - } - } -} diff --git a/dist/es2017/implementation/validation-messages.d.ts b/dist/es2017/implementation/validation-messages.d.ts deleted file mode 100644 index eb4cb9d4..00000000 --- a/dist/es2017/implementation/validation-messages.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Expression } from 'aurelia-binding'; -import { ValidationMessageParser } from './validation-message-parser'; -export interface ValidationMessages { - [key: string]: string; -} -/** - * Dictionary of validation messages. [messageKey]: messageExpression - */ -export declare const validationMessages: ValidationMessages; -/** - * Retrieves validation messages and property display names. - */ -export declare class ValidationMessageProvider { - parser: ValidationMessageParser; - static inject: (typeof ValidationMessageParser)[]; - constructor(parser: ValidationMessageParser); - /** - * Returns a message binding expression that corresponds to the key. - * @param key The message key. - */ - getMessage(key: string): Expression; - /** - * Formulates a property display name using the property name and the configured - * displayName (if provided). - * Override this with your own custom logic. - * @param propertyName The property name. - */ - getDisplayName(propertyName: string | number, displayName?: string | null | (() => string)): string; -} diff --git a/dist/es2017/implementation/validation-messages.js b/dist/es2017/implementation/validation-messages.js deleted file mode 100644 index d64acf32..00000000 --- a/dist/es2017/implementation/validation-messages.js +++ /dev/null @@ -1,56 +0,0 @@ -import { ValidationMessageParser } from './validation-message-parser'; -/** - * Dictionary of validation messages. [messageKey]: messageExpression - */ -export const validationMessages = { - /** - * The default validation message. Used with rules that have no standard message. - */ - default: `\${$displayName} is invalid.`, - required: `\${$displayName} is required.`, - matches: `\${$displayName} is not correctly formatted.`, - email: `\${$displayName} is not a valid email.`, - minLength: `\${$displayName} must be at least \${$config.length} character\${$config.length === 1 ? '' : 's'}.`, - maxLength: `\${$displayName} cannot be longer than \${$config.length} character\${$config.length === 1 ? '' : 's'}.`, - minItems: `\${$displayName} must contain at least \${$config.count} item\${$config.count === 1 ? '' : 's'}.`, - maxItems: `\${$displayName} cannot contain more than \${$config.count} item\${$config.count === 1 ? '' : 's'}.`, - equals: `\${$displayName} must be \${$config.expectedValue}.`, -}; -/** - * Retrieves validation messages and property display names. - */ -export class ValidationMessageProvider { - constructor(parser) { - this.parser = parser; - } - /** - * Returns a message binding expression that corresponds to the key. - * @param key The message key. - */ - getMessage(key) { - let message; - if (key in validationMessages) { - message = validationMessages[key]; - } - else { - message = validationMessages['default']; - } - return this.parser.parse(message); - } - /** - * Formulates a property display name using the property name and the configured - * displayName (if provided). - * Override this with your own custom logic. - * @param propertyName The property name. - */ - getDisplayName(propertyName, displayName) { - if (displayName !== null && displayName !== undefined) { - return (displayName instanceof Function) ? displayName() : displayName; - } - // split on upper-case letters. - const words = propertyName.toString().split(/(?=[A-Z])/).join(' '); - // capitalize first letter. - return words.charAt(0).toUpperCase() + words.slice(1); - } -} -ValidationMessageProvider.inject = [ValidationMessageParser]; diff --git a/dist/es2017/implementation/validation-rules.d.ts b/dist/es2017/implementation/validation-rules.d.ts deleted file mode 100644 index 995b2a8a..00000000 --- a/dist/es2017/implementation/validation-rules.d.ts +++ /dev/null @@ -1,262 +0,0 @@ -import { Rule, RuleProperty, ValidationDisplayNameAccessor } from './rule'; -import { ValidationMessageParser } from './validation-message-parser'; -import { PropertyAccessorParser, PropertyAccessor } from '../property-accessor-parser'; -/** - * Part of the fluent rule API. Enables customizing property rules. - */ -export declare class FluentRuleCustomizer { - private fluentEnsure; - private fluentRules; - private parsers; - private rule; - constructor(property: RuleProperty, condition: (value: TValue, object?: TObject) => boolean | Promise, config: object | undefined, fluentEnsure: FluentEnsure, fluentRules: FluentRules, parsers: Parsers); - /** - * Validate subsequent rules after previously declared rules have - * been validated successfully. Use to postpone validation of costly - * rules until less expensive rules pass validation. - */ - then(): this; - /** - * Specifies the key to use when looking up the rule's validation message. - */ - withMessageKey(key: string): this; - /** - * Specifies rule's validation message. - */ - withMessage(message: string): this; - /** - * Specifies a condition that must be met before attempting to validate the rule. - * @param condition A function that accepts the object as a parameter and returns true - * or false whether the rule should be evaluated. - */ - when(condition: (object: TObject) => boolean): this; - /** - * Tags the rule instance, enabling the rule to be found easily - * using ValidationRules.taggedRules(rules, tag) - */ - tag(tag: string): this; - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - ensure(subject: string | ((model: TObject) => TValue2)): FluentRules; - /** - * Targets an object with validation rules. - */ - ensureObject(): FluentRules; - /** - * Rules that have been defined using the fluent API. - */ - readonly rules: Rule[][]; - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - on(target: any): FluentEnsure; - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - satisfies(condition: (value: TValue, object: TObject) => boolean | Promise, config?: object): FluentRuleCustomizer; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - satisfiesRule(name: string, ...args: any[]): FluentRuleCustomizer; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - required(): FluentRuleCustomizer; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - matches(regex: RegExp): FluentRuleCustomizer; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - email(): FluentRuleCustomizer; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - minLength(length: number): FluentRuleCustomizer; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - maxLength(length: number): FluentRuleCustomizer; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - minItems(count: number): FluentRuleCustomizer; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - maxItems(count: number): FluentRuleCustomizer; - /** - * Applies the "equals" validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - equals(expectedValue: TValue): FluentRuleCustomizer; -} -/** - * Part of the fluent rule API. Enables applying rules to properties and objects. - */ -export declare class FluentRules { - private fluentEnsure; - private parsers; - private property; - static customRules: { - [name: string]: { - condition: (value: any, object?: any, ...fluentArgs: any[]) => boolean | Promise; - argsToConfig?: (...args: any[]) => any; - }; - }; - /** - * Current rule sequence number. Used to postpone evaluation of rules until rules - * with lower sequence number have successfully validated. The "then" fluent API method - * manages this property, there's usually no need to set it directly. - */ - sequence: number; - constructor(fluentEnsure: FluentEnsure, parsers: Parsers, property: RuleProperty); - /** - * Sets the display name of the ensured property. - */ - displayName(name: string | ValidationDisplayNameAccessor | null): this; - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - satisfies(condition: (value: TValue, object?: TObject) => boolean | Promise, config?: object): FluentRuleCustomizer; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - satisfiesRule(name: string, ...args: any[]): FluentRuleCustomizer; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - required(): FluentRuleCustomizer; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - matches(regex: RegExp): FluentRuleCustomizer; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - email(): FluentRuleCustomizer; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - minLength(length: number): FluentRuleCustomizer; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - maxLength(length: number): FluentRuleCustomizer; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - minItems(count: number): FluentRuleCustomizer; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - maxItems(count: number): FluentRuleCustomizer; - /** - * Applies the "equals" validation rule to the property. - * null and undefined values are considered valid. - */ - equals(expectedValue: TValue): FluentRuleCustomizer; -} -/** - * Part of the fluent rule API. Enables targeting properties and objects with rules. - */ -export declare class FluentEnsure { - private parsers; - /** - * Rules that have been defined using the fluent API. - */ - rules: Rule[][]; - constructor(parsers: Parsers); - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor - * function. - */ - ensure(property: string | number | PropertyAccessor): FluentRules; - /** - * Targets an object with validation rules. - */ - ensureObject(): FluentRules; - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - on(target: any): this; - private assertInitialized(); - private mergeRules(fluentRules, propertyName); -} -/** - * Fluent rule definition API. - */ -export declare class ValidationRules { - private static parsers; - static initialize(messageParser: ValidationMessageParser, propertyParser: PropertyAccessorParser): void; - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - static ensure(property: string | number | PropertyAccessor): FluentRules; - /** - * Targets an object with validation rules. - */ - static ensureObject(): FluentRules; - /** - * Defines a custom rule. - * @param name The name of the custom rule. Also serves as the message key. - * @param condition The rule function. - * @param message The message expression - * @param argsToConfig A function that maps the rule's arguments to a "config" - * object that can be used when evaluating the message expression. - */ - static customRule(name: string, condition: (value: any, object?: any, ...args: any[]) => boolean | Promise, message: string, argsToConfig?: (...args: any[]) => any): void; - /** - * Returns rules with the matching tag. - * @param rules The rules to search. - * @param tag The tag to search for. - */ - static taggedRules(rules: Rule[][], tag: string): Rule[][]; - /** - * Returns rules that have no tag. - * @param rules The rules to search. - */ - static untaggedRules(rules: Rule[][]): Rule[][]; - /** - * Removes the rules from a class or object. - * @param target A class or object. - */ - static off(target: any): void; -} -export interface Parsers { - message: ValidationMessageParser; - property: PropertyAccessorParser; -} diff --git a/dist/es2017/implementation/validation-rules.js b/dist/es2017/implementation/validation-rules.js deleted file mode 100644 index a099896f..00000000 --- a/dist/es2017/implementation/validation-rules.js +++ /dev/null @@ -1,412 +0,0 @@ -import { Rules } from './rules'; -import { validationMessages } from './validation-messages'; -import { isString } from '../util'; -/** - * Part of the fluent rule API. Enables customizing property rules. - */ -export class FluentRuleCustomizer { - constructor(property, condition, config = {}, fluentEnsure, fluentRules, parsers) { - this.fluentEnsure = fluentEnsure; - this.fluentRules = fluentRules; - this.parsers = parsers; - this.rule = { - property, - condition, - config, - when: null, - messageKey: 'default', - message: null, - sequence: fluentRules.sequence - }; - this.fluentEnsure._addRule(this.rule); - } - /** - * Validate subsequent rules after previously declared rules have - * been validated successfully. Use to postpone validation of costly - * rules until less expensive rules pass validation. - */ - then() { - this.fluentRules.sequence++; - return this; - } - /** - * Specifies the key to use when looking up the rule's validation message. - */ - withMessageKey(key) { - this.rule.messageKey = key; - this.rule.message = null; - return this; - } - /** - * Specifies rule's validation message. - */ - withMessage(message) { - this.rule.messageKey = 'custom'; - this.rule.message = this.parsers.message.parse(message); - return this; - } - /** - * Specifies a condition that must be met before attempting to validate the rule. - * @param condition A function that accepts the object as a parameter and returns true - * or false whether the rule should be evaluated. - */ - when(condition) { - this.rule.when = condition; - return this; - } - /** - * Tags the rule instance, enabling the rule to be found easily - * using ValidationRules.taggedRules(rules, tag) - */ - tag(tag) { - this.rule.tag = tag; - return this; - } - ///// FluentEnsure APIs ///// - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - ensure(subject) { - return this.fluentEnsure.ensure(subject); - } - /** - * Targets an object with validation rules. - */ - ensureObject() { - return this.fluentEnsure.ensureObject(); - } - /** - * Rules that have been defined using the fluent API. - */ - get rules() { - return this.fluentEnsure.rules; - } - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - on(target) { - return this.fluentEnsure.on(target); - } - ///////// FluentRules APIs ///////// - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - satisfies(condition, config) { - return this.fluentRules.satisfies(condition, config); - } - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - satisfiesRule(name, ...args) { - return this.fluentRules.satisfiesRule(name, ...args); - } - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - required() { - return this.fluentRules.required(); - } - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - matches(regex) { - return this.fluentRules.matches(regex); - } - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - email() { - return this.fluentRules.email(); - } - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - minLength(length) { - return this.fluentRules.minLength(length); - } - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - maxLength(length) { - return this.fluentRules.maxLength(length); - } - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - minItems(count) { - return this.fluentRules.minItems(count); - } - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - maxItems(count) { - return this.fluentRules.maxItems(count); - } - /** - * Applies the "equals" validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - equals(expectedValue) { - return this.fluentRules.equals(expectedValue); - } -} -/** - * Part of the fluent rule API. Enables applying rules to properties and objects. - */ -export class FluentRules { - constructor(fluentEnsure, parsers, property) { - this.fluentEnsure = fluentEnsure; - this.parsers = parsers; - this.property = property; - /** - * Current rule sequence number. Used to postpone evaluation of rules until rules - * with lower sequence number have successfully validated. The "then" fluent API method - * manages this property, there's usually no need to set it directly. - */ - this.sequence = 0; - } - /** - * Sets the display name of the ensured property. - */ - displayName(name) { - this.property.displayName = name; - return this; - } - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - satisfies(condition, config) { - return new FluentRuleCustomizer(this.property, condition, config, this.fluentEnsure, this, this.parsers); - } - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - satisfiesRule(name, ...args) { - let rule = FluentRules.customRules[name]; - if (!rule) { - // standard rule? - rule = this[name]; - if (rule instanceof Function) { - return rule.call(this, ...args); - } - throw new Error(`Rule with name "${name}" does not exist.`); - } - const config = rule.argsToConfig ? rule.argsToConfig(...args) : undefined; - return this.satisfies((value, obj) => rule.condition.call(this, value, obj, ...args), config) - .withMessageKey(name); - } - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - required() { - return this.satisfies(value => value !== null - && value !== undefined - && !(isString(value) && !/\S/.test(value))).withMessageKey('required'); - } - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - matches(regex) { - return this.satisfies(value => value === null || value === undefined || value.length === 0 || regex.test(value)) - .withMessageKey('matches'); - } - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - email() { - // regex from https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address - /* tslint:disable:max-line-length */ - return this.matches(/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/) - .withMessageKey('email'); - } - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - minLength(length) { - return this.satisfies((value) => value === null || value === undefined || value.length === 0 || value.length >= length, { length }) - .withMessageKey('minLength'); - } - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - maxLength(length) { - return this.satisfies((value) => value === null || value === undefined || value.length === 0 || value.length <= length, { length }) - .withMessageKey('maxLength'); - } - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - minItems(count) { - return this.satisfies((value) => value === null || value === undefined || value.length >= count, { count }) - .withMessageKey('minItems'); - } - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - maxItems(count) { - return this.satisfies((value) => value === null || value === undefined || value.length <= count, { count }) - .withMessageKey('maxItems'); - } - /** - * Applies the "equals" validation rule to the property. - * null and undefined values are considered valid. - */ - equals(expectedValue) { - return this.satisfies(value => value === null || value === undefined || value === '' || value === expectedValue, { expectedValue }) - .withMessageKey('equals'); - } -} -FluentRules.customRules = {}; -/** - * Part of the fluent rule API. Enables targeting properties and objects with rules. - */ -export class FluentEnsure { - constructor(parsers) { - this.parsers = parsers; - /** - * Rules that have been defined using the fluent API. - */ - this.rules = []; - } - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor - * function. - */ - ensure(property) { - this.assertInitialized(); - const name = this.parsers.property.parse(property); - const fluentRules = new FluentRules(this, this.parsers, { name, displayName: null }); - return this.mergeRules(fluentRules, name); - } - /** - * Targets an object with validation rules. - */ - ensureObject() { - this.assertInitialized(); - const fluentRules = new FluentRules(this, this.parsers, { name: null, displayName: null }); - return this.mergeRules(fluentRules, null); - } - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - on(target) { - Rules.set(target, this.rules); - return this; - } - /** - * Adds a rule definition to the sequenced ruleset. - * @internal - */ - _addRule(rule) { - while (this.rules.length < rule.sequence + 1) { - this.rules.push([]); - } - this.rules[rule.sequence].push(rule); - } - assertInitialized() { - if (this.parsers) { - return; - } - throw new Error(`Did you forget to add ".plugin('aurelia-validation')" to your main.js?`); - } - mergeRules(fluentRules, propertyName) { - // tslint:disable-next-line:triple-equals | Use loose equality for property keys - const existingRules = this.rules.find(r => r.length > 0 && r[0].property.name == propertyName); - if (existingRules) { - const rule = existingRules[existingRules.length - 1]; - fluentRules.sequence = rule.sequence; - if (rule.property.displayName !== null) { - fluentRules = fluentRules.displayName(rule.property.displayName); - } - } - return fluentRules; - } -} -/** - * Fluent rule definition API. - */ -export class ValidationRules { - static initialize(messageParser, propertyParser) { - this.parsers = { - message: messageParser, - property: propertyParser - }; - } - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - static ensure(property) { - return new FluentEnsure(ValidationRules.parsers).ensure(property); - } - /** - * Targets an object with validation rules. - */ - static ensureObject() { - return new FluentEnsure(ValidationRules.parsers).ensureObject(); - } - /** - * Defines a custom rule. - * @param name The name of the custom rule. Also serves as the message key. - * @param condition The rule function. - * @param message The message expression - * @param argsToConfig A function that maps the rule's arguments to a "config" - * object that can be used when evaluating the message expression. - */ - static customRule(name, condition, message, argsToConfig) { - validationMessages[name] = message; - FluentRules.customRules[name] = { condition, argsToConfig }; - } - /** - * Returns rules with the matching tag. - * @param rules The rules to search. - * @param tag The tag to search for. - */ - static taggedRules(rules, tag) { - return rules.map(x => x.filter(r => r.tag === tag)); - } - /** - * Returns rules that have no tag. - * @param rules The rules to search. - */ - static untaggedRules(rules) { - return rules.map(x => x.filter(r => r.tag === undefined)); - } - /** - * Removes the rules from a class or object. - * @param target A class or object. - */ - static off(target) { - Rules.unset(target); - } -} diff --git a/dist/es2017/property-accessor-parser.d.ts b/dist/es2017/property-accessor-parser.d.ts deleted file mode 100644 index ba64614b..00000000 --- a/dist/es2017/property-accessor-parser.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Parser } from 'aurelia-binding'; -export declare type PropertyAccessor = (object: TObject) => TValue; -export declare class PropertyAccessorParser { - private parser; - static inject: (typeof Parser)[]; - constructor(parser: Parser); - parse(property: string | number | PropertyAccessor): string | number; -} -export declare function getAccessorExpression(fn: string): string; diff --git a/dist/es2017/property-accessor-parser.js b/dist/es2017/property-accessor-parser.js deleted file mode 100644 index 7ed019fa..00000000 --- a/dist/es2017/property-accessor-parser.js +++ /dev/null @@ -1,31 +0,0 @@ -import { Parser, AccessMember, AccessScope } from 'aurelia-binding'; -import { isString, isNumber } from './util'; -export class PropertyAccessorParser { - constructor(parser) { - this.parser = parser; - } - parse(property) { - if (isString(property) || isNumber(property)) { - return property; - } - const accessorText = getAccessorExpression(property.toString()); - const accessor = this.parser.parse(accessorText); - if (accessor instanceof AccessScope - || accessor instanceof AccessMember && accessor.object instanceof AccessScope) { - return accessor.name; - } - throw new Error(`Invalid property expression: "${accessor}"`); - } -} -PropertyAccessorParser.inject = [Parser]; -export function getAccessorExpression(fn) { - /* tslint:disable:max-line-length */ - const classic = /^function\s*\([$_\w\d]+\)\s*\{(?:\s*"use strict";)?\s*(?:[$_\w\d.['"\]+;]+)?\s*return\s+[$_\w\d]+\.([$_\w\d]+)\s*;?\s*\}$/; - /* tslint:enable:max-line-length */ - const arrow = /^\(?[$_\w\d]+\)?\s*=>\s*[$_\w\d]+\.([$_\w\d]+)$/; - const match = classic.exec(fn) || arrow.exec(fn); - if (match === null) { - throw new Error(`Unable to parse accessor function:\n${fn}`); - } - return match[1]; -} diff --git a/dist/es2017/property-info.d.ts b/dist/es2017/property-info.d.ts deleted file mode 100644 index 35fef1d5..00000000 --- a/dist/es2017/property-info.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Expression, Scope } from 'aurelia-binding'; -/** - * Retrieves the object and property name for the specified expression. - * @param expression The expression - * @param source The scope - */ -export declare function getPropertyInfo(expression: Expression, source: Scope): { - object: object; - propertyName: string; -} | null; diff --git a/dist/es2017/property-info.js b/dist/es2017/property-info.js deleted file mode 100644 index 031b4665..00000000 --- a/dist/es2017/property-info.js +++ /dev/null @@ -1,41 +0,0 @@ -import { AccessMember, AccessScope, AccessKeyed, BindingBehavior, ValueConverter, getContextFor } from 'aurelia-binding'; -function getObject(expression, objectExpression, source) { - const value = objectExpression.evaluate(source, null); - if (value === null || value === undefined || value instanceof Object) { - return value; - } - // tslint:disable-next-line:max-line-length - throw new Error(`The '${objectExpression}' part of '${expression}' evaluates to ${value} instead of an object, null or undefined.`); -} -/** - * Retrieves the object and property name for the specified expression. - * @param expression The expression - * @param source The scope - */ -export function getPropertyInfo(expression, source) { - const originalExpression = expression; - while (expression instanceof BindingBehavior || expression instanceof ValueConverter) { - expression = expression.expression; - } - let object; - let propertyName; - if (expression instanceof AccessScope) { - object = getContextFor(expression.name, source, expression.ancestor); - propertyName = expression.name; - } - else if (expression instanceof AccessMember) { - object = getObject(originalExpression, expression.object, source); - propertyName = expression.name; - } - else if (expression instanceof AccessKeyed) { - object = getObject(originalExpression, expression.object, source); - propertyName = expression.key.evaluate(source); - } - else { - throw new Error(`Expression '${originalExpression}' is not compatible with the validate binding-behavior.`); - } - if (object === null || object === undefined) { - return null; - } - return { object, propertyName }; -} diff --git a/dist/es2017/util.d.ts b/dist/es2017/util.d.ts deleted file mode 100644 index f6873f03..00000000 --- a/dist/es2017/util.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export declare function isString(value: any): boolean; -export declare function isNumber(value: any): boolean; diff --git a/dist/es2017/util.js b/dist/es2017/util.js deleted file mode 100644 index 8b4ad402..00000000 --- a/dist/es2017/util.js +++ /dev/null @@ -1,6 +0,0 @@ -export function isString(value) { - return Object.prototype.toString.call(value) === '[object String]'; -} -export function isNumber(value) { - return Object.prototype.toString.call(value) === '[object Number]'; -} diff --git a/dist/es2017/validate-binding-behavior-base.d.ts b/dist/es2017/validate-binding-behavior-base.d.ts deleted file mode 100644 index 971c8e83..00000000 --- a/dist/es2017/validate-binding-behavior-base.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { TaskQueue } from 'aurelia-task-queue'; -import { ValidationController } from './validation-controller'; -import { validateTrigger } from './validate-trigger'; -/** - * Binding behavior. Indicates the bound property should be validated. - */ -export declare abstract class ValidateBindingBehaviorBase { - private taskQueue; - constructor(taskQueue: TaskQueue); - protected abstract getValidateTrigger(controller: ValidationController): validateTrigger; - bind(binding: any, source: any, rulesOrController?: ValidationController | any, rules?: any): void; - unbind(binding: any): void; -} diff --git a/dist/es2017/validate-binding-behavior-base.js b/dist/es2017/validate-binding-behavior-base.js deleted file mode 100644 index b35e5805..00000000 --- a/dist/es2017/validate-binding-behavior-base.js +++ /dev/null @@ -1,76 +0,0 @@ -import { Optional } from 'aurelia-dependency-injection'; -import { ValidationController } from './validation-controller'; -import { validateTrigger } from './validate-trigger'; -import { getTargetDOMElement } from './get-target-dom-element'; -/** - * Binding behavior. Indicates the bound property should be validated. - */ -export class ValidateBindingBehaviorBase { - constructor(taskQueue) { - this.taskQueue = taskQueue; - } - bind(binding, source, rulesOrController, rules) { - // identify the target element. - const target = getTargetDOMElement(binding, source); - // locate the controller. - let controller; - if (rulesOrController instanceof ValidationController) { - controller = rulesOrController; - } - else { - controller = source.container.get(Optional.of(ValidationController)); - rules = rulesOrController; - } - if (controller === null) { - throw new Error(`A ValidationController has not been registered.`); - } - controller.registerBinding(binding, target, rules); - binding.validationController = controller; - const trigger = this.getValidateTrigger(controller); - // tslint:disable-next-line:no-bitwise - if (trigger & validateTrigger.change) { - binding.vbbUpdateSource = binding.updateSource; - // tslint:disable-next-line:only-arrow-functions - // tslint:disable-next-line:space-before-function-paren - binding.updateSource = function (value) { - this.vbbUpdateSource(value); - this.validationController.validateBinding(this); - }; - } - // tslint:disable-next-line:no-bitwise - if (trigger & validateTrigger.blur) { - binding.validateBlurHandler = () => { - this.taskQueue.queueMicroTask(() => controller.validateBinding(binding)); - }; - binding.validateTarget = target; - target.addEventListener('blur', binding.validateBlurHandler); - } - if (trigger !== validateTrigger.manual) { - binding.standardUpdateTarget = binding.updateTarget; - // tslint:disable-next-line:only-arrow-functions - // tslint:disable-next-line:space-before-function-paren - binding.updateTarget = function (value) { - this.standardUpdateTarget(value); - this.validationController.resetBinding(this); - }; - } - } - unbind(binding) { - // reset the binding to it's original state. - if (binding.vbbUpdateSource) { - binding.updateSource = binding.vbbUpdateSource; - binding.vbbUpdateSource = null; - } - if (binding.standardUpdateTarget) { - binding.updateTarget = binding.standardUpdateTarget; - binding.standardUpdateTarget = null; - } - if (binding.validateBlurHandler) { - binding.validateTarget.removeEventListener('blur', binding.validateBlurHandler); - binding.validateBlurHandler = null; - binding.validateTarget = null; - } - binding.validationController.unregisterBinding(binding); - binding.validationController = null; - } -} diff --git a/dist/es2017/validate-binding-behavior.d.ts b/dist/es2017/validate-binding-behavior.d.ts deleted file mode 100644 index 08b5d9e0..00000000 --- a/dist/es2017/validate-binding-behavior.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { TaskQueue } from 'aurelia-task-queue'; -import { ValidationController } from './validation-controller'; -import { validateTrigger } from './validate-trigger'; -import { ValidateBindingBehaviorBase } from './validate-binding-behavior-base'; -/** - * Binding behavior. Indicates the bound property should be validated - * when the validate trigger specified by the associated controller's - * validateTrigger property occurs. - */ -export declare class ValidateBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(controller: ValidationController): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property will be validated - * manually, by calling controller.validate(). No automatic validation - * triggered by data-entry or blur will occur. - */ -export declare class ValidateManuallyBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs. - */ -export declare class ValidateOnBlurBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element is changed by the user, causing a change - * to the model. - */ -export declare class ValidateOnChangeBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs or is changed by the user, causing - * a change to the model. - */ -export declare class ValidateOnChangeOrBlurBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} diff --git a/dist/es2017/validate-binding-behavior.js b/dist/es2017/validate-binding-behavior.js deleted file mode 100644 index 318d227a..00000000 --- a/dist/es2017/validate-binding-behavior.js +++ /dev/null @@ -1,57 +0,0 @@ -import { TaskQueue } from 'aurelia-task-queue'; -import { validateTrigger } from './validate-trigger'; -import { ValidateBindingBehaviorBase } from './validate-binding-behavior-base'; -/** - * Binding behavior. Indicates the bound property should be validated - * when the validate trigger specified by the associated controller's - * validateTrigger property occurs. - */ -export class ValidateBindingBehavior extends ValidateBindingBehaviorBase { - getValidateTrigger(controller) { - return controller.validateTrigger; - } -} -ValidateBindingBehavior.inject = [TaskQueue]; -/** - * Binding behavior. Indicates the bound property will be validated - * manually, by calling controller.validate(). No automatic validation - * triggered by data-entry or blur will occur. - */ -export class ValidateManuallyBindingBehavior extends ValidateBindingBehaviorBase { - getValidateTrigger() { - return validateTrigger.manual; - } -} -ValidateManuallyBindingBehavior.inject = [TaskQueue]; -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs. - */ -export class ValidateOnBlurBindingBehavior extends ValidateBindingBehaviorBase { - getValidateTrigger() { - return validateTrigger.blur; - } -} -ValidateOnBlurBindingBehavior.inject = [TaskQueue]; -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element is changed by the user, causing a change - * to the model. - */ -export class ValidateOnChangeBindingBehavior extends ValidateBindingBehaviorBase { - getValidateTrigger() { - return validateTrigger.change; - } -} -ValidateOnChangeBindingBehavior.inject = [TaskQueue]; -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs or is changed by the user, causing - * a change to the model. - */ -export class ValidateOnChangeOrBlurBindingBehavior extends ValidateBindingBehaviorBase { - getValidateTrigger() { - return validateTrigger.changeOrBlur; - } -} -ValidateOnChangeOrBlurBindingBehavior.inject = [TaskQueue]; diff --git a/dist/es2017/validate-event.d.ts b/dist/es2017/validate-event.d.ts deleted file mode 100644 index 0fbacbb7..00000000 --- a/dist/es2017/validate-event.d.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { ValidateResult } from './validate-result'; -import { ValidateInstruction } from './validate-instruction'; -import { ControllerValidateResult } from './controller-validate-result'; -export declare class ValidateEvent { - /** - * The type of validate event. Either "validate" or "reset". - */ - readonly type: 'validate' | 'reset'; - /** - * The controller's current array of errors. For an array containing both - * failed rules and passed rules, use the "results" property. - */ - readonly errors: ValidateResult[]; - /** - * The controller's current array of validate results. This - * includes both passed rules and failed rules. For an array of only failed rules, - * use the "errors" property. - */ - readonly results: ValidateResult[]; - /** - * The instruction passed to the "validate" or "reset" event. Will be null when - * the controller's validate/reset method was called with no instruction argument. - */ - readonly instruction: ValidateInstruction | null; - /** - * In events with type === "validate", this property will contain the result - * of validating the instruction (see "instruction" property). Use the controllerValidateResult - * to access the validate results specific to the call to "validate" - * (as opposed to using the "results" and "errors" properties to access the controller's entire - * set of results/errors). - */ - readonly controllerValidateResult: ControllerValidateResult | null; - constructor( - /** - * The type of validate event. Either "validate" or "reset". - */ - type: 'validate' | 'reset', - /** - * The controller's current array of errors. For an array containing both - * failed rules and passed rules, use the "results" property. - */ - errors: ValidateResult[], - /** - * The controller's current array of validate results. This - * includes both passed rules and failed rules. For an array of only failed rules, - * use the "errors" property. - */ - results: ValidateResult[], - /** - * The instruction passed to the "validate" or "reset" event. Will be null when - * the controller's validate/reset method was called with no instruction argument. - */ - instruction: ValidateInstruction | null, - /** - * In events with type === "validate", this property will contain the result - * of validating the instruction (see "instruction" property). Use the controllerValidateResult - * to access the validate results specific to the call to "validate" - * (as opposed to using the "results" and "errors" properties to access the controller's entire - * set of results/errors). - */ - controllerValidateResult: ControllerValidateResult | null); -} diff --git a/dist/es2017/validate-event.js b/dist/es2017/validate-event.js deleted file mode 100644 index e6c5d57b..00000000 --- a/dist/es2017/validate-event.js +++ /dev/null @@ -1,37 +0,0 @@ -export class ValidateEvent { - constructor( - /** - * The type of validate event. Either "validate" or "reset". - */ - type, - /** - * The controller's current array of errors. For an array containing both - * failed rules and passed rules, use the "results" property. - */ - errors, - /** - * The controller's current array of validate results. This - * includes both passed rules and failed rules. For an array of only failed rules, - * use the "errors" property. - */ - results, - /** - * The instruction passed to the "validate" or "reset" event. Will be null when - * the controller's validate/reset method was called with no instruction argument. - */ - instruction, - /** - * In events with type === "validate", this property will contain the result - * of validating the instruction (see "instruction" property). Use the controllerValidateResult - * to access the validate results specific to the call to "validate" - * (as opposed to using the "results" and "errors" properties to access the controller's entire - * set of results/errors). - */ - controllerValidateResult) { - this.type = type; - this.errors = errors; - this.results = results; - this.instruction = instruction; - this.controllerValidateResult = controllerValidateResult; - } -} diff --git a/dist/es2017/validate-instruction.d.ts b/dist/es2017/validate-instruction.d.ts deleted file mode 100644 index 2f792a70..00000000 --- a/dist/es2017/validate-instruction.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Instructions for the validation controller's validate method. - */ -export interface ValidateInstruction { - /** - * The object to validate. - */ - object: any; - /** - * The property to validate. Optional. - */ - propertyName?: any; - /** - * The rules to validate. Optional. - */ - rules?: any; -} diff --git a/dist/es2017/validate-instruction.js b/dist/es2017/validate-instruction.js deleted file mode 100644 index e69de29b..00000000 diff --git a/dist/es2017/validate-result.d.ts b/dist/es2017/validate-result.d.ts deleted file mode 100644 index 91d79995..00000000 --- a/dist/es2017/validate-result.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * The result of validating an individual validation rule. - */ -export declare class ValidateResult { - rule: any; - object: any; - propertyName: string | number | null; - valid: boolean; - message: string | null; - private static nextId; - /** - * A number that uniquely identifies the result instance. - */ - id: number; - /** - * @param rule The rule associated with the result. Validator implementation specific. - * @param object The object that was validated. - * @param propertyName The name of the property that was validated. - * @param error The error, if the result is a validation error. - */ - constructor(rule: any, object: any, propertyName: string | number | null, valid: boolean, message?: string | null); - toString(): string | null; -} diff --git a/dist/es2017/validate-result.js b/dist/es2017/validate-result.js deleted file mode 100644 index 37e90f42..00000000 --- a/dist/es2017/validate-result.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * The result of validating an individual validation rule. - */ -export class ValidateResult { - /** - * @param rule The rule associated with the result. Validator implementation specific. - * @param object The object that was validated. - * @param propertyName The name of the property that was validated. - * @param error The error, if the result is a validation error. - */ - constructor(rule, object, propertyName, valid, message = null) { - this.rule = rule; - this.object = object; - this.propertyName = propertyName; - this.valid = valid; - this.message = message; - this.id = ValidateResult.nextId++; - } - toString() { - return this.valid ? 'Valid.' : this.message; - } -} -ValidateResult.nextId = 0; diff --git a/dist/es2017/validate-trigger.d.ts b/dist/es2017/validate-trigger.d.ts deleted file mode 100644 index 43e76851..00000000 --- a/dist/es2017/validate-trigger.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Validation triggers. - */ -export declare enum validateTrigger { - /** - * Manual validation. Use the controller's `validate()` and `reset()` methods - * to validate all bindings. - */ - manual = 0, - /** - * Validate the binding when the binding's target element fires a DOM "blur" event. - */ - blur = 1, - /** - * Validate the binding when it updates the model due to a change in the view. - */ - change = 2, - /** - * Validate the binding when the binding's target element fires a DOM "blur" event and - * when it updates the model due to a change in the view. - */ - changeOrBlur = 3, -} diff --git a/dist/es2017/validate-trigger.js b/dist/es2017/validate-trigger.js deleted file mode 100644 index c00b9e21..00000000 --- a/dist/es2017/validate-trigger.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Validation triggers. - */ -export var validateTrigger; -(function (validateTrigger) { - /** - * Manual validation. Use the controller's `validate()` and `reset()` methods - * to validate all bindings. - */ - validateTrigger[validateTrigger["manual"] = 0] = "manual"; - /** - * Validate the binding when the binding's target element fires a DOM "blur" event. - */ - validateTrigger[validateTrigger["blur"] = 1] = "blur"; - /** - * Validate the binding when it updates the model due to a change in the view. - */ - validateTrigger[validateTrigger["change"] = 2] = "change"; - /** - * Validate the binding when the binding's target element fires a DOM "blur" event and - * when it updates the model due to a change in the view. - */ - validateTrigger[validateTrigger["changeOrBlur"] = 3] = "changeOrBlur"; -})(validateTrigger || (validateTrigger = {})); diff --git a/dist/es2017/validation-controller-factory.d.ts b/dist/es2017/validation-controller-factory.d.ts deleted file mode 100644 index 2c51999e..00000000 --- a/dist/es2017/validation-controller-factory.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Container } from 'aurelia-dependency-injection'; -import { ValidationController } from './validation-controller'; -import { Validator } from './validator'; -/** - * Creates ValidationController instances. - */ -export declare class ValidationControllerFactory { - private container; - static get(container: Container): ValidationControllerFactory; - constructor(container: Container); - /** - * Creates a new controller instance. - */ - create(validator?: Validator): ValidationController; - /** - * Creates a new controller and registers it in the current element's container so that it's - * available to the validate binding behavior and renderers. - */ - createForCurrentScope(validator?: Validator): ValidationController; -} diff --git a/dist/es2017/validation-controller-factory.js b/dist/es2017/validation-controller-factory.js deleted file mode 100644 index b2e86933..00000000 --- a/dist/es2017/validation-controller-factory.js +++ /dev/null @@ -1,34 +0,0 @@ -import { ValidationController } from './validation-controller'; -import { Validator } from './validator'; -import { PropertyAccessorParser } from './property-accessor-parser'; -/** - * Creates ValidationController instances. - */ -export class ValidationControllerFactory { - constructor(container) { - this.container = container; - } - static get(container) { - return new ValidationControllerFactory(container); - } - /** - * Creates a new controller instance. - */ - create(validator) { - if (!validator) { - validator = this.container.get(Validator); - } - const propertyParser = this.container.get(PropertyAccessorParser); - return new ValidationController(validator, propertyParser); - } - /** - * Creates a new controller and registers it in the current element's container so that it's - * available to the validate binding behavior and renderers. - */ - createForCurrentScope(validator) { - const controller = this.create(validator); - this.container.registerInstance(ValidationController, controller); - return controller; - } -} -ValidationControllerFactory['protocol:aurelia:resolver'] = true; diff --git a/dist/es2017/validation-controller.d.ts b/dist/es2017/validation-controller.d.ts deleted file mode 100644 index 7f208d49..00000000 --- a/dist/es2017/validation-controller.d.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { Binding } from 'aurelia-binding'; -import { Validator } from './validator'; -import { validateTrigger } from './validate-trigger'; -import { ValidationRenderer } from './validation-renderer'; -import { ValidateResult } from './validate-result'; -import { ValidateInstruction } from './validate-instruction'; -import { ControllerValidateResult } from './controller-validate-result'; -import { PropertyAccessorParser, PropertyAccessor } from './property-accessor-parser'; -import { ValidateEvent } from './validate-event'; -/** - * Orchestrates validation. - * Manages a set of bindings, renderers and objects. - * Exposes the current list of validation results for binding purposes. - */ -export declare class ValidationController { - private validator; - private propertyParser; - static inject: (typeof PropertyAccessorParser | typeof Validator)[]; - private bindings; - private renderers; - /** - * Validation results that have been rendered by the controller. - */ - private results; - /** - * Validation errors that have been rendered by the controller. - */ - errors: ValidateResult[]; - /** - * Whether the controller is currently validating. - */ - validating: boolean; - private elements; - private objects; - /** - * The trigger that will invoke automatic validation of a property used in a binding. - */ - validateTrigger: validateTrigger; - private finishValidating; - private eventCallbacks; - constructor(validator: Validator, propertyParser: PropertyAccessorParser); - /** - * Subscribe to controller validate and reset events. These events occur when the - * controller's "validate"" and "reset" methods are called. - * @param callback The callback to be invoked when the controller validates or resets. - */ - subscribe(callback: (event: ValidateEvent) => void): { - dispose: () => void; - }; - /** - * Adds an object to the set of objects that should be validated when validate is called. - * @param object The object. - * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. - */ - addObject(object: any, rules?: any): void; - /** - * Removes an object from the set of objects that should be validated when validate is called. - * @param object The object. - */ - removeObject(object: any): void; - /** - * Adds and renders an error. - */ - addError(message: string, object: TObject, propertyName?: string | PropertyAccessor | null): ValidateResult; - /** - * Removes and unrenders an error. - */ - removeError(result: ValidateResult): void; - /** - * Adds a renderer. - * @param renderer The renderer. - */ - addRenderer(renderer: ValidationRenderer): void; - /** - * Removes a renderer. - * @param renderer The renderer. - */ - removeRenderer(renderer: ValidationRenderer): void; - /** - * Registers a binding with the controller. - * @param binding The binding instance. - * @param target The DOM element. - * @param rules (optional) rules associated with the binding. Validator implementation specific. - */ - registerBinding(binding: Binding, target: Element, rules?: any): void; - /** - * Unregisters a binding with the controller. - * @param binding The binding instance. - */ - unregisterBinding(binding: Binding): void; - /** - * Interprets the instruction and returns a predicate that will identify - * relevant results in the list of rendered validation results. - */ - private getInstructionPredicate(instruction?); - /** - * Validates and renders results. - * @param instruction Optional. Instructions on what to validate. If undefined, all - * objects and bindings will be validated. - */ - validate(instruction?: ValidateInstruction): Promise; - /** - * Resets any rendered validation results (unrenders). - * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results - * will be unrendered. - */ - reset(instruction?: ValidateInstruction): void; - /** - * Gets the elements associated with an object and propertyName (if any). - */ - private getAssociatedElements({object, propertyName}); - private processResultDelta(kind, oldResults, newResults); - /** - * Validates the property associated with a binding. - */ - validateBinding(binding: Binding): void; - /** - * Resets the results for a property associated with a binding. - */ - resetBinding(binding: Binding): void; - /** - * Changes the controller's validateTrigger. - * @param newTrigger The new validateTrigger - */ - changeTrigger(newTrigger: validateTrigger): void; - /** - * Revalidates the controller's current set of errors. - */ - revalidateErrors(): void; - private invokeCallbacks(instruction, result); -} diff --git a/dist/es2017/validation-controller.js b/dist/es2017/validation-controller.js deleted file mode 100644 index 2428a303..00000000 --- a/dist/es2017/validation-controller.js +++ /dev/null @@ -1,392 +0,0 @@ -import { Validator } from './validator'; -import { validateTrigger } from './validate-trigger'; -import { getPropertyInfo } from './property-info'; -import { ValidateResult } from './validate-result'; -import { PropertyAccessorParser } from './property-accessor-parser'; -import { ValidateEvent } from './validate-event'; -/** - * Orchestrates validation. - * Manages a set of bindings, renderers and objects. - * Exposes the current list of validation results for binding purposes. - */ -export class ValidationController { - constructor(validator, propertyParser) { - this.validator = validator; - this.propertyParser = propertyParser; - // Registered bindings (via the validate binding behavior) - this.bindings = new Map(); - // Renderers that have been added to the controller instance. - this.renderers = []; - /** - * Validation results that have been rendered by the controller. - */ - this.results = []; - /** - * Validation errors that have been rendered by the controller. - */ - this.errors = []; - /** - * Whether the controller is currently validating. - */ - this.validating = false; - // Elements related to validation results that have been rendered. - this.elements = new Map(); - // Objects that have been added to the controller instance (entity-style validation). - this.objects = new Map(); - /** - * The trigger that will invoke automatic validation of a property used in a binding. - */ - this.validateTrigger = validateTrigger.blur; - // Promise that resolves when validation has completed. - this.finishValidating = Promise.resolve(); - this.eventCallbacks = []; - } - /** - * Subscribe to controller validate and reset events. These events occur when the - * controller's "validate"" and "reset" methods are called. - * @param callback The callback to be invoked when the controller validates or resets. - */ - subscribe(callback) { - this.eventCallbacks.push(callback); - return { - dispose: () => { - const index = this.eventCallbacks.indexOf(callback); - if (index === -1) { - return; - } - this.eventCallbacks.splice(index, 1); - } - }; - } - /** - * Adds an object to the set of objects that should be validated when validate is called. - * @param object The object. - * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. - */ - addObject(object, rules) { - this.objects.set(object, rules); - } - /** - * Removes an object from the set of objects that should be validated when validate is called. - * @param object The object. - */ - removeObject(object) { - this.objects.delete(object); - this.processResultDelta('reset', this.results.filter(result => result.object === object), []); - } - /** - * Adds and renders an error. - */ - addError(message, object, propertyName = null) { - let resolvedPropertyName; - if (propertyName === null) { - resolvedPropertyName = propertyName; - } - else { - resolvedPropertyName = this.propertyParser.parse(propertyName); - } - const result = new ValidateResult({ __manuallyAdded__: true }, object, resolvedPropertyName, false, message); - this.processResultDelta('validate', [], [result]); - return result; - } - /** - * Removes and unrenders an error. - */ - removeError(result) { - if (this.results.indexOf(result) !== -1) { - this.processResultDelta('reset', [result], []); - } - } - /** - * Adds a renderer. - * @param renderer The renderer. - */ - addRenderer(renderer) { - this.renderers.push(renderer); - renderer.render({ - kind: 'validate', - render: this.results.map(result => ({ result, elements: this.elements.get(result) })), - unrender: [] - }); - } - /** - * Removes a renderer. - * @param renderer The renderer. - */ - removeRenderer(renderer) { - this.renderers.splice(this.renderers.indexOf(renderer), 1); - renderer.render({ - kind: 'reset', - render: [], - unrender: this.results.map(result => ({ result, elements: this.elements.get(result) })) - }); - } - /** - * Registers a binding with the controller. - * @param binding The binding instance. - * @param target The DOM element. - * @param rules (optional) rules associated with the binding. Validator implementation specific. - */ - registerBinding(binding, target, rules) { - this.bindings.set(binding, { target, rules, propertyInfo: null }); - } - /** - * Unregisters a binding with the controller. - * @param binding The binding instance. - */ - unregisterBinding(binding) { - this.resetBinding(binding); - this.bindings.delete(binding); - } - /** - * Interprets the instruction and returns a predicate that will identify - * relevant results in the list of rendered validation results. - */ - getInstructionPredicate(instruction) { - if (instruction) { - const { object, propertyName, rules } = instruction; - let predicate; - if (instruction.propertyName) { - predicate = x => x.object === object && x.propertyName === propertyName; - } - else { - predicate = x => x.object === object; - } - if (rules) { - return x => predicate(x) && this.validator.ruleExists(rules, x.rule); - } - return predicate; - } - else { - return () => true; - } - } - /** - * Validates and renders results. - * @param instruction Optional. Instructions on what to validate. If undefined, all - * objects and bindings will be validated. - */ - validate(instruction) { - // Get a function that will process the validation instruction. - let execute; - if (instruction) { - // tslint:disable-next-line:prefer-const - let { object, propertyName, rules } = instruction; - // if rules were not specified, check the object map. - rules = rules || this.objects.get(object); - // property specified? - if (instruction.propertyName === undefined) { - // validate the specified object. - execute = () => this.validator.validateObject(object, rules); - } - else { - // validate the specified property. - execute = () => this.validator.validateProperty(object, propertyName, rules); - } - } - else { - // validate all objects and bindings. - execute = () => { - const promises = []; - for (const [object, rules] of Array.from(this.objects)) { - promises.push(this.validator.validateObject(object, rules)); - } - for (const [binding, { rules }] of Array.from(this.bindings)) { - const propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); - if (!propertyInfo || this.objects.has(propertyInfo.object)) { - continue; - } - promises.push(this.validator.validateProperty(propertyInfo.object, propertyInfo.propertyName, rules)); - } - return Promise.all(promises).then(resultSets => resultSets.reduce((a, b) => a.concat(b), [])); - }; - } - // Wait for any existing validation to finish, execute the instruction, render the results. - this.validating = true; - const returnPromise = this.finishValidating - .then(execute) - .then((newResults) => { - const predicate = this.getInstructionPredicate(instruction); - const oldResults = this.results.filter(predicate); - this.processResultDelta('validate', oldResults, newResults); - if (returnPromise === this.finishValidating) { - this.validating = false; - } - const result = { - instruction, - valid: newResults.find(x => !x.valid) === undefined, - results: newResults - }; - this.invokeCallbacks(instruction, result); - return result; - }) - .catch(exception => { - // recover, to enable subsequent calls to validate() - this.validating = false; - this.finishValidating = Promise.resolve(); - return Promise.reject(exception); - }); - this.finishValidating = returnPromise; - return returnPromise; - } - /** - * Resets any rendered validation results (unrenders). - * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results - * will be unrendered. - */ - reset(instruction) { - const predicate = this.getInstructionPredicate(instruction); - const oldResults = this.results.filter(predicate); - this.processResultDelta('reset', oldResults, []); - this.invokeCallbacks(instruction, null); - } - /** - * Gets the elements associated with an object and propertyName (if any). - */ - getAssociatedElements({ object, propertyName }) { - const elements = []; - for (const [binding, { target }] of Array.from(this.bindings)) { - const propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); - if (propertyInfo && propertyInfo.object === object && propertyInfo.propertyName === propertyName) { - elements.push(target); - } - } - return elements; - } - processResultDelta(kind, oldResults, newResults) { - // prepare the instruction. - const instruction = { - kind, - render: [], - unrender: [] - }; - // create a shallow copy of newResults so we can mutate it without causing side-effects. - newResults = newResults.slice(0); - // create unrender instructions from the old results. - for (const oldResult of oldResults) { - // get the elements associated with the old result. - const elements = this.elements.get(oldResult); - // remove the old result from the element map. - this.elements.delete(oldResult); - // create the unrender instruction. - instruction.unrender.push({ result: oldResult, elements }); - // determine if there's a corresponding new result for the old result we are unrendering. - const newResultIndex = newResults.findIndex(x => x.rule === oldResult.rule && x.object === oldResult.object && x.propertyName === oldResult.propertyName); - if (newResultIndex === -1) { - // no corresponding new result... simple remove. - this.results.splice(this.results.indexOf(oldResult), 1); - if (!oldResult.valid) { - this.errors.splice(this.errors.indexOf(oldResult), 1); - } - } - else { - // there is a corresponding new result... - const newResult = newResults.splice(newResultIndex, 1)[0]; - // get the elements that are associated with the new result. - const elements = this.getAssociatedElements(newResult); - this.elements.set(newResult, elements); - // create a render instruction for the new result. - instruction.render.push({ result: newResult, elements }); - // do an in-place replacement of the old result with the new result. - // this ensures any repeats bound to this.results will not thrash. - this.results.splice(this.results.indexOf(oldResult), 1, newResult); - if (!oldResult.valid && newResult.valid) { - this.errors.splice(this.errors.indexOf(oldResult), 1); - } - else if (!oldResult.valid && !newResult.valid) { - this.errors.splice(this.errors.indexOf(oldResult), 1, newResult); - } - else if (!newResult.valid) { - this.errors.push(newResult); - } - } - } - // create render instructions from the remaining new results. - for (const result of newResults) { - const elements = this.getAssociatedElements(result); - instruction.render.push({ result, elements }); - this.elements.set(result, elements); - this.results.push(result); - if (!result.valid) { - this.errors.push(result); - } - } - // render. - for (const renderer of this.renderers) { - renderer.render(instruction); - } - } - /** - * Validates the property associated with a binding. - */ - validateBinding(binding) { - if (!binding.isBound) { - return; - } - const propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); - let rules; - const registeredBinding = this.bindings.get(binding); - if (registeredBinding) { - rules = registeredBinding.rules; - registeredBinding.propertyInfo = propertyInfo; - } - if (!propertyInfo) { - return; - } - const { object, propertyName } = propertyInfo; - this.validate({ object, propertyName, rules }); - } - /** - * Resets the results for a property associated with a binding. - */ - resetBinding(binding) { - const registeredBinding = this.bindings.get(binding); - let propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); - if (!propertyInfo && registeredBinding) { - propertyInfo = registeredBinding.propertyInfo; - } - if (registeredBinding) { - registeredBinding.propertyInfo = null; - } - if (!propertyInfo) { - return; - } - const { object, propertyName } = propertyInfo; - this.reset({ object, propertyName }); - } - /** - * Changes the controller's validateTrigger. - * @param newTrigger The new validateTrigger - */ - changeTrigger(newTrigger) { - this.validateTrigger = newTrigger; - const bindings = Array.from(this.bindings.keys()); - for (const binding of bindings) { - const source = binding.source; - binding.unbind(); - binding.bind(source); - } - } - /** - * Revalidates the controller's current set of errors. - */ - revalidateErrors() { - for (const { object, propertyName, rule } of this.errors) { - if (rule.__manuallyAdded__) { - continue; - } - const rules = [[rule]]; - this.validate({ object, propertyName, rules }); - } - } - invokeCallbacks(instruction, result) { - if (this.eventCallbacks.length === 0) { - return; - } - const event = new ValidateEvent(result ? 'validate' : 'reset', this.errors, this.results, instruction || null, result); - for (let i = 0; i < this.eventCallbacks.length; i++) { - this.eventCallbacks[i](event); - } - } -} -ValidationController.inject = [Validator, PropertyAccessorParser]; diff --git a/dist/es2017/validation-errors-custom-attribute.d.ts b/dist/es2017/validation-errors-custom-attribute.d.ts deleted file mode 100644 index 056e08ea..00000000 --- a/dist/es2017/validation-errors-custom-attribute.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Lazy } from 'aurelia-dependency-injection'; -import { ValidationController } from './validation-controller'; -import { ValidateResult } from './validate-result'; -import { ValidationRenderer, RenderInstruction } from './validation-renderer'; -export interface RenderedError { - error: ValidateResult; - targets: Element[]; -} -export declare class ValidationErrorsCustomAttribute implements ValidationRenderer { - private boundaryElement; - private controllerAccessor; - static inject(): ({ - new (): Element; - prototype: Element; - } | Lazy)[]; - controller: ValidationController | null; - errors: RenderedError[]; - private errorsInternal; - constructor(boundaryElement: Element, controllerAccessor: () => ValidationController); - sort(): void; - interestingElements(elements: Element[]): Element[]; - render(instruction: RenderInstruction): void; - bind(): void; - unbind(): void; -} diff --git a/dist/es2017/validation-errors-custom-attribute.js b/dist/es2017/validation-errors-custom-attribute.js deleted file mode 100644 index c6af963f..00000000 --- a/dist/es2017/validation-errors-custom-attribute.js +++ /dev/null @@ -1,74 +0,0 @@ -var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -}; -import { bindingMode } from 'aurelia-binding'; -import { Lazy } from 'aurelia-dependency-injection'; -import { customAttribute, bindable } from 'aurelia-templating'; -import { ValidationController } from './validation-controller'; -import { DOM } from 'aurelia-pal'; -let ValidationErrorsCustomAttribute = class ValidationErrorsCustomAttribute { - constructor(boundaryElement, controllerAccessor) { - this.boundaryElement = boundaryElement; - this.controllerAccessor = controllerAccessor; - this.controller = null; - this.errors = []; - this.errorsInternal = []; - } - static inject() { return [DOM.Element, Lazy.of(ValidationController)]; } - sort() { - this.errorsInternal.sort((a, b) => { - if (a.targets[0] === b.targets[0]) { - return 0; - } - // tslint:disable-next-line:no-bitwise - return a.targets[0].compareDocumentPosition(b.targets[0]) & 2 ? 1 : -1; - }); - } - interestingElements(elements) { - return elements.filter(e => this.boundaryElement.contains(e)); - } - render(instruction) { - for (const { result } of instruction.unrender) { - const index = this.errorsInternal.findIndex(x => x.error === result); - if (index !== -1) { - this.errorsInternal.splice(index, 1); - } - } - for (const { result, elements } of instruction.render) { - if (result.valid) { - continue; - } - const targets = this.interestingElements(elements); - if (targets.length) { - this.errorsInternal.push({ error: result, targets }); - } - } - this.sort(); - this.errors = this.errorsInternal; - } - bind() { - if (!this.controller) { - this.controller = this.controllerAccessor(); - } - // this will call render() with the side-effect of updating this.errors - this.controller.addRenderer(this); - } - unbind() { - if (this.controller) { - this.controller.removeRenderer(this); - } - } -}; -__decorate([ - bindable({ defaultBindingMode: bindingMode.oneWay }) -], ValidationErrorsCustomAttribute.prototype, "controller", void 0); -__decorate([ - bindable({ primaryProperty: true, defaultBindingMode: bindingMode.twoWay }) -], ValidationErrorsCustomAttribute.prototype, "errors", void 0); -ValidationErrorsCustomAttribute = __decorate([ - customAttribute('validation-errors') -], ValidationErrorsCustomAttribute); -export { ValidationErrorsCustomAttribute }; diff --git a/dist/es2017/validation-renderer-custom-attribute.d.ts b/dist/es2017/validation-renderer-custom-attribute.d.ts deleted file mode 100644 index 9f48614e..00000000 --- a/dist/es2017/validation-renderer-custom-attribute.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export declare class ValidationRendererCustomAttribute { - private container; - private controller; - private value; - private renderer; - created(view: any): void; - bind(): void; - unbind(): void; -} diff --git a/dist/es2017/validation-renderer-custom-attribute.js b/dist/es2017/validation-renderer-custom-attribute.js deleted file mode 100644 index 83b6c5d4..00000000 --- a/dist/es2017/validation-renderer-custom-attribute.js +++ /dev/null @@ -1,16 +0,0 @@ -import { ValidationController } from './validation-controller'; -export class ValidationRendererCustomAttribute { - created(view) { - this.container = view.container; - } - bind() { - this.controller = this.container.get(ValidationController); - this.renderer = this.container.get(this.value); - this.controller.addRenderer(this.renderer); - } - unbind() { - this.controller.removeRenderer(this.renderer); - this.controller = null; - this.renderer = null; - } -} diff --git a/dist/es2017/validation-renderer.d.ts b/dist/es2017/validation-renderer.d.ts deleted file mode 100644 index eb430d9d..00000000 --- a/dist/es2017/validation-renderer.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { ValidateResult } from './validate-result'; -/** - * A result to render (or unrender) and the associated elements (if any) - */ -export interface ResultInstruction { - /** - * The validation result. - */ - result: ValidateResult; - /** - * The associated elements (if any). - */ - elements: Element[]; -} -/** - * Defines which validation results to render and which validation results to unrender. - */ -export interface RenderInstruction { - /** - * The "kind" of render instruction. Either 'validate' or 'reset'. - */ - kind: 'validate' | 'reset'; - /** - * The results to render. - */ - render: ResultInstruction[]; - /** - * The results to unrender. - */ - unrender: ResultInstruction[]; -} -/** - * Renders validation results. - */ -export interface ValidationRenderer { - /** - * Render the validation results. - * @param instruction The render instruction. Defines which results to render and which - * results to unrender. - */ - render(instruction: RenderInstruction): void; -} diff --git a/dist/es2017/validation-renderer.js b/dist/es2017/validation-renderer.js deleted file mode 100644 index e69de29b..00000000 diff --git a/dist/es2017/validator.d.ts b/dist/es2017/validator.d.ts deleted file mode 100644 index 82c045e8..00000000 --- a/dist/es2017/validator.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ValidateResult } from './validate-result'; -/** - * Validates objects and properties. - */ -export declare abstract class Validator { - /** - * Validates the specified property. - * @param object The object to validate. - * @param propertyName The name of the property to validate. - * @param rules Optional. If unspecified, the implementation should lookup the rules for the - * specified object. This may not be possible for all implementations of this interface. - */ - abstract validateProperty(object: any, propertyName: string, rules?: any): Promise; - /** - * Validates all rules for specified object and it's properties. - * @param object The object to validate. - * @param rules Optional. If unspecified, the implementation should lookup the rules for the - * specified object. This may not be possible for all implementations of this interface. - */ - abstract validateObject(object: any, rules?: any): Promise; - /** - * Determines whether a rule exists in a set of rules. - * @param rules The rules to search. - * @parem rule The rule to find. - */ - abstract ruleExists(rules: any, rule: any): boolean; -} diff --git a/dist/es2017/validator.js b/dist/es2017/validator.js deleted file mode 100644 index 2fd07a54..00000000 --- a/dist/es2017/validator.js +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Validates objects and properties. - */ -export class Validator { -} diff --git a/dist/native-modules/aurelia-validation.d.ts b/dist/native-modules/aurelia-validation.d.ts deleted file mode 100644 index d744ccfb..00000000 --- a/dist/native-modules/aurelia-validation.d.ts +++ /dev/null @@ -1,46 +0,0 @@ -export * from './controller-validate-result'; -export * from './get-target-dom-element'; -export * from './property-info'; -export * from './property-accessor-parser'; -export * from './validate-binding-behavior'; -export * from './validate-event'; -export * from './validate-instruction'; -export * from './validate-result'; -export * from './validate-trigger'; -export * from './validation-controller'; -export * from './validation-controller-factory'; -export * from './validation-errors-custom-attribute'; -export * from './validation-renderer-custom-attribute'; -export * from './validation-renderer'; -export * from './validator'; -export * from './implementation/rule'; -export * from './implementation/rules'; -export * from './implementation/standard-validator'; -export * from './implementation/validation-messages'; -export * from './implementation/validation-message-parser'; -export * from './implementation/validation-rules'; -import { Container } from 'aurelia-dependency-injection'; -import { Validator } from './validator'; -/** - * Aurelia Validation Configuration API - */ -export declare class AureliaValidationConfiguration { - private validatorType; - /** - * Use a custom Validator implementation. - */ - customValidator(type: { - new (...args: any[]): Validator; - }): void; - /** - * Applies the configuration. - */ - apply(container: Container): void; -} -/** - * Configures the plugin. - */ -export declare function configure(frameworkConfig: { - container: Container; - globalResources?: (...resources: string[]) => any; -}, callback?: (config: AureliaValidationConfiguration) => void): void; diff --git a/dist/native-modules/aurelia-validation.js b/dist/native-modules/aurelia-validation.js index 4833094a..23393ce7 100644 --- a/dist/native-modules/aurelia-validation.js +++ b/dist/native-modules/aurelia-validation.js @@ -1,68 +1,1772 @@ -// Exports -export * from './get-target-dom-element'; -export * from './property-info'; -export * from './property-accessor-parser'; -export * from './validate-binding-behavior'; -export * from './validate-event'; -export * from './validate-result'; -export * from './validate-trigger'; -export * from './validation-controller'; -export * from './validation-controller-factory'; -export * from './validation-errors-custom-attribute'; -export * from './validation-renderer-custom-attribute'; -export * from './validator'; -export * from './implementation/rules'; -export * from './implementation/standard-validator'; -export * from './implementation/validation-messages'; -export * from './implementation/validation-message-parser'; -export * from './implementation/validation-rules'; -// Configuration -import { PLATFORM } from 'aurelia-pal'; -import { Validator } from './validator'; -import { StandardValidator } from './implementation/standard-validator'; -import { ValidationMessageParser } from './implementation/validation-message-parser'; -import { PropertyAccessorParser } from './property-accessor-parser'; -import { ValidationRules } from './implementation/validation-rules'; -/** - * Aurelia Validation Configuration API - */ -var AureliaValidationConfiguration = /** @class */ (function () { - function AureliaValidationConfiguration() { - this.validatorType = StandardValidator; - } - /** - * Use a custom Validator implementation. - */ - AureliaValidationConfiguration.prototype.customValidator = function (type) { - this.validatorType = type; - }; - /** - * Applies the configuration. - */ - AureliaValidationConfiguration.prototype.apply = function (container) { - var validator = container.get(this.validatorType); - container.registerInstance(Validator, validator); - }; - return AureliaValidationConfiguration; +import { DOM } from 'aurelia-pal'; +import { AccessMember, AccessScope, AccessKeyed, BindingBehavior, ValueConverter, getContextFor, Parser, bindingMode, LiteralString, Binary, Conditional, LiteralPrimitive, CallMember } from 'aurelia-binding'; +import { Optional, Lazy } from 'aurelia-dependency-injection'; +import { TaskQueue } from 'aurelia-task-queue'; +import { customAttribute, bindable, BindingLanguage, ViewResources } from 'aurelia-templating'; +import { customAttribute as customAttribute$1 } from 'aurelia-framework'; +import { getLogger } from 'aurelia-logging'; + +/** + * Gets the DOM element associated with the data-binding. Most of the time it's + * the binding.target but sometimes binding.target is an aurelia custom element, + * or custom attribute which is a javascript "class" instance, so we need to use + * the controller's container to retrieve the actual DOM element. + */ +function getTargetDOMElement(binding, view) { + var target = binding.target; + // DOM element + if (target instanceof Element) { + return target; + } + // custom element or custom attribute + // tslint:disable-next-line:prefer-const + for (var i = 0, ii = view.controllers.length; i < ii; i++) { + var controller = view.controllers[i]; + if (controller.viewModel === target) { + var element = controller.container.get(DOM.Element); + if (element) { + return element; + } + throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\"."); + } + } + throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\"."); +} + +function getObject(expression, objectExpression, source) { + var value = objectExpression.evaluate(source, null); + if (value === null || value === undefined || value instanceof Object) { + return value; + } + // tslint:disable-next-line:max-line-length + throw new Error("The '" + objectExpression + "' part of '" + expression + "' evaluates to " + value + " instead of an object, null or undefined."); +} +/** + * Retrieves the object and property name for the specified expression. + * @param expression The expression + * @param source The scope + */ +function getPropertyInfo(expression, source) { + var originalExpression = expression; + while (expression instanceof BindingBehavior || expression instanceof ValueConverter) { + expression = expression.expression; + } + var object; + var propertyName; + if (expression instanceof AccessScope) { + object = getContextFor(expression.name, source, expression.ancestor); + propertyName = expression.name; + } + else if (expression instanceof AccessMember) { + object = getObject(originalExpression, expression.object, source); + propertyName = expression.name; + } + else if (expression instanceof AccessKeyed) { + object = getObject(originalExpression, expression.object, source); + propertyName = expression.key.evaluate(source); + } + else { + throw new Error("Expression '" + originalExpression + "' is not compatible with the validate binding-behavior."); + } + if (object === null || object === undefined) { + return null; + } + return { object: object, propertyName: propertyName }; +} + +function isString(value) { + return Object.prototype.toString.call(value) === '[object String]'; +} +function isNumber(value) { + return Object.prototype.toString.call(value) === '[object Number]'; +} + +var PropertyAccessorParser = /** @class */ (function () { + function PropertyAccessorParser(parser) { + this.parser = parser; + } + PropertyAccessorParser.prototype.parse = function (property) { + if (isString(property) || isNumber(property)) { + return property; + } + var accessorText = getAccessorExpression(property.toString()); + var accessor = this.parser.parse(accessorText); + if (accessor instanceof AccessScope + || accessor instanceof AccessMember && accessor.object instanceof AccessScope) { + return accessor.name; + } + throw new Error("Invalid property expression: \"" + accessor + "\""); + }; + PropertyAccessorParser.inject = [Parser]; + return PropertyAccessorParser; +}()); +function getAccessorExpression(fn) { + /* tslint:disable:max-line-length */ + var classic = /^function\s*\([$_\w\d]+\)\s*\{(?:\s*"use strict";)?\s*(?:[$_\w\d.['"\]+;]+)?\s*return\s+[$_\w\d]+\.([$_\w\d]+)\s*;?\s*\}$/; + /* tslint:enable:max-line-length */ + var arrow = /^\(?[$_\w\d]+\)?\s*=>\s*[$_\w\d]+\.([$_\w\d]+)$/; + var match = classic.exec(fn) || arrow.exec(fn); + if (match === null) { + throw new Error("Unable to parse accessor function:\n" + fn); + } + return match[1]; +} + +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at http://www.apache.org/licenses/LICENSE-2.0 + +THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED +WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +MERCHANTABLITY OR NON-INFRINGEMENT. + +See the Apache Version 2.0 License for specific language governing permissions +and limitations under the License. +***************************************************************************** */ +/* global Reflect, Promise */ + +var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); +}; + +function __extends(d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} + +function __decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +} + +/** + * Validation triggers. + */ +var validateTrigger; +(function (validateTrigger) { + /** + * Manual validation. Use the controller's `validate()` and `reset()` methods + * to validate all bindings. + */ + validateTrigger[validateTrigger["manual"] = 0] = "manual"; + /** + * Validate the binding when the binding's target element fires a DOM "blur" event. + */ + validateTrigger[validateTrigger["blur"] = 1] = "blur"; + /** + * Validate the binding when it updates the model due to a change in the view. + */ + validateTrigger[validateTrigger["change"] = 2] = "change"; + /** + * Validate the binding when the binding's target element fires a DOM "blur" event and + * when it updates the model due to a change in the view. + */ + validateTrigger[validateTrigger["changeOrBlur"] = 3] = "changeOrBlur"; +})(validateTrigger || (validateTrigger = {})); + +/** + * Validates objects and properties. + */ +var Validator = /** @class */ (function () { + function Validator() { + } + return Validator; +}()); + +/** + * The result of validating an individual validation rule. + */ +var ValidateResult = /** @class */ (function () { + /** + * @param rule The rule associated with the result. Validator implementation specific. + * @param object The object that was validated. + * @param propertyName The name of the property that was validated. + * @param error The error, if the result is a validation error. + */ + function ValidateResult(rule, object, propertyName, valid, message) { + if (message === void 0) { message = null; } + this.rule = rule; + this.object = object; + this.propertyName = propertyName; + this.valid = valid; + this.message = message; + this.id = ValidateResult.nextId++; + } + ValidateResult.prototype.toString = function () { + return this.valid ? 'Valid.' : this.message; + }; + ValidateResult.nextId = 0; + return ValidateResult; +}()); + +var ValidateEvent = /** @class */ (function () { + function ValidateEvent( + /** + * The type of validate event. Either "validate" or "reset". + */ + type, + /** + * The controller's current array of errors. For an array containing both + * failed rules and passed rules, use the "results" property. + */ + errors, + /** + * The controller's current array of validate results. This + * includes both passed rules and failed rules. For an array of only failed rules, + * use the "errors" property. + */ + results, + /** + * The instruction passed to the "validate" or "reset" event. Will be null when + * the controller's validate/reset method was called with no instruction argument. + */ + instruction, + /** + * In events with type === "validate", this property will contain the result + * of validating the instruction (see "instruction" property). Use the controllerValidateResult + * to access the validate results specific to the call to "validate" + * (as opposed to using the "results" and "errors" properties to access the controller's entire + * set of results/errors). + */ + controllerValidateResult) { + this.type = type; + this.errors = errors; + this.results = results; + this.instruction = instruction; + this.controllerValidateResult = controllerValidateResult; + } + return ValidateEvent; +}()); + +/** + * Orchestrates validation. + * Manages a set of bindings, renderers and objects. + * Exposes the current list of validation results for binding purposes. + */ +var ValidationController = /** @class */ (function () { + function ValidationController(validator, propertyParser) { + this.validator = validator; + this.propertyParser = propertyParser; + // Registered bindings (via the validate binding behavior) + this.bindings = new Map(); + // Renderers that have been added to the controller instance. + this.renderers = []; + /** + * Validation results that have been rendered by the controller. + */ + this.results = []; + /** + * Validation errors that have been rendered by the controller. + */ + this.errors = []; + /** + * Whether the controller is currently validating. + */ + this.validating = false; + // Elements related to validation results that have been rendered. + this.elements = new Map(); + // Objects that have been added to the controller instance (entity-style validation). + this.objects = new Map(); + /** + * The trigger that will invoke automatic validation of a property used in a binding. + */ + this.validateTrigger = validateTrigger.blur; + // Promise that resolves when validation has completed. + this.finishValidating = Promise.resolve(); + this.eventCallbacks = []; + } + /** + * Subscribe to controller validate and reset events. These events occur when the + * controller's "validate"" and "reset" methods are called. + * @param callback The callback to be invoked when the controller validates or resets. + */ + ValidationController.prototype.subscribe = function (callback) { + var _this = this; + this.eventCallbacks.push(callback); + return { + dispose: function () { + var index = _this.eventCallbacks.indexOf(callback); + if (index === -1) { + return; + } + _this.eventCallbacks.splice(index, 1); + } + }; + }; + /** + * Adds an object to the set of objects that should be validated when validate is called. + * @param object The object. + * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. + */ + ValidationController.prototype.addObject = function (object, rules) { + this.objects.set(object, rules); + }; + /** + * Removes an object from the set of objects that should be validated when validate is called. + * @param object The object. + */ + ValidationController.prototype.removeObject = function (object) { + this.objects.delete(object); + this.processResultDelta('reset', this.results.filter(function (result) { return result.object === object; }), []); + }; + /** + * Adds and renders an error. + */ + ValidationController.prototype.addError = function (message, object, propertyName) { + if (propertyName === void 0) { propertyName = null; } + var resolvedPropertyName; + if (propertyName === null) { + resolvedPropertyName = propertyName; + } + else { + resolvedPropertyName = this.propertyParser.parse(propertyName); + } + var result = new ValidateResult({ __manuallyAdded__: true }, object, resolvedPropertyName, false, message); + this.processResultDelta('validate', [], [result]); + return result; + }; + /** + * Removes and unrenders an error. + */ + ValidationController.prototype.removeError = function (result) { + if (this.results.indexOf(result) !== -1) { + this.processResultDelta('reset', [result], []); + } + }; + /** + * Adds a renderer. + * @param renderer The renderer. + */ + ValidationController.prototype.addRenderer = function (renderer) { + var _this = this; + this.renderers.push(renderer); + renderer.render({ + kind: 'validate', + render: this.results.map(function (result) { return ({ result: result, elements: _this.elements.get(result) }); }), + unrender: [] + }); + }; + /** + * Removes a renderer. + * @param renderer The renderer. + */ + ValidationController.prototype.removeRenderer = function (renderer) { + var _this = this; + this.renderers.splice(this.renderers.indexOf(renderer), 1); + renderer.render({ + kind: 'reset', + render: [], + unrender: this.results.map(function (result) { return ({ result: result, elements: _this.elements.get(result) }); }) + }); + }; + /** + * Registers a binding with the controller. + * @param binding The binding instance. + * @param target The DOM element. + * @param rules (optional) rules associated with the binding. Validator implementation specific. + */ + ValidationController.prototype.registerBinding = function (binding, target, rules) { + this.bindings.set(binding, { target: target, rules: rules, propertyInfo: null }); + }; + /** + * Unregisters a binding with the controller. + * @param binding The binding instance. + */ + ValidationController.prototype.unregisterBinding = function (binding) { + this.resetBinding(binding); + this.bindings.delete(binding); + }; + /** + * Interprets the instruction and returns a predicate that will identify + * relevant results in the list of rendered validation results. + */ + ValidationController.prototype.getInstructionPredicate = function (instruction) { + var _this = this; + if (instruction) { + var object_1 = instruction.object, propertyName_1 = instruction.propertyName, rules_1 = instruction.rules; + var predicate_1; + if (instruction.propertyName) { + predicate_1 = function (x) { return x.object === object_1 && x.propertyName === propertyName_1; }; + } + else { + predicate_1 = function (x) { return x.object === object_1; }; + } + if (rules_1) { + return function (x) { return predicate_1(x) && _this.validator.ruleExists(rules_1, x.rule); }; + } + return predicate_1; + } + else { + return function () { return true; }; + } + }; + /** + * Validates and renders results. + * @param instruction Optional. Instructions on what to validate. If undefined, all + * objects and bindings will be validated. + */ + ValidationController.prototype.validate = function (instruction) { + var _this = this; + // Get a function that will process the validation instruction. + var execute; + if (instruction) { + // tslint:disable-next-line:prefer-const + var object_2 = instruction.object, propertyName_2 = instruction.propertyName, rules_2 = instruction.rules; + // if rules were not specified, check the object map. + rules_2 = rules_2 || this.objects.get(object_2); + // property specified? + if (instruction.propertyName === undefined) { + // validate the specified object. + execute = function () { return _this.validator.validateObject(object_2, rules_2); }; + } + else { + // validate the specified property. + execute = function () { return _this.validator.validateProperty(object_2, propertyName_2, rules_2); }; + } + } + else { + // validate all objects and bindings. + execute = function () { + var promises = []; + for (var _i = 0, _a = Array.from(_this.objects); _i < _a.length; _i++) { + var _b = _a[_i], object = _b[0], rules = _b[1]; + promises.push(_this.validator.validateObject(object, rules)); + } + for (var _c = 0, _d = Array.from(_this.bindings); _c < _d.length; _c++) { + var _e = _d[_c], binding = _e[0], rules = _e[1].rules; + var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + if (!propertyInfo || _this.objects.has(propertyInfo.object)) { + continue; + } + promises.push(_this.validator.validateProperty(propertyInfo.object, propertyInfo.propertyName, rules)); + } + return Promise.all(promises).then(function (resultSets) { return resultSets.reduce(function (a, b) { return a.concat(b); }, []); }); + }; + } + // Wait for any existing validation to finish, execute the instruction, render the results. + this.validating = true; + var returnPromise = this.finishValidating + .then(execute) + .then(function (newResults) { + var predicate = _this.getInstructionPredicate(instruction); + var oldResults = _this.results.filter(predicate); + _this.processResultDelta('validate', oldResults, newResults); + if (returnPromise === _this.finishValidating) { + _this.validating = false; + } + var result = { + instruction: instruction, + valid: newResults.find(function (x) { return !x.valid; }) === undefined, + results: newResults + }; + _this.invokeCallbacks(instruction, result); + return result; + }) + .catch(function (exception) { + // recover, to enable subsequent calls to validate() + _this.validating = false; + _this.finishValidating = Promise.resolve(); + return Promise.reject(exception); + }); + this.finishValidating = returnPromise; + return returnPromise; + }; + /** + * Resets any rendered validation results (unrenders). + * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results + * will be unrendered. + */ + ValidationController.prototype.reset = function (instruction) { + var predicate = this.getInstructionPredicate(instruction); + var oldResults = this.results.filter(predicate); + this.processResultDelta('reset', oldResults, []); + this.invokeCallbacks(instruction, null); + }; + /** + * Gets the elements associated with an object and propertyName (if any). + */ + ValidationController.prototype.getAssociatedElements = function (_a) { + var object = _a.object, propertyName = _a.propertyName; + var elements = []; + for (var _i = 0, _b = Array.from(this.bindings); _i < _b.length; _i++) { + var _c = _b[_i], binding = _c[0], target = _c[1].target; + var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + if (propertyInfo && propertyInfo.object === object && propertyInfo.propertyName === propertyName) { + elements.push(target); + } + } + return elements; + }; + ValidationController.prototype.processResultDelta = function (kind, oldResults, newResults) { + // prepare the instruction. + var instruction = { + kind: kind, + render: [], + unrender: [] + }; + // create a shallow copy of newResults so we can mutate it without causing side-effects. + newResults = newResults.slice(0); + var _loop_1 = function (oldResult) { + // get the elements associated with the old result. + var elements = this_1.elements.get(oldResult); + // remove the old result from the element map. + this_1.elements.delete(oldResult); + // create the unrender instruction. + instruction.unrender.push({ result: oldResult, elements: elements }); + // determine if there's a corresponding new result for the old result we are unrendering. + var newResultIndex = newResults.findIndex(function (x) { return x.rule === oldResult.rule && x.object === oldResult.object && x.propertyName === oldResult.propertyName; }); + if (newResultIndex === -1) { + // no corresponding new result... simple remove. + this_1.results.splice(this_1.results.indexOf(oldResult), 1); + if (!oldResult.valid) { + this_1.errors.splice(this_1.errors.indexOf(oldResult), 1); + } + } + else { + // there is a corresponding new result... + var newResult = newResults.splice(newResultIndex, 1)[0]; + // get the elements that are associated with the new result. + var elements_1 = this_1.getAssociatedElements(newResult); + this_1.elements.set(newResult, elements_1); + // create a render instruction for the new result. + instruction.render.push({ result: newResult, elements: elements_1 }); + // do an in-place replacement of the old result with the new result. + // this ensures any repeats bound to this.results will not thrash. + this_1.results.splice(this_1.results.indexOf(oldResult), 1, newResult); + if (!oldResult.valid && newResult.valid) { + this_1.errors.splice(this_1.errors.indexOf(oldResult), 1); + } + else if (!oldResult.valid && !newResult.valid) { + this_1.errors.splice(this_1.errors.indexOf(oldResult), 1, newResult); + } + else if (!newResult.valid) { + this_1.errors.push(newResult); + } + } + }; + var this_1 = this; + // create unrender instructions from the old results. + for (var _i = 0, oldResults_1 = oldResults; _i < oldResults_1.length; _i++) { + var oldResult = oldResults_1[_i]; + _loop_1(oldResult); + } + // create render instructions from the remaining new results. + for (var _a = 0, newResults_1 = newResults; _a < newResults_1.length; _a++) { + var result = newResults_1[_a]; + var elements = this.getAssociatedElements(result); + instruction.render.push({ result: result, elements: elements }); + this.elements.set(result, elements); + this.results.push(result); + if (!result.valid) { + this.errors.push(result); + } + } + // render. + for (var _b = 0, _c = this.renderers; _b < _c.length; _b++) { + var renderer = _c[_b]; + renderer.render(instruction); + } + }; + /** + * Validates the property associated with a binding. + */ + ValidationController.prototype.validateBinding = function (binding) { + if (!binding.isBound) { + return; + } + var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + var rules; + var registeredBinding = this.bindings.get(binding); + if (registeredBinding) { + rules = registeredBinding.rules; + registeredBinding.propertyInfo = propertyInfo; + } + if (!propertyInfo) { + return; + } + var object = propertyInfo.object, propertyName = propertyInfo.propertyName; + this.validate({ object: object, propertyName: propertyName, rules: rules }); + }; + /** + * Resets the results for a property associated with a binding. + */ + ValidationController.prototype.resetBinding = function (binding) { + var registeredBinding = this.bindings.get(binding); + var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + if (!propertyInfo && registeredBinding) { + propertyInfo = registeredBinding.propertyInfo; + } + if (registeredBinding) { + registeredBinding.propertyInfo = null; + } + if (!propertyInfo) { + return; + } + var object = propertyInfo.object, propertyName = propertyInfo.propertyName; + this.reset({ object: object, propertyName: propertyName }); + }; + /** + * Changes the controller's validateTrigger. + * @param newTrigger The new validateTrigger + */ + ValidationController.prototype.changeTrigger = function (newTrigger) { + this.validateTrigger = newTrigger; + var bindings = Array.from(this.bindings.keys()); + for (var _i = 0, bindings_1 = bindings; _i < bindings_1.length; _i++) { + var binding = bindings_1[_i]; + var source = binding.source; + binding.unbind(); + binding.bind(source); + } + }; + /** + * Revalidates the controller's current set of errors. + */ + ValidationController.prototype.revalidateErrors = function () { + for (var _i = 0, _a = this.errors; _i < _a.length; _i++) { + var _b = _a[_i], object = _b.object, propertyName = _b.propertyName, rule = _b.rule; + if (rule.__manuallyAdded__) { + continue; + } + var rules = [[rule]]; + this.validate({ object: object, propertyName: propertyName, rules: rules }); + } + }; + ValidationController.prototype.invokeCallbacks = function (instruction, result) { + if (this.eventCallbacks.length === 0) { + return; + } + var event = new ValidateEvent(result ? 'validate' : 'reset', this.errors, this.results, instruction || null, result); + for (var i = 0; i < this.eventCallbacks.length; i++) { + this.eventCallbacks[i](event); + } + }; + ValidationController.inject = [Validator, PropertyAccessorParser]; + return ValidationController; +}()); + +/** + * Binding behavior. Indicates the bound property should be validated. + */ +var ValidateBindingBehaviorBase = /** @class */ (function () { + function ValidateBindingBehaviorBase(taskQueue) { + this.taskQueue = taskQueue; + } + ValidateBindingBehaviorBase.prototype.bind = function (binding, source, rulesOrController, rules) { + var _this = this; + // identify the target element. + var target = getTargetDOMElement(binding, source); + // locate the controller. + var controller; + if (rulesOrController instanceof ValidationController) { + controller = rulesOrController; + } + else { + controller = source.container.get(Optional.of(ValidationController)); + rules = rulesOrController; + } + if (controller === null) { + throw new Error("A ValidationController has not been registered."); + } + controller.registerBinding(binding, target, rules); + binding.validationController = controller; + var trigger = this.getValidateTrigger(controller); + // tslint:disable-next-line:no-bitwise + if (trigger & validateTrigger.change) { + binding.vbbUpdateSource = binding.updateSource; + // tslint:disable-next-line:only-arrow-functions + // tslint:disable-next-line:space-before-function-paren + binding.updateSource = function (value) { + this.vbbUpdateSource(value); + this.validationController.validateBinding(this); + }; + } + // tslint:disable-next-line:no-bitwise + if (trigger & validateTrigger.blur) { + binding.validateBlurHandler = function () { + _this.taskQueue.queueMicroTask(function () { return controller.validateBinding(binding); }); + }; + binding.validateTarget = target; + target.addEventListener('blur', binding.validateBlurHandler); + } + if (trigger !== validateTrigger.manual) { + binding.standardUpdateTarget = binding.updateTarget; + // tslint:disable-next-line:only-arrow-functions + // tslint:disable-next-line:space-before-function-paren + binding.updateTarget = function (value) { + this.standardUpdateTarget(value); + this.validationController.resetBinding(this); + }; + } + }; + ValidateBindingBehaviorBase.prototype.unbind = function (binding) { + // reset the binding to it's original state. + if (binding.vbbUpdateSource) { + binding.updateSource = binding.vbbUpdateSource; + binding.vbbUpdateSource = null; + } + if (binding.standardUpdateTarget) { + binding.updateTarget = binding.standardUpdateTarget; + binding.standardUpdateTarget = null; + } + if (binding.validateBlurHandler) { + binding.validateTarget.removeEventListener('blur', binding.validateBlurHandler); + binding.validateBlurHandler = null; + binding.validateTarget = null; + } + binding.validationController.unregisterBinding(binding); + binding.validationController = null; + }; + return ValidateBindingBehaviorBase; +}()); + +/** + * Binding behavior. Indicates the bound property should be validated + * when the validate trigger specified by the associated controller's + * validateTrigger property occurs. + */ +var ValidateBindingBehavior = /** @class */ (function (_super) { + __extends(ValidateBindingBehavior, _super); + function ValidateBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateBindingBehavior.prototype.getValidateTrigger = function (controller) { + return controller.validateTrigger; + }; + ValidateBindingBehavior.inject = [TaskQueue]; + return ValidateBindingBehavior; +}(ValidateBindingBehaviorBase)); +/** + * Binding behavior. Indicates the bound property will be validated + * manually, by calling controller.validate(). No automatic validation + * triggered by data-entry or blur will occur. + */ +var ValidateManuallyBindingBehavior = /** @class */ (function (_super) { + __extends(ValidateManuallyBindingBehavior, _super); + function ValidateManuallyBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateManuallyBindingBehavior.prototype.getValidateTrigger = function () { + return validateTrigger.manual; + }; + ValidateManuallyBindingBehavior.inject = [TaskQueue]; + return ValidateManuallyBindingBehavior; +}(ValidateBindingBehaviorBase)); +/** + * Binding behavior. Indicates the bound property should be validated + * when the associated element blurs. + */ +var ValidateOnBlurBindingBehavior = /** @class */ (function (_super) { + __extends(ValidateOnBlurBindingBehavior, _super); + function ValidateOnBlurBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateOnBlurBindingBehavior.prototype.getValidateTrigger = function () { + return validateTrigger.blur; + }; + ValidateOnBlurBindingBehavior.inject = [TaskQueue]; + return ValidateOnBlurBindingBehavior; +}(ValidateBindingBehaviorBase)); +/** + * Binding behavior. Indicates the bound property should be validated + * when the associated element is changed by the user, causing a change + * to the model. + */ +var ValidateOnChangeBindingBehavior = /** @class */ (function (_super) { + __extends(ValidateOnChangeBindingBehavior, _super); + function ValidateOnChangeBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateOnChangeBindingBehavior.prototype.getValidateTrigger = function () { + return validateTrigger.change; + }; + ValidateOnChangeBindingBehavior.inject = [TaskQueue]; + return ValidateOnChangeBindingBehavior; +}(ValidateBindingBehaviorBase)); +/** + * Binding behavior. Indicates the bound property should be validated + * when the associated element blurs or is changed by the user, causing + * a change to the model. + */ +var ValidateOnChangeOrBlurBindingBehavior = /** @class */ (function (_super) { + __extends(ValidateOnChangeOrBlurBindingBehavior, _super); + function ValidateOnChangeOrBlurBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateOnChangeOrBlurBindingBehavior.prototype.getValidateTrigger = function () { + return validateTrigger.changeOrBlur; + }; + ValidateOnChangeOrBlurBindingBehavior.inject = [TaskQueue]; + return ValidateOnChangeOrBlurBindingBehavior; +}(ValidateBindingBehaviorBase)); + +/** + * Creates ValidationController instances. + */ +var ValidationControllerFactory = /** @class */ (function () { + function ValidationControllerFactory(container) { + this.container = container; + } + ValidationControllerFactory.get = function (container) { + return new ValidationControllerFactory(container); + }; + /** + * Creates a new controller instance. + */ + ValidationControllerFactory.prototype.create = function (validator) { + if (!validator) { + validator = this.container.get(Validator); + } + var propertyParser = this.container.get(PropertyAccessorParser); + return new ValidationController(validator, propertyParser); + }; + /** + * Creates a new controller and registers it in the current element's container so that it's + * available to the validate binding behavior and renderers. + */ + ValidationControllerFactory.prototype.createForCurrentScope = function (validator) { + var controller = this.create(validator); + this.container.registerInstance(ValidationController, controller); + return controller; + }; + return ValidationControllerFactory; +}()); +ValidationControllerFactory['protocol:aurelia:resolver'] = true; + +var ValidationErrorsCustomAttribute = /** @class */ (function () { + function ValidationErrorsCustomAttribute(boundaryElement, controllerAccessor) { + this.boundaryElement = boundaryElement; + this.controllerAccessor = controllerAccessor; + this.controller = null; + this.errors = []; + this.errorsInternal = []; + } + ValidationErrorsCustomAttribute.inject = function () { + return [DOM.Element, Lazy.of(ValidationController)]; + }; + ValidationErrorsCustomAttribute.prototype.sort = function () { + this.errorsInternal.sort(function (a, b) { + if (a.targets[0] === b.targets[0]) { + return 0; + } + // tslint:disable-next-line:no-bitwise + return a.targets[0].compareDocumentPosition(b.targets[0]) & 2 ? 1 : -1; + }); + }; + ValidationErrorsCustomAttribute.prototype.interestingElements = function (elements) { + var _this = this; + return elements.filter(function (e) { return _this.boundaryElement.contains(e); }); + }; + ValidationErrorsCustomAttribute.prototype.render = function (instruction) { + var _loop_1 = function (result) { + var index = this_1.errorsInternal.findIndex(function (x) { return x.error === result; }); + if (index !== -1) { + this_1.errorsInternal.splice(index, 1); + } + }; + var this_1 = this; + for (var _i = 0, _a = instruction.unrender; _i < _a.length; _i++) { + var result = _a[_i].result; + _loop_1(result); + } + for (var _b = 0, _c = instruction.render; _b < _c.length; _b++) { + var _d = _c[_b], result = _d.result, elements = _d.elements; + if (result.valid) { + continue; + } + var targets = this.interestingElements(elements); + if (targets.length) { + this.errorsInternal.push({ error: result, targets: targets }); + } + } + this.sort(); + this.errors = this.errorsInternal; + }; + ValidationErrorsCustomAttribute.prototype.bind = function () { + if (!this.controller) { + this.controller = this.controllerAccessor(); + } + // this will call render() with the side-effect of updating this.errors + this.controller.addRenderer(this); + }; + ValidationErrorsCustomAttribute.prototype.unbind = function () { + if (this.controller) { + this.controller.removeRenderer(this); + } + }; + __decorate([ + bindable({ defaultBindingMode: bindingMode.oneWay }) + ], ValidationErrorsCustomAttribute.prototype, "controller", void 0); + __decorate([ + bindable({ primaryProperty: true, defaultBindingMode: bindingMode.twoWay }) + ], ValidationErrorsCustomAttribute.prototype, "errors", void 0); + ValidationErrorsCustomAttribute = __decorate([ + customAttribute('validation-errors') + ], ValidationErrorsCustomAttribute); + return ValidationErrorsCustomAttribute; +}()); + +var ValidationRendererCustomAttribute = /** @class */ (function () { + function ValidationRendererCustomAttribute() { + } + ValidationRendererCustomAttribute.prototype.created = function (view) { + this.container = view.container; + }; + ValidationRendererCustomAttribute.prototype.bind = function () { + this.controller = this.container.get(ValidationController); + this.renderer = this.container.get(this.value); + this.controller.addRenderer(this.renderer); + }; + ValidationRendererCustomAttribute.prototype.unbind = function () { + this.controller.removeRenderer(this.renderer); + this.controller = null; + this.renderer = null; + }; + ValidationRendererCustomAttribute = __decorate([ + customAttribute$1('validation-renderer') + ], ValidationRendererCustomAttribute); + return ValidationRendererCustomAttribute; +}()); + +/** + * Sets, unsets and retrieves rules on an object or constructor function. + */ +var Rules = /** @class */ (function () { + function Rules() { + } + /** + * Applies the rules to a target. + */ + Rules.set = function (target, rules) { + if (target instanceof Function) { + target = target.prototype; + } + Object.defineProperty(target, Rules.key, { enumerable: false, configurable: false, writable: true, value: rules }); + }; + /** + * Removes rules from a target. + */ + Rules.unset = function (target) { + if (target instanceof Function) { + target = target.prototype; + } + target[Rules.key] = null; + }; + /** + * Retrieves the target's rules. + */ + Rules.get = function (target) { + return target[Rules.key] || null; + }; + /** + * The name of the property that stores the rules. + */ + Rules.key = '__rules__'; + return Rules; +}()); + +// tslint:disable:no-empty +var ExpressionVisitor = /** @class */ (function () { + function ExpressionVisitor() { + } + ExpressionVisitor.prototype.visitChain = function (chain) { + this.visitArgs(chain.expressions); + }; + ExpressionVisitor.prototype.visitBindingBehavior = function (behavior) { + behavior.expression.accept(this); + this.visitArgs(behavior.args); + }; + ExpressionVisitor.prototype.visitValueConverter = function (converter) { + converter.expression.accept(this); + this.visitArgs(converter.args); + }; + ExpressionVisitor.prototype.visitAssign = function (assign) { + assign.target.accept(this); + assign.value.accept(this); + }; + ExpressionVisitor.prototype.visitConditional = function (conditional) { + conditional.condition.accept(this); + conditional.yes.accept(this); + conditional.no.accept(this); + }; + ExpressionVisitor.prototype.visitAccessThis = function (access) { + access.ancestor = access.ancestor; + }; + ExpressionVisitor.prototype.visitAccessScope = function (access) { + access.name = access.name; + }; + ExpressionVisitor.prototype.visitAccessMember = function (access) { + access.object.accept(this); + }; + ExpressionVisitor.prototype.visitAccessKeyed = function (access) { + access.object.accept(this); + access.key.accept(this); + }; + ExpressionVisitor.prototype.visitCallScope = function (call) { + this.visitArgs(call.args); + }; + ExpressionVisitor.prototype.visitCallFunction = function (call) { + call.func.accept(this); + this.visitArgs(call.args); + }; + ExpressionVisitor.prototype.visitCallMember = function (call) { + call.object.accept(this); + this.visitArgs(call.args); + }; + ExpressionVisitor.prototype.visitPrefix = function (prefix) { + prefix.expression.accept(this); + }; + ExpressionVisitor.prototype.visitBinary = function (binary) { + binary.left.accept(this); + binary.right.accept(this); + }; + ExpressionVisitor.prototype.visitLiteralPrimitive = function (literal) { + literal.value = literal.value; + }; + ExpressionVisitor.prototype.visitLiteralArray = function (literal) { + this.visitArgs(literal.elements); + }; + ExpressionVisitor.prototype.visitLiteralObject = function (literal) { + this.visitArgs(literal.values); + }; + ExpressionVisitor.prototype.visitLiteralString = function (literal) { + literal.value = literal.value; + }; + ExpressionVisitor.prototype.visitArgs = function (args) { + for (var i = 0; i < args.length; i++) { + args[i].accept(this); + } + }; + return ExpressionVisitor; +}()); + +var ValidationMessageParser = /** @class */ (function () { + function ValidationMessageParser(bindinqLanguage) { + this.bindinqLanguage = bindinqLanguage; + this.emptyStringExpression = new LiteralString(''); + this.nullExpression = new LiteralPrimitive(null); + this.undefinedExpression = new LiteralPrimitive(undefined); + this.cache = {}; + } + ValidationMessageParser.prototype.parse = function (message) { + if (this.cache[message] !== undefined) { + return this.cache[message]; + } + var parts = this.bindinqLanguage.parseInterpolation(null, message); + if (parts === null) { + return new LiteralString(message); + } + var expression = new LiteralString(parts[0]); + for (var i = 1; i < parts.length; i += 2) { + expression = new Binary('+', expression, new Binary('+', this.coalesce(parts[i]), new LiteralString(parts[i + 1]))); + } + MessageExpressionValidator.validate(expression, message); + this.cache[message] = expression; + return expression; + }; + ValidationMessageParser.prototype.coalesce = function (part) { + // part === null || part === undefined ? '' : part + return new Conditional(new Binary('||', new Binary('===', part, this.nullExpression), new Binary('===', part, this.undefinedExpression)), this.emptyStringExpression, new CallMember(part, 'toString', [])); + }; + ValidationMessageParser.inject = [BindingLanguage]; + return ValidationMessageParser; +}()); +var MessageExpressionValidator = /** @class */ (function (_super) { + __extends(MessageExpressionValidator, _super); + function MessageExpressionValidator(originalMessage) { + var _this = _super.call(this) || this; + _this.originalMessage = originalMessage; + return _this; + } + MessageExpressionValidator.validate = function (expression, originalMessage) { + var visitor = new MessageExpressionValidator(originalMessage); + expression.accept(visitor); + }; + MessageExpressionValidator.prototype.visitAccessScope = function (access) { + if (access.ancestor !== 0) { + throw new Error('$parent is not permitted in validation message expressions.'); + } + if (['displayName', 'propertyName', 'value', 'object', 'config', 'getDisplayName'].indexOf(access.name) !== -1) { + getLogger('aurelia-validation') + // tslint:disable-next-line:max-line-length + .warn("Did you mean to use \"$" + access.name + "\" instead of \"" + access.name + "\" in this validation message template: \"" + this.originalMessage + "\"?"); + } + }; + return MessageExpressionValidator; +}(ExpressionVisitor)); + +/** + * Dictionary of validation messages. [messageKey]: messageExpression + */ +var validationMessages = { + /** + * The default validation message. Used with rules that have no standard message. + */ + default: "${$displayName} is invalid.", + required: "${$displayName} is required.", + matches: "${$displayName} is not correctly formatted.", + email: "${$displayName} is not a valid email.", + minLength: "${$displayName} must be at least ${$config.length} character${$config.length === 1 ? '' : 's'}.", + maxLength: "${$displayName} cannot be longer than ${$config.length} character${$config.length === 1 ? '' : 's'}.", + minItems: "${$displayName} must contain at least ${$config.count} item${$config.count === 1 ? '' : 's'}.", + maxItems: "${$displayName} cannot contain more than ${$config.count} item${$config.count === 1 ? '' : 's'}.", + equals: "${$displayName} must be ${$config.expectedValue}.", +}; +/** + * Retrieves validation messages and property display names. + */ +var ValidationMessageProvider = /** @class */ (function () { + function ValidationMessageProvider(parser) { + this.parser = parser; + } + /** + * Returns a message binding expression that corresponds to the key. + * @param key The message key. + */ + ValidationMessageProvider.prototype.getMessage = function (key) { + var message; + if (key in validationMessages) { + message = validationMessages[key]; + } + else { + message = validationMessages['default']; + } + return this.parser.parse(message); + }; + /** + * Formulates a property display name using the property name and the configured + * displayName (if provided). + * Override this with your own custom logic. + * @param propertyName The property name. + */ + ValidationMessageProvider.prototype.getDisplayName = function (propertyName, displayName) { + if (displayName !== null && displayName !== undefined) { + return (displayName instanceof Function) ? displayName() : displayName; + } + // split on upper-case letters. + var words = propertyName.toString().split(/(?=[A-Z])/).join(' '); + // capitalize first letter. + return words.charAt(0).toUpperCase() + words.slice(1); + }; + ValidationMessageProvider.inject = [ValidationMessageParser]; + return ValidationMessageProvider; +}()); + +/** + * Validates. + * Responsible for validating objects and properties. + */ +var StandardValidator = /** @class */ (function (_super) { + __extends(StandardValidator, _super); + function StandardValidator(messageProvider, resources) { + var _this = _super.call(this) || this; + _this.messageProvider = messageProvider; + _this.lookupFunctions = resources.lookupFunctions; + _this.getDisplayName = messageProvider.getDisplayName.bind(messageProvider); + return _this; + } + /** + * Validates the specified property. + * @param object The object to validate. + * @param propertyName The name of the property to validate. + * @param rules Optional. If unspecified, the rules will be looked up using the metadata + * for the object created by ValidationRules....on(class/object) + */ + StandardValidator.prototype.validateProperty = function (object, propertyName, rules) { + return this.validate(object, propertyName, rules || null); + }; + /** + * Validates all rules for specified object and it's properties. + * @param object The object to validate. + * @param rules Optional. If unspecified, the rules will be looked up using the metadata + * for the object created by ValidationRules....on(class/object) + */ + StandardValidator.prototype.validateObject = function (object, rules) { + return this.validate(object, null, rules || null); + }; + /** + * Determines whether a rule exists in a set of rules. + * @param rules The rules to search. + * @parem rule The rule to find. + */ + StandardValidator.prototype.ruleExists = function (rules, rule) { + var i = rules.length; + while (i--) { + if (rules[i].indexOf(rule) !== -1) { + return true; + } + } + return false; + }; + StandardValidator.prototype.getMessage = function (rule, object, value) { + var expression = rule.message || this.messageProvider.getMessage(rule.messageKey); + // tslint:disable-next-line:prefer-const + var _a = rule.property, propertyName = _a.name, displayName = _a.displayName; + if (propertyName !== null) { + displayName = this.messageProvider.getDisplayName(propertyName, displayName); + } + var overrideContext = { + $displayName: displayName, + $propertyName: propertyName, + $value: value, + $object: object, + $config: rule.config, + // returns the name of a given property, given just the property name (irrespective of the property's displayName) + // split on capital letters, first letter ensured to be capitalized + $getDisplayName: this.getDisplayName + }; + return expression.evaluate({ bindingContext: object, overrideContext: overrideContext }, this.lookupFunctions); + }; + StandardValidator.prototype.validateRuleSequence = function (object, propertyName, ruleSequence, sequence, results) { + var _this = this; + // are we validating all properties or a single property? + var validateAllProperties = propertyName === null || propertyName === undefined; + var rules = ruleSequence[sequence]; + var allValid = true; + // validate each rule. + var promises = []; + var _loop_1 = function (i) { + var rule = rules[i]; + // is the rule related to the property we're validating. + // tslint:disable-next-line:triple-equals | Use loose equality for property keys + if (!validateAllProperties && rule.property.name != propertyName) { + return "continue"; + } + // is this a conditional rule? is the condition met? + if (rule.when && !rule.when(object)) { + return "continue"; + } + // validate. + var value = rule.property.name === null ? object : object[rule.property.name]; + var promiseOrBoolean = rule.condition(value, object); + if (!(promiseOrBoolean instanceof Promise)) { + promiseOrBoolean = Promise.resolve(promiseOrBoolean); + } + promises.push(promiseOrBoolean.then(function (valid) { + var message = valid ? null : _this.getMessage(rule, object, value); + results.push(new ValidateResult(rule, object, rule.property.name, valid, message)); + allValid = allValid && valid; + return valid; + })); + }; + for (var i = 0; i < rules.length; i++) { + _loop_1(i); + } + return Promise.all(promises) + .then(function () { + sequence++; + if (allValid && sequence < ruleSequence.length) { + return _this.validateRuleSequence(object, propertyName, ruleSequence, sequence, results); + } + return results; + }); + }; + StandardValidator.prototype.validate = function (object, propertyName, rules) { + // rules specified? + if (!rules) { + // no. attempt to locate the rules. + rules = Rules.get(object); + } + // any rules? + if (!rules || rules.length === 0) { + return Promise.resolve([]); + } + return this.validateRuleSequence(object, propertyName, rules, 0, []); + }; + StandardValidator.inject = [ValidationMessageProvider, ViewResources]; + return StandardValidator; +}(Validator)); + +/** + * Part of the fluent rule API. Enables customizing property rules. + */ +var FluentRuleCustomizer = /** @class */ (function () { + function FluentRuleCustomizer(property, condition, config, fluentEnsure, fluentRules, parsers) { + if (config === void 0) { config = {}; } + this.fluentEnsure = fluentEnsure; + this.fluentRules = fluentRules; + this.parsers = parsers; + this.rule = { + property: property, + condition: condition, + config: config, + when: null, + messageKey: 'default', + message: null, + sequence: fluentRules.sequence + }; + this.fluentEnsure._addRule(this.rule); + } + /** + * Validate subsequent rules after previously declared rules have + * been validated successfully. Use to postpone validation of costly + * rules until less expensive rules pass validation. + */ + FluentRuleCustomizer.prototype.then = function () { + this.fluentRules.sequence++; + return this; + }; + /** + * Specifies the key to use when looking up the rule's validation message. + */ + FluentRuleCustomizer.prototype.withMessageKey = function (key) { + this.rule.messageKey = key; + this.rule.message = null; + return this; + }; + /** + * Specifies rule's validation message. + */ + FluentRuleCustomizer.prototype.withMessage = function (message) { + this.rule.messageKey = 'custom'; + this.rule.message = this.parsers.message.parse(message); + return this; + }; + /** + * Specifies a condition that must be met before attempting to validate the rule. + * @param condition A function that accepts the object as a parameter and returns true + * or false whether the rule should be evaluated. + */ + FluentRuleCustomizer.prototype.when = function (condition) { + this.rule.when = condition; + return this; + }; + /** + * Tags the rule instance, enabling the rule to be found easily + * using ValidationRules.taggedRules(rules, tag) + */ + FluentRuleCustomizer.prototype.tag = function (tag) { + this.rule.tag = tag; + return this; + }; + ///// FluentEnsure APIs ///// + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor function. + */ + FluentRuleCustomizer.prototype.ensure = function (subject) { + return this.fluentEnsure.ensure(subject); + }; + /** + * Targets an object with validation rules. + */ + FluentRuleCustomizer.prototype.ensureObject = function () { + return this.fluentEnsure.ensureObject(); + }; + Object.defineProperty(FluentRuleCustomizer.prototype, "rules", { + /** + * Rules that have been defined using the fluent API. + */ + get: function () { + return this.fluentEnsure.rules; + }, + enumerable: true, + configurable: true + }); + /** + * Applies the rules to a class or object, making them discoverable by the StandardValidator. + * @param target A class or object. + */ + FluentRuleCustomizer.prototype.on = function (target) { + return this.fluentEnsure.on(target); + }; + ///////// FluentRules APIs ///////// + /** + * Applies an ad-hoc rule function to the ensured property or object. + * @param condition The function to validate the rule. + * Will be called with two arguments, the property value and the object. + * Should return a boolean or a Promise that resolves to a boolean. + */ + FluentRuleCustomizer.prototype.satisfies = function (condition, config) { + return this.fluentRules.satisfies(condition, config); + }; + /** + * Applies a rule by name. + * @param name The name of the custom or standard rule. + * @param args The rule's arguments. + */ + FluentRuleCustomizer.prototype.satisfiesRule = function (name) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + var _a; + return (_a = this.fluentRules).satisfiesRule.apply(_a, [name].concat(args)); + }; + /** + * Applies the "required" rule to the property. + * The value cannot be null, undefined or whitespace. + */ + FluentRuleCustomizer.prototype.required = function () { + return this.fluentRules.required(); + }; + /** + * Applies the "matches" rule to the property. + * Value must match the specified regular expression. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.matches = function (regex) { + return this.fluentRules.matches(regex); + }; + /** + * Applies the "email" rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.email = function () { + return this.fluentRules.email(); + }; + /** + * Applies the "minLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.minLength = function (length) { + return this.fluentRules.minLength(length); + }; + /** + * Applies the "maxLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.maxLength = function (length) { + return this.fluentRules.maxLength(length); + }; + /** + * Applies the "minItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRuleCustomizer.prototype.minItems = function (count) { + return this.fluentRules.minItems(count); + }; + /** + * Applies the "maxItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRuleCustomizer.prototype.maxItems = function (count) { + return this.fluentRules.maxItems(count); + }; + /** + * Applies the "equals" validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.equals = function (expectedValue) { + return this.fluentRules.equals(expectedValue); + }; + return FluentRuleCustomizer; +}()); +/** + * Part of the fluent rule API. Enables applying rules to properties and objects. + */ +var FluentRules = /** @class */ (function () { + function FluentRules(fluentEnsure, parsers, property) { + this.fluentEnsure = fluentEnsure; + this.parsers = parsers; + this.property = property; + /** + * Current rule sequence number. Used to postpone evaluation of rules until rules + * with lower sequence number have successfully validated. The "then" fluent API method + * manages this property, there's usually no need to set it directly. + */ + this.sequence = 0; + } + /** + * Sets the display name of the ensured property. + */ + FluentRules.prototype.displayName = function (name) { + this.property.displayName = name; + return this; + }; + /** + * Applies an ad-hoc rule function to the ensured property or object. + * @param condition The function to validate the rule. + * Will be called with two arguments, the property value and the object. + * Should return a boolean or a Promise that resolves to a boolean. + */ + FluentRules.prototype.satisfies = function (condition, config) { + return new FluentRuleCustomizer(this.property, condition, config, this.fluentEnsure, this, this.parsers); + }; + /** + * Applies a rule by name. + * @param name The name of the custom or standard rule. + * @param args The rule's arguments. + */ + FluentRules.prototype.satisfiesRule = function (name) { + var _this = this; + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + var rule = FluentRules.customRules[name]; + if (!rule) { + // standard rule? + rule = this[name]; + if (rule instanceof Function) { + return rule.call.apply(rule, [this].concat(args)); + } + throw new Error("Rule with name \"" + name + "\" does not exist."); + } + var config = rule.argsToConfig ? rule.argsToConfig.apply(rule, args) : undefined; + return this.satisfies(function (value, obj) { + var _a; + return (_a = rule.condition).call.apply(_a, [_this, value, obj].concat(args)); + }, config) + .withMessageKey(name); + }; + /** + * Applies the "required" rule to the property. + * The value cannot be null, undefined or whitespace. + */ + FluentRules.prototype.required = function () { + return this.satisfies(function (value) { + return value !== null + && value !== undefined + && !(isString(value) && !/\S/.test(value)); + }).withMessageKey('required'); + }; + /** + * Applies the "matches" rule to the property. + * Value must match the specified regular expression. + * null, undefined and empty-string values are considered valid. + */ + FluentRules.prototype.matches = function (regex) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || regex.test(value); }) + .withMessageKey('matches'); + }; + /** + * Applies the "email" rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRules.prototype.email = function () { + // regex from https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address + /* tslint:disable:max-line-length */ + return this.matches(/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/) + /* tslint:enable:max-line-length */ + .withMessageKey('email'); + }; + /** + * Applies the "minLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRules.prototype.minLength = function (length) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || value.length >= length; }, { length: length }) + .withMessageKey('minLength'); + }; + /** + * Applies the "maxLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRules.prototype.maxLength = function (length) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || value.length <= length; }, { length: length }) + .withMessageKey('maxLength'); + }; + /** + * Applies the "minItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRules.prototype.minItems = function (count) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length >= count; }, { count: count }) + .withMessageKey('minItems'); + }; + /** + * Applies the "maxItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRules.prototype.maxItems = function (count) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length <= count; }, { count: count }) + .withMessageKey('maxItems'); + }; + /** + * Applies the "equals" validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRules.prototype.equals = function (expectedValue) { + return this.satisfies(function (value) { return value === null || value === undefined || value === '' || value === expectedValue; }, { expectedValue: expectedValue }) + .withMessageKey('equals'); + }; + FluentRules.customRules = {}; + return FluentRules; +}()); +/** + * Part of the fluent rule API. Enables targeting properties and objects with rules. + */ +var FluentEnsure = /** @class */ (function () { + function FluentEnsure(parsers) { + this.parsers = parsers; + /** + * Rules that have been defined using the fluent API. + */ + this.rules = []; + } + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor + * function. + */ + FluentEnsure.prototype.ensure = function (property) { + this.assertInitialized(); + var name = this.parsers.property.parse(property); + var fluentRules = new FluentRules(this, this.parsers, { name: name, displayName: null }); + return this.mergeRules(fluentRules, name); + }; + /** + * Targets an object with validation rules. + */ + FluentEnsure.prototype.ensureObject = function () { + this.assertInitialized(); + var fluentRules = new FluentRules(this, this.parsers, { name: null, displayName: null }); + return this.mergeRules(fluentRules, null); + }; + /** + * Applies the rules to a class or object, making them discoverable by the StandardValidator. + * @param target A class or object. + */ + FluentEnsure.prototype.on = function (target) { + Rules.set(target, this.rules); + return this; + }; + /** + * Adds a rule definition to the sequenced ruleset. + * @internal + */ + FluentEnsure.prototype._addRule = function (rule) { + while (this.rules.length < rule.sequence + 1) { + this.rules.push([]); + } + this.rules[rule.sequence].push(rule); + }; + FluentEnsure.prototype.assertInitialized = function () { + if (this.parsers) { + return; + } + throw new Error("Did you forget to add \".plugin('aurelia-validation')\" to your main.js?"); + }; + FluentEnsure.prototype.mergeRules = function (fluentRules, propertyName) { + // tslint:disable-next-line:triple-equals | Use loose equality for property keys + var existingRules = this.rules.find(function (r) { return r.length > 0 && r[0].property.name == propertyName; }); + if (existingRules) { + var rule = existingRules[existingRules.length - 1]; + fluentRules.sequence = rule.sequence; + if (rule.property.displayName !== null) { + fluentRules = fluentRules.displayName(rule.property.displayName); + } + } + return fluentRules; + }; + return FluentEnsure; +}()); +/** + * Fluent rule definition API. + */ +var ValidationRules = /** @class */ (function () { + function ValidationRules() { + } + ValidationRules.initialize = function (messageParser, propertyParser) { + this.parsers = { + message: messageParser, + property: propertyParser + }; + }; + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor function. + */ + ValidationRules.ensure = function (property) { + return new FluentEnsure(ValidationRules.parsers).ensure(property); + }; + /** + * Targets an object with validation rules. + */ + ValidationRules.ensureObject = function () { + return new FluentEnsure(ValidationRules.parsers).ensureObject(); + }; + /** + * Defines a custom rule. + * @param name The name of the custom rule. Also serves as the message key. + * @param condition The rule function. + * @param message The message expression + * @param argsToConfig A function that maps the rule's arguments to a "config" + * object that can be used when evaluating the message expression. + */ + ValidationRules.customRule = function (name, condition, message, argsToConfig) { + validationMessages[name] = message; + FluentRules.customRules[name] = { condition: condition, argsToConfig: argsToConfig }; + }; + /** + * Returns rules with the matching tag. + * @param rules The rules to search. + * @param tag The tag to search for. + */ + ValidationRules.taggedRules = function (rules, tag) { + return rules.map(function (x) { return x.filter(function (r) { return r.tag === tag; }); }); + }; + /** + * Returns rules that have no tag. + * @param rules The rules to search. + */ + ValidationRules.untaggedRules = function (rules) { + return rules.map(function (x) { return x.filter(function (r) { return r.tag === undefined; }); }); + }; + /** + * Removes the rules from a class or object. + * @param target A class or object. + */ + ValidationRules.off = function (target) { + Rules.unset(target); + }; + return ValidationRules; }()); -export { AureliaValidationConfiguration }; -/** - * Configures the plugin. - */ -export function configure(frameworkConfig, callback) { - // the fluent rule definition API needs the parser to translate messages - // to interpolation expressions. - var messageParser = frameworkConfig.container.get(ValidationMessageParser); - var propertyParser = frameworkConfig.container.get(PropertyAccessorParser); - ValidationRules.initialize(messageParser, propertyParser); - // configure... - var config = new AureliaValidationConfiguration(); - if (callback instanceof Function) { - callback(config); - } - config.apply(frameworkConfig.container); - // globalize the behaviors. - if (frameworkConfig.globalResources) { - frameworkConfig.globalResources(PLATFORM.moduleName('./validate-binding-behavior'), PLATFORM.moduleName('./validation-errors-custom-attribute'), PLATFORM.moduleName('./validation-renderer-custom-attribute')); - } + +// Exports +/** + * Aurelia Validation Configuration API + */ +var AureliaValidationConfiguration = /** @class */ (function () { + function AureliaValidationConfiguration() { + this.validatorType = StandardValidator; + } + /** + * Use a custom Validator implementation. + */ + AureliaValidationConfiguration.prototype.customValidator = function (type) { + this.validatorType = type; + }; + /** + * Applies the configuration. + */ + AureliaValidationConfiguration.prototype.apply = function (container) { + var validator = container.get(this.validatorType); + container.registerInstance(Validator, validator); + }; + return AureliaValidationConfiguration; +}()); +/** + * Configures the plugin. + */ +function configure( +// tslint:disable-next-line:ban-types +frameworkConfig, callback) { + // the fluent rule definition API needs the parser to translate messages + // to interpolation expressions. + var messageParser = frameworkConfig.container.get(ValidationMessageParser); + var propertyParser = frameworkConfig.container.get(PropertyAccessorParser); + ValidationRules.initialize(messageParser, propertyParser); + // configure... + var config = new AureliaValidationConfiguration(); + if (callback instanceof Function) { + callback(config); + } + config.apply(frameworkConfig.container); + // globalize the behaviors. + if (frameworkConfig.globalResources) { + frameworkConfig.globalResources(ValidateBindingBehavior, ValidateManuallyBindingBehavior, ValidateOnBlurBindingBehavior, ValidateOnChangeBindingBehavior, ValidateOnChangeOrBlurBindingBehavior, ValidationErrorsCustomAttribute, ValidationRendererCustomAttribute); + } } + +export { AureliaValidationConfiguration, configure, getTargetDOMElement, getPropertyInfo, PropertyAccessorParser, getAccessorExpression, ValidateBindingBehavior, ValidateManuallyBindingBehavior, ValidateOnBlurBindingBehavior, ValidateOnChangeBindingBehavior, ValidateOnChangeOrBlurBindingBehavior, ValidateEvent, ValidateResult, validateTrigger, ValidationController, ValidationControllerFactory, ValidationErrorsCustomAttribute, ValidationRendererCustomAttribute, Validator, Rules, StandardValidator, validationMessages, ValidationMessageProvider, ValidationMessageParser, MessageExpressionValidator, FluentRuleCustomizer, FluentRules, FluentEnsure, ValidationRules }; diff --git a/dist/native-modules/controller-validate-result.d.ts b/dist/native-modules/controller-validate-result.d.ts deleted file mode 100644 index 5f814ed0..00000000 --- a/dist/native-modules/controller-validate-result.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { ValidateResult } from './validate-result'; -import { ValidateInstruction } from './validate-instruction'; -/** - * The result of a call to the validation controller's validate method. - */ -export interface ControllerValidateResult { - /** - * Whether validation passed. - */ - valid: boolean; - /** - * The validation result of every rule that was evaluated. - */ - results: ValidateResult[]; - /** - * The instruction passed to the controller's validate method. - */ - instruction?: ValidateInstruction; -} diff --git a/dist/native-modules/controller-validate-result.js b/dist/native-modules/controller-validate-result.js deleted file mode 100644 index e69de29b..00000000 diff --git a/dist/native-modules/get-target-dom-element.d.ts b/dist/native-modules/get-target-dom-element.d.ts deleted file mode 100644 index 314fc952..00000000 --- a/dist/native-modules/get-target-dom-element.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Gets the DOM element associated with the data-binding. Most of the time it's - * the binding.target but sometimes binding.target is an aurelia custom element, - * or custom attribute which is a javascript "class" instance, so we need to use - * the controller's container to retrieve the actual DOM element. - */ -export declare function getTargetDOMElement(binding: any, view: any): Element; diff --git a/dist/native-modules/get-target-dom-element.js b/dist/native-modules/get-target-dom-element.js deleted file mode 100644 index 6df9d16a..00000000 --- a/dist/native-modules/get-target-dom-element.js +++ /dev/null @@ -1,27 +0,0 @@ -import { DOM } from 'aurelia-pal'; -/** - * Gets the DOM element associated with the data-binding. Most of the time it's - * the binding.target but sometimes binding.target is an aurelia custom element, - * or custom attribute which is a javascript "class" instance, so we need to use - * the controller's container to retrieve the actual DOM element. - */ -export function getTargetDOMElement(binding, view) { - var target = binding.target; - // DOM element - if (target instanceof Element) { - return target; - } - // custom element or custom attribute - // tslint:disable-next-line:prefer-const - for (var i = 0, ii = view.controllers.length; i < ii; i++) { - var controller = view.controllers[i]; - if (controller.viewModel === target) { - var element = controller.container.get(DOM.Element); - if (element) { - return element; - } - throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\"."); - } - } - throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\"."); -} diff --git a/dist/native-modules/implementation/expression-visitor.d.ts b/dist/native-modules/implementation/expression-visitor.d.ts deleted file mode 100644 index 47769fae..00000000 --- a/dist/native-modules/implementation/expression-visitor.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { ValueConverter, Conditional, AccessMember, AccessKeyed, CallMember, BindingBehavior, Binary } from 'aurelia-binding'; -export declare type Chain = any; -export declare type Assign = any; -export declare type AccessThis = any; -export declare type AccessScope = any; -export declare type CallScope = any; -export declare type CallFunction = any; -export declare type PrefixNot = any; -export declare type LiteralPrimitive = any; -export declare type LiteralArray = any; -export declare type LiteralObject = any; -export declare type LiteralString = any; -export declare class ExpressionVisitor { - visitChain(chain: Chain): void; - visitBindingBehavior(behavior: BindingBehavior): void; - visitValueConverter(converter: ValueConverter): void; - visitAssign(assign: Assign): void; - visitConditional(conditional: Conditional): void; - visitAccessThis(access: AccessThis): void; - visitAccessScope(access: AccessScope): void; - visitAccessMember(access: AccessMember): void; - visitAccessKeyed(access: AccessKeyed): void; - visitCallScope(call: CallScope): void; - visitCallFunction(call: CallFunction): void; - visitCallMember(call: CallMember): void; - visitPrefix(prefix: PrefixNot): void; - visitBinary(binary: Binary): void; - visitLiteralPrimitive(literal: LiteralPrimitive): void; - visitLiteralArray(literal: LiteralArray): void; - visitLiteralObject(literal: LiteralObject): void; - visitLiteralString(literal: LiteralString): void; - private visitArgs(args); -} diff --git a/dist/native-modules/implementation/expression-visitor.js b/dist/native-modules/implementation/expression-visitor.js deleted file mode 100644 index 51a02581..00000000 --- a/dist/native-modules/implementation/expression-visitor.js +++ /dev/null @@ -1,75 +0,0 @@ -// tslint:disable:no-empty -var ExpressionVisitor = /** @class */ (function () { - function ExpressionVisitor() { - } - ExpressionVisitor.prototype.visitChain = function (chain) { - this.visitArgs(chain.expressions); - }; - ExpressionVisitor.prototype.visitBindingBehavior = function (behavior) { - behavior.expression.accept(this); - this.visitArgs(behavior.args); - }; - ExpressionVisitor.prototype.visitValueConverter = function (converter) { - converter.expression.accept(this); - this.visitArgs(converter.args); - }; - ExpressionVisitor.prototype.visitAssign = function (assign) { - assign.target.accept(this); - assign.value.accept(this); - }; - ExpressionVisitor.prototype.visitConditional = function (conditional) { - conditional.condition.accept(this); - conditional.yes.accept(this); - conditional.no.accept(this); - }; - ExpressionVisitor.prototype.visitAccessThis = function (access) { - access.ancestor = access.ancestor; - }; - ExpressionVisitor.prototype.visitAccessScope = function (access) { - access.name = access.name; - }; - ExpressionVisitor.prototype.visitAccessMember = function (access) { - access.object.accept(this); - }; - ExpressionVisitor.prototype.visitAccessKeyed = function (access) { - access.object.accept(this); - access.key.accept(this); - }; - ExpressionVisitor.prototype.visitCallScope = function (call) { - this.visitArgs(call.args); - }; - ExpressionVisitor.prototype.visitCallFunction = function (call) { - call.func.accept(this); - this.visitArgs(call.args); - }; - ExpressionVisitor.prototype.visitCallMember = function (call) { - call.object.accept(this); - this.visitArgs(call.args); - }; - ExpressionVisitor.prototype.visitPrefix = function (prefix) { - prefix.expression.accept(this); - }; - ExpressionVisitor.prototype.visitBinary = function (binary) { - binary.left.accept(this); - binary.right.accept(this); - }; - ExpressionVisitor.prototype.visitLiteralPrimitive = function (literal) { - literal.value = literal.value; - }; - ExpressionVisitor.prototype.visitLiteralArray = function (literal) { - this.visitArgs(literal.elements); - }; - ExpressionVisitor.prototype.visitLiteralObject = function (literal) { - this.visitArgs(literal.values); - }; - ExpressionVisitor.prototype.visitLiteralString = function (literal) { - literal.value = literal.value; - }; - ExpressionVisitor.prototype.visitArgs = function (args) { - for (var i = 0; i < args.length; i++) { - args[i].accept(this); - } - }; - return ExpressionVisitor; -}()); -export { ExpressionVisitor }; diff --git a/dist/native-modules/implementation/rule.d.ts b/dist/native-modules/implementation/rule.d.ts deleted file mode 100644 index ffbb7b21..00000000 --- a/dist/native-modules/implementation/rule.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Expression } from 'aurelia-binding'; -export declare type ValidationDisplayNameAccessor = () => string; -/** - * Information related to a property that is the subject of validation. - */ -export interface RuleProperty { - /** - * The property name. null indicates the rule targets the object itself. - */ - name: string | number | null; - /** - * The displayName of the property (or object). - */ - displayName: string | ValidationDisplayNameAccessor | null; -} -/** - * A rule definition. Associations a rule with a property or object. - */ -export interface Rule { - property: RuleProperty; - condition: (value: TValue, object?: TObject) => boolean | Promise; - config: object; - when: ((object: TObject) => boolean) | null; - messageKey: string; - message: Expression | null; - sequence: number; - tag?: string; -} diff --git a/dist/native-modules/implementation/rule.js b/dist/native-modules/implementation/rule.js deleted file mode 100644 index e69de29b..00000000 diff --git a/dist/native-modules/implementation/rules.d.ts b/dist/native-modules/implementation/rules.d.ts deleted file mode 100644 index 30947f6f..00000000 --- a/dist/native-modules/implementation/rules.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Rule } from './rule'; -/** - * Sets, unsets and retrieves rules on an object or constructor function. - */ -export declare class Rules { - /** - * The name of the property that stores the rules. - */ - private static key; - /** - * Applies the rules to a target. - */ - static set(target: any, rules: Rule[][]): void; - /** - * Removes rules from a target. - */ - static unset(target: any): void; - /** - * Retrieves the target's rules. - */ - static get(target: any): Rule[][] | null; -} diff --git a/dist/native-modules/implementation/rules.js b/dist/native-modules/implementation/rules.js deleted file mode 100644 index 5041fc6e..00000000 --- a/dist/native-modules/implementation/rules.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Sets, unsets and retrieves rules on an object or constructor function. - */ -var Rules = /** @class */ (function () { - function Rules() { - } - /** - * Applies the rules to a target. - */ - Rules.set = function (target, rules) { - if (target instanceof Function) { - target = target.prototype; - } - Object.defineProperty(target, Rules.key, { enumerable: false, configurable: false, writable: true, value: rules }); - }; - /** - * Removes rules from a target. - */ - Rules.unset = function (target) { - if (target instanceof Function) { - target = target.prototype; - } - target[Rules.key] = null; - }; - /** - * Retrieves the target's rules. - */ - Rules.get = function (target) { - return target[Rules.key] || null; - }; - /** - * The name of the property that stores the rules. - */ - Rules.key = '__rules__'; - return Rules; -}()); -export { Rules }; diff --git a/dist/native-modules/implementation/standard-validator.d.ts b/dist/native-modules/implementation/standard-validator.d.ts deleted file mode 100644 index c47a7d2e..00000000 --- a/dist/native-modules/implementation/standard-validator.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { ViewResources } from 'aurelia-templating'; -import { Validator } from '../validator'; -import { ValidateResult } from '../validate-result'; -import { Rule } from './rule'; -import { ValidationMessageProvider } from './validation-messages'; -/** - * Validates. - * Responsible for validating objects and properties. - */ -export declare class StandardValidator extends Validator { - static inject: (typeof ViewResources | typeof ValidationMessageProvider)[]; - private messageProvider; - private lookupFunctions; - private getDisplayName; - constructor(messageProvider: ValidationMessageProvider, resources: ViewResources); - /** - * Validates the specified property. - * @param object The object to validate. - * @param propertyName The name of the property to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - validateProperty(object: any, propertyName: string | number, rules?: any): Promise; - /** - * Validates all rules for specified object and it's properties. - * @param object The object to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - validateObject(object: any, rules?: any): Promise; - /** - * Determines whether a rule exists in a set of rules. - * @param rules The rules to search. - * @parem rule The rule to find. - */ - ruleExists(rules: Rule[][], rule: Rule): boolean; - private getMessage(rule, object, value); - private validateRuleSequence(object, propertyName, ruleSequence, sequence, results); - private validate(object, propertyName, rules); -} diff --git a/dist/native-modules/implementation/standard-validator.js b/dist/native-modules/implementation/standard-validator.js deleted file mode 100644 index 18e2870f..00000000 --- a/dist/native-modules/implementation/standard-validator.js +++ /dev/null @@ -1,140 +0,0 @@ -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -import { ViewResources } from 'aurelia-templating'; -import { Validator } from '../validator'; -import { ValidateResult } from '../validate-result'; -import { Rules } from './rules'; -import { ValidationMessageProvider } from './validation-messages'; -/** - * Validates. - * Responsible for validating objects and properties. - */ -var StandardValidator = /** @class */ (function (_super) { - __extends(StandardValidator, _super); - function StandardValidator(messageProvider, resources) { - var _this = _super.call(this) || this; - _this.messageProvider = messageProvider; - _this.lookupFunctions = resources.lookupFunctions; - _this.getDisplayName = messageProvider.getDisplayName.bind(messageProvider); - return _this; - } - /** - * Validates the specified property. - * @param object The object to validate. - * @param propertyName The name of the property to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - StandardValidator.prototype.validateProperty = function (object, propertyName, rules) { - return this.validate(object, propertyName, rules || null); - }; - /** - * Validates all rules for specified object and it's properties. - * @param object The object to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - StandardValidator.prototype.validateObject = function (object, rules) { - return this.validate(object, null, rules || null); - }; - /** - * Determines whether a rule exists in a set of rules. - * @param rules The rules to search. - * @parem rule The rule to find. - */ - StandardValidator.prototype.ruleExists = function (rules, rule) { - var i = rules.length; - while (i--) { - if (rules[i].indexOf(rule) !== -1) { - return true; - } - } - return false; - }; - StandardValidator.prototype.getMessage = function (rule, object, value) { - var expression = rule.message || this.messageProvider.getMessage(rule.messageKey); - // tslint:disable-next-line:prefer-const - var _a = rule.property, propertyName = _a.name, displayName = _a.displayName; - if (propertyName !== null) { - displayName = this.messageProvider.getDisplayName(propertyName, displayName); - } - var overrideContext = { - $displayName: displayName, - $propertyName: propertyName, - $value: value, - $object: object, - $config: rule.config, - // returns the name of a given property, given just the property name (irrespective of the property's displayName) - // split on capital letters, first letter ensured to be capitalized - $getDisplayName: this.getDisplayName - }; - return expression.evaluate({ bindingContext: object, overrideContext: overrideContext }, this.lookupFunctions); - }; - StandardValidator.prototype.validateRuleSequence = function (object, propertyName, ruleSequence, sequence, results) { - var _this = this; - // are we validating all properties or a single property? - var validateAllProperties = propertyName === null || propertyName === undefined; - var rules = ruleSequence[sequence]; - var allValid = true; - // validate each rule. - var promises = []; - var _loop_1 = function (i) { - var rule = rules[i]; - // is the rule related to the property we're validating. - // tslint:disable-next-line:triple-equals | Use loose equality for property keys - if (!validateAllProperties && rule.property.name != propertyName) { - return "continue"; - } - // is this a conditional rule? is the condition met? - if (rule.when && !rule.when(object)) { - return "continue"; - } - // validate. - var value = rule.property.name === null ? object : object[rule.property.name]; - var promiseOrBoolean = rule.condition(value, object); - if (!(promiseOrBoolean instanceof Promise)) { - promiseOrBoolean = Promise.resolve(promiseOrBoolean); - } - promises.push(promiseOrBoolean.then(function (valid) { - var message = valid ? null : _this.getMessage(rule, object, value); - results.push(new ValidateResult(rule, object, rule.property.name, valid, message)); - allValid = allValid && valid; - return valid; - })); - }; - for (var i = 0; i < rules.length; i++) { - _loop_1(i); - } - return Promise.all(promises) - .then(function () { - sequence++; - if (allValid && sequence < ruleSequence.length) { - return _this.validateRuleSequence(object, propertyName, ruleSequence, sequence, results); - } - return results; - }); - }; - StandardValidator.prototype.validate = function (object, propertyName, rules) { - // rules specified? - if (!rules) { - // no. attempt to locate the rules. - rules = Rules.get(object); - } - // any rules? - if (!rules || rules.length === 0) { - return Promise.resolve([]); - } - return this.validateRuleSequence(object, propertyName, rules, 0, []); - }; - StandardValidator.inject = [ValidationMessageProvider, ViewResources]; - return StandardValidator; -}(Validator)); -export { StandardValidator }; diff --git a/dist/native-modules/implementation/validation-message-parser.d.ts b/dist/native-modules/implementation/validation-message-parser.d.ts deleted file mode 100644 index 39d288c0..00000000 --- a/dist/native-modules/implementation/validation-message-parser.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Expression, AccessScope } from 'aurelia-binding'; -import { BindingLanguage } from 'aurelia-templating'; -import { ExpressionVisitor } from './expression-visitor'; -export declare class ValidationMessageParser { - private bindinqLanguage; - static inject: (typeof BindingLanguage)[]; - private emptyStringExpression; - private nullExpression; - private undefinedExpression; - private cache; - constructor(bindinqLanguage: BindingLanguage); - parse(message: string): Expression; - private coalesce(part); -} -export declare class MessageExpressionValidator extends ExpressionVisitor { - private originalMessage; - static validate(expression: Expression, originalMessage: string): void; - constructor(originalMessage: string); - visitAccessScope(access: AccessScope): void; -} diff --git a/dist/native-modules/implementation/validation-message-parser.js b/dist/native-modules/implementation/validation-message-parser.js deleted file mode 100644 index ba2a73c5..00000000 --- a/dist/native-modules/implementation/validation-message-parser.js +++ /dev/null @@ -1,69 +0,0 @@ -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -import { LiteralString, Binary, Conditional, LiteralPrimitive, CallMember } from 'aurelia-binding'; -import { BindingLanguage } from 'aurelia-templating'; -import * as LogManager from 'aurelia-logging'; -import { ExpressionVisitor } from './expression-visitor'; -var ValidationMessageParser = /** @class */ (function () { - function ValidationMessageParser(bindinqLanguage) { - this.bindinqLanguage = bindinqLanguage; - this.emptyStringExpression = new LiteralString(''); - this.nullExpression = new LiteralPrimitive(null); - this.undefinedExpression = new LiteralPrimitive(undefined); - this.cache = {}; - } - ValidationMessageParser.prototype.parse = function (message) { - if (this.cache[message] !== undefined) { - return this.cache[message]; - } - var parts = this.bindinqLanguage.parseInterpolation(null, message); - if (parts === null) { - return new LiteralString(message); - } - var expression = new LiteralString(parts[0]); - for (var i = 1; i < parts.length; i += 2) { - expression = new Binary('+', expression, new Binary('+', this.coalesce(parts[i]), new LiteralString(parts[i + 1]))); - } - MessageExpressionValidator.validate(expression, message); - this.cache[message] = expression; - return expression; - }; - ValidationMessageParser.prototype.coalesce = function (part) { - // part === null || part === undefined ? '' : part - return new Conditional(new Binary('||', new Binary('===', part, this.nullExpression), new Binary('===', part, this.undefinedExpression)), this.emptyStringExpression, new CallMember(part, 'toString', [])); - }; - ValidationMessageParser.inject = [BindingLanguage]; - return ValidationMessageParser; -}()); -export { ValidationMessageParser }; -var MessageExpressionValidator = /** @class */ (function (_super) { - __extends(MessageExpressionValidator, _super); - function MessageExpressionValidator(originalMessage) { - var _this = _super.call(this) || this; - _this.originalMessage = originalMessage; - return _this; - } - MessageExpressionValidator.validate = function (expression, originalMessage) { - var visitor = new MessageExpressionValidator(originalMessage); - expression.accept(visitor); - }; - MessageExpressionValidator.prototype.visitAccessScope = function (access) { - if (access.ancestor !== 0) { - throw new Error('$parent is not permitted in validation message expressions.'); - } - if (['displayName', 'propertyName', 'value', 'object', 'config', 'getDisplayName'].indexOf(access.name) !== -1) { - LogManager.getLogger('aurelia-validation') - .warn("Did you mean to use \"$" + access.name + "\" instead of \"" + access.name + "\" in this validation message template: \"" + this.originalMessage + "\"?"); - } - }; - return MessageExpressionValidator; -}(ExpressionVisitor)); -export { MessageExpressionValidator }; diff --git a/dist/native-modules/implementation/validation-messages.d.ts b/dist/native-modules/implementation/validation-messages.d.ts deleted file mode 100644 index eb4cb9d4..00000000 --- a/dist/native-modules/implementation/validation-messages.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Expression } from 'aurelia-binding'; -import { ValidationMessageParser } from './validation-message-parser'; -export interface ValidationMessages { - [key: string]: string; -} -/** - * Dictionary of validation messages. [messageKey]: messageExpression - */ -export declare const validationMessages: ValidationMessages; -/** - * Retrieves validation messages and property display names. - */ -export declare class ValidationMessageProvider { - parser: ValidationMessageParser; - static inject: (typeof ValidationMessageParser)[]; - constructor(parser: ValidationMessageParser); - /** - * Returns a message binding expression that corresponds to the key. - * @param key The message key. - */ - getMessage(key: string): Expression; - /** - * Formulates a property display name using the property name and the configured - * displayName (if provided). - * Override this with your own custom logic. - * @param propertyName The property name. - */ - getDisplayName(propertyName: string | number, displayName?: string | null | (() => string)): string; -} diff --git a/dist/native-modules/implementation/validation-messages.js b/dist/native-modules/implementation/validation-messages.js deleted file mode 100644 index a3711db1..00000000 --- a/dist/native-modules/implementation/validation-messages.js +++ /dev/null @@ -1,58 +0,0 @@ -import { ValidationMessageParser } from './validation-message-parser'; -/** - * Dictionary of validation messages. [messageKey]: messageExpression - */ -export var validationMessages = { - /** - * The default validation message. Used with rules that have no standard message. - */ - default: "${$displayName} is invalid.", - required: "${$displayName} is required.", - matches: "${$displayName} is not correctly formatted.", - email: "${$displayName} is not a valid email.", - minLength: "${$displayName} must be at least ${$config.length} character${$config.length === 1 ? '' : 's'}.", - maxLength: "${$displayName} cannot be longer than ${$config.length} character${$config.length === 1 ? '' : 's'}.", - minItems: "${$displayName} must contain at least ${$config.count} item${$config.count === 1 ? '' : 's'}.", - maxItems: "${$displayName} cannot contain more than ${$config.count} item${$config.count === 1 ? '' : 's'}.", - equals: "${$displayName} must be ${$config.expectedValue}.", -}; -/** - * Retrieves validation messages and property display names. - */ -var ValidationMessageProvider = /** @class */ (function () { - function ValidationMessageProvider(parser) { - this.parser = parser; - } - /** - * Returns a message binding expression that corresponds to the key. - * @param key The message key. - */ - ValidationMessageProvider.prototype.getMessage = function (key) { - var message; - if (key in validationMessages) { - message = validationMessages[key]; - } - else { - message = validationMessages['default']; - } - return this.parser.parse(message); - }; - /** - * Formulates a property display name using the property name and the configured - * displayName (if provided). - * Override this with your own custom logic. - * @param propertyName The property name. - */ - ValidationMessageProvider.prototype.getDisplayName = function (propertyName, displayName) { - if (displayName !== null && displayName !== undefined) { - return (displayName instanceof Function) ? displayName() : displayName; - } - // split on upper-case letters. - var words = propertyName.toString().split(/(?=[A-Z])/).join(' '); - // capitalize first letter. - return words.charAt(0).toUpperCase() + words.slice(1); - }; - ValidationMessageProvider.inject = [ValidationMessageParser]; - return ValidationMessageProvider; -}()); -export { ValidationMessageProvider }; diff --git a/dist/native-modules/implementation/validation-rules.d.ts b/dist/native-modules/implementation/validation-rules.d.ts deleted file mode 100644 index 995b2a8a..00000000 --- a/dist/native-modules/implementation/validation-rules.d.ts +++ /dev/null @@ -1,262 +0,0 @@ -import { Rule, RuleProperty, ValidationDisplayNameAccessor } from './rule'; -import { ValidationMessageParser } from './validation-message-parser'; -import { PropertyAccessorParser, PropertyAccessor } from '../property-accessor-parser'; -/** - * Part of the fluent rule API. Enables customizing property rules. - */ -export declare class FluentRuleCustomizer { - private fluentEnsure; - private fluentRules; - private parsers; - private rule; - constructor(property: RuleProperty, condition: (value: TValue, object?: TObject) => boolean | Promise, config: object | undefined, fluentEnsure: FluentEnsure, fluentRules: FluentRules, parsers: Parsers); - /** - * Validate subsequent rules after previously declared rules have - * been validated successfully. Use to postpone validation of costly - * rules until less expensive rules pass validation. - */ - then(): this; - /** - * Specifies the key to use when looking up the rule's validation message. - */ - withMessageKey(key: string): this; - /** - * Specifies rule's validation message. - */ - withMessage(message: string): this; - /** - * Specifies a condition that must be met before attempting to validate the rule. - * @param condition A function that accepts the object as a parameter and returns true - * or false whether the rule should be evaluated. - */ - when(condition: (object: TObject) => boolean): this; - /** - * Tags the rule instance, enabling the rule to be found easily - * using ValidationRules.taggedRules(rules, tag) - */ - tag(tag: string): this; - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - ensure(subject: string | ((model: TObject) => TValue2)): FluentRules; - /** - * Targets an object with validation rules. - */ - ensureObject(): FluentRules; - /** - * Rules that have been defined using the fluent API. - */ - readonly rules: Rule[][]; - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - on(target: any): FluentEnsure; - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - satisfies(condition: (value: TValue, object: TObject) => boolean | Promise, config?: object): FluentRuleCustomizer; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - satisfiesRule(name: string, ...args: any[]): FluentRuleCustomizer; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - required(): FluentRuleCustomizer; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - matches(regex: RegExp): FluentRuleCustomizer; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - email(): FluentRuleCustomizer; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - minLength(length: number): FluentRuleCustomizer; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - maxLength(length: number): FluentRuleCustomizer; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - minItems(count: number): FluentRuleCustomizer; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - maxItems(count: number): FluentRuleCustomizer; - /** - * Applies the "equals" validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - equals(expectedValue: TValue): FluentRuleCustomizer; -} -/** - * Part of the fluent rule API. Enables applying rules to properties and objects. - */ -export declare class FluentRules { - private fluentEnsure; - private parsers; - private property; - static customRules: { - [name: string]: { - condition: (value: any, object?: any, ...fluentArgs: any[]) => boolean | Promise; - argsToConfig?: (...args: any[]) => any; - }; - }; - /** - * Current rule sequence number. Used to postpone evaluation of rules until rules - * with lower sequence number have successfully validated. The "then" fluent API method - * manages this property, there's usually no need to set it directly. - */ - sequence: number; - constructor(fluentEnsure: FluentEnsure, parsers: Parsers, property: RuleProperty); - /** - * Sets the display name of the ensured property. - */ - displayName(name: string | ValidationDisplayNameAccessor | null): this; - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - satisfies(condition: (value: TValue, object?: TObject) => boolean | Promise, config?: object): FluentRuleCustomizer; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - satisfiesRule(name: string, ...args: any[]): FluentRuleCustomizer; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - required(): FluentRuleCustomizer; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - matches(regex: RegExp): FluentRuleCustomizer; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - email(): FluentRuleCustomizer; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - minLength(length: number): FluentRuleCustomizer; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - maxLength(length: number): FluentRuleCustomizer; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - minItems(count: number): FluentRuleCustomizer; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - maxItems(count: number): FluentRuleCustomizer; - /** - * Applies the "equals" validation rule to the property. - * null and undefined values are considered valid. - */ - equals(expectedValue: TValue): FluentRuleCustomizer; -} -/** - * Part of the fluent rule API. Enables targeting properties and objects with rules. - */ -export declare class FluentEnsure { - private parsers; - /** - * Rules that have been defined using the fluent API. - */ - rules: Rule[][]; - constructor(parsers: Parsers); - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor - * function. - */ - ensure(property: string | number | PropertyAccessor): FluentRules; - /** - * Targets an object with validation rules. - */ - ensureObject(): FluentRules; - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - on(target: any): this; - private assertInitialized(); - private mergeRules(fluentRules, propertyName); -} -/** - * Fluent rule definition API. - */ -export declare class ValidationRules { - private static parsers; - static initialize(messageParser: ValidationMessageParser, propertyParser: PropertyAccessorParser): void; - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - static ensure(property: string | number | PropertyAccessor): FluentRules; - /** - * Targets an object with validation rules. - */ - static ensureObject(): FluentRules; - /** - * Defines a custom rule. - * @param name The name of the custom rule. Also serves as the message key. - * @param condition The rule function. - * @param message The message expression - * @param argsToConfig A function that maps the rule's arguments to a "config" - * object that can be used when evaluating the message expression. - */ - static customRule(name: string, condition: (value: any, object?: any, ...args: any[]) => boolean | Promise, message: string, argsToConfig?: (...args: any[]) => any): void; - /** - * Returns rules with the matching tag. - * @param rules The rules to search. - * @param tag The tag to search for. - */ - static taggedRules(rules: Rule[][], tag: string): Rule[][]; - /** - * Returns rules that have no tag. - * @param rules The rules to search. - */ - static untaggedRules(rules: Rule[][]): Rule[][]; - /** - * Removes the rules from a class or object. - * @param target A class or object. - */ - static off(target: any): void; -} -export interface Parsers { - message: ValidationMessageParser; - property: PropertyAccessorParser; -} diff --git a/dist/native-modules/implementation/validation-rules.js b/dist/native-modules/implementation/validation-rules.js deleted file mode 100644 index 549a1d5c..00000000 --- a/dist/native-modules/implementation/validation-rules.js +++ /dev/null @@ -1,442 +0,0 @@ -import { Rules } from './rules'; -import { validationMessages } from './validation-messages'; -import { isString } from '../util'; -/** - * Part of the fluent rule API. Enables customizing property rules. - */ -var FluentRuleCustomizer = /** @class */ (function () { - function FluentRuleCustomizer(property, condition, config, fluentEnsure, fluentRules, parsers) { - if (config === void 0) { config = {}; } - this.fluentEnsure = fluentEnsure; - this.fluentRules = fluentRules; - this.parsers = parsers; - this.rule = { - property: property, - condition: condition, - config: config, - when: null, - messageKey: 'default', - message: null, - sequence: fluentRules.sequence - }; - this.fluentEnsure._addRule(this.rule); - } - /** - * Validate subsequent rules after previously declared rules have - * been validated successfully. Use to postpone validation of costly - * rules until less expensive rules pass validation. - */ - FluentRuleCustomizer.prototype.then = function () { - this.fluentRules.sequence++; - return this; - }; - /** - * Specifies the key to use when looking up the rule's validation message. - */ - FluentRuleCustomizer.prototype.withMessageKey = function (key) { - this.rule.messageKey = key; - this.rule.message = null; - return this; - }; - /** - * Specifies rule's validation message. - */ - FluentRuleCustomizer.prototype.withMessage = function (message) { - this.rule.messageKey = 'custom'; - this.rule.message = this.parsers.message.parse(message); - return this; - }; - /** - * Specifies a condition that must be met before attempting to validate the rule. - * @param condition A function that accepts the object as a parameter and returns true - * or false whether the rule should be evaluated. - */ - FluentRuleCustomizer.prototype.when = function (condition) { - this.rule.when = condition; - return this; - }; - /** - * Tags the rule instance, enabling the rule to be found easily - * using ValidationRules.taggedRules(rules, tag) - */ - FluentRuleCustomizer.prototype.tag = function (tag) { - this.rule.tag = tag; - return this; - }; - ///// FluentEnsure APIs ///// - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - FluentRuleCustomizer.prototype.ensure = function (subject) { - return this.fluentEnsure.ensure(subject); - }; - /** - * Targets an object with validation rules. - */ - FluentRuleCustomizer.prototype.ensureObject = function () { - return this.fluentEnsure.ensureObject(); - }; - Object.defineProperty(FluentRuleCustomizer.prototype, "rules", { - /** - * Rules that have been defined using the fluent API. - */ - get: function () { - return this.fluentEnsure.rules; - }, - enumerable: true, - configurable: true - }); - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - FluentRuleCustomizer.prototype.on = function (target) { - return this.fluentEnsure.on(target); - }; - ///////// FluentRules APIs ///////// - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - FluentRuleCustomizer.prototype.satisfies = function (condition, config) { - return this.fluentRules.satisfies(condition, config); - }; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - FluentRuleCustomizer.prototype.satisfiesRule = function (name) { - var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; - } - return (_a = this.fluentRules).satisfiesRule.apply(_a, [name].concat(args)); - var _a; - }; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - FluentRuleCustomizer.prototype.required = function () { - return this.fluentRules.required(); - }; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.matches = function (regex) { - return this.fluentRules.matches(regex); - }; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.email = function () { - return this.fluentRules.email(); - }; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.minLength = function (length) { - return this.fluentRules.minLength(length); - }; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.maxLength = function (length) { - return this.fluentRules.maxLength(length); - }; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRuleCustomizer.prototype.minItems = function (count) { - return this.fluentRules.minItems(count); - }; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRuleCustomizer.prototype.maxItems = function (count) { - return this.fluentRules.maxItems(count); - }; - /** - * Applies the "equals" validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.equals = function (expectedValue) { - return this.fluentRules.equals(expectedValue); - }; - return FluentRuleCustomizer; -}()); -export { FluentRuleCustomizer }; -/** - * Part of the fluent rule API. Enables applying rules to properties and objects. - */ -var FluentRules = /** @class */ (function () { - function FluentRules(fluentEnsure, parsers, property) { - this.fluentEnsure = fluentEnsure; - this.parsers = parsers; - this.property = property; - /** - * Current rule sequence number. Used to postpone evaluation of rules until rules - * with lower sequence number have successfully validated. The "then" fluent API method - * manages this property, there's usually no need to set it directly. - */ - this.sequence = 0; - } - /** - * Sets the display name of the ensured property. - */ - FluentRules.prototype.displayName = function (name) { - this.property.displayName = name; - return this; - }; - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - FluentRules.prototype.satisfies = function (condition, config) { - return new FluentRuleCustomizer(this.property, condition, config, this.fluentEnsure, this, this.parsers); - }; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - FluentRules.prototype.satisfiesRule = function (name) { - var _this = this; - var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; - } - var rule = FluentRules.customRules[name]; - if (!rule) { - // standard rule? - rule = this[name]; - if (rule instanceof Function) { - return rule.call.apply(rule, [this].concat(args)); - } - throw new Error("Rule with name \"" + name + "\" does not exist."); - } - var config = rule.argsToConfig ? rule.argsToConfig.apply(rule, args) : undefined; - return this.satisfies(function (value, obj) { - return (_a = rule.condition).call.apply(_a, [_this, value, obj].concat(args)); - var _a; - }, config) - .withMessageKey(name); - }; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - FluentRules.prototype.required = function () { - return this.satisfies(function (value) { - return value !== null - && value !== undefined - && !(isString(value) && !/\S/.test(value)); - }).withMessageKey('required'); - }; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - FluentRules.prototype.matches = function (regex) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || regex.test(value); }) - .withMessageKey('matches'); - }; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRules.prototype.email = function () { - // regex from https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address - /* tslint:disable:max-line-length */ - return this.matches(/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/) - .withMessageKey('email'); - }; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRules.prototype.minLength = function (length) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || value.length >= length; }, { length: length }) - .withMessageKey('minLength'); - }; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRules.prototype.maxLength = function (length) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || value.length <= length; }, { length: length }) - .withMessageKey('maxLength'); - }; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRules.prototype.minItems = function (count) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length >= count; }, { count: count }) - .withMessageKey('minItems'); - }; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRules.prototype.maxItems = function (count) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length <= count; }, { count: count }) - .withMessageKey('maxItems'); - }; - /** - * Applies the "equals" validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRules.prototype.equals = function (expectedValue) { - return this.satisfies(function (value) { return value === null || value === undefined || value === '' || value === expectedValue; }, { expectedValue: expectedValue }) - .withMessageKey('equals'); - }; - FluentRules.customRules = {}; - return FluentRules; -}()); -export { FluentRules }; -/** - * Part of the fluent rule API. Enables targeting properties and objects with rules. - */ -var FluentEnsure = /** @class */ (function () { - function FluentEnsure(parsers) { - this.parsers = parsers; - /** - * Rules that have been defined using the fluent API. - */ - this.rules = []; - } - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor - * function. - */ - FluentEnsure.prototype.ensure = function (property) { - this.assertInitialized(); - var name = this.parsers.property.parse(property); - var fluentRules = new FluentRules(this, this.parsers, { name: name, displayName: null }); - return this.mergeRules(fluentRules, name); - }; - /** - * Targets an object with validation rules. - */ - FluentEnsure.prototype.ensureObject = function () { - this.assertInitialized(); - var fluentRules = new FluentRules(this, this.parsers, { name: null, displayName: null }); - return this.mergeRules(fluentRules, null); - }; - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - FluentEnsure.prototype.on = function (target) { - Rules.set(target, this.rules); - return this; - }; - /** - * Adds a rule definition to the sequenced ruleset. - * @internal - */ - FluentEnsure.prototype._addRule = function (rule) { - while (this.rules.length < rule.sequence + 1) { - this.rules.push([]); - } - this.rules[rule.sequence].push(rule); - }; - FluentEnsure.prototype.assertInitialized = function () { - if (this.parsers) { - return; - } - throw new Error("Did you forget to add \".plugin('aurelia-validation')\" to your main.js?"); - }; - FluentEnsure.prototype.mergeRules = function (fluentRules, propertyName) { - // tslint:disable-next-line:triple-equals | Use loose equality for property keys - var existingRules = this.rules.find(function (r) { return r.length > 0 && r[0].property.name == propertyName; }); - if (existingRules) { - var rule = existingRules[existingRules.length - 1]; - fluentRules.sequence = rule.sequence; - if (rule.property.displayName !== null) { - fluentRules = fluentRules.displayName(rule.property.displayName); - } - } - return fluentRules; - }; - return FluentEnsure; -}()); -export { FluentEnsure }; -/** - * Fluent rule definition API. - */ -var ValidationRules = /** @class */ (function () { - function ValidationRules() { - } - ValidationRules.initialize = function (messageParser, propertyParser) { - this.parsers = { - message: messageParser, - property: propertyParser - }; - }; - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - ValidationRules.ensure = function (property) { - return new FluentEnsure(ValidationRules.parsers).ensure(property); - }; - /** - * Targets an object with validation rules. - */ - ValidationRules.ensureObject = function () { - return new FluentEnsure(ValidationRules.parsers).ensureObject(); - }; - /** - * Defines a custom rule. - * @param name The name of the custom rule. Also serves as the message key. - * @param condition The rule function. - * @param message The message expression - * @param argsToConfig A function that maps the rule's arguments to a "config" - * object that can be used when evaluating the message expression. - */ - ValidationRules.customRule = function (name, condition, message, argsToConfig) { - validationMessages[name] = message; - FluentRules.customRules[name] = { condition: condition, argsToConfig: argsToConfig }; - }; - /** - * Returns rules with the matching tag. - * @param rules The rules to search. - * @param tag The tag to search for. - */ - ValidationRules.taggedRules = function (rules, tag) { - return rules.map(function (x) { return x.filter(function (r) { return r.tag === tag; }); }); - }; - /** - * Returns rules that have no tag. - * @param rules The rules to search. - */ - ValidationRules.untaggedRules = function (rules) { - return rules.map(function (x) { return x.filter(function (r) { return r.tag === undefined; }); }); - }; - /** - * Removes the rules from a class or object. - * @param target A class or object. - */ - ValidationRules.off = function (target) { - Rules.unset(target); - }; - return ValidationRules; -}()); -export { ValidationRules }; diff --git a/dist/native-modules/property-accessor-parser.d.ts b/dist/native-modules/property-accessor-parser.d.ts deleted file mode 100644 index ba64614b..00000000 --- a/dist/native-modules/property-accessor-parser.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Parser } from 'aurelia-binding'; -export declare type PropertyAccessor = (object: TObject) => TValue; -export declare class PropertyAccessorParser { - private parser; - static inject: (typeof Parser)[]; - constructor(parser: Parser); - parse(property: string | number | PropertyAccessor): string | number; -} -export declare function getAccessorExpression(fn: string): string; diff --git a/dist/native-modules/property-accessor-parser.js b/dist/native-modules/property-accessor-parser.js deleted file mode 100644 index d56baad8..00000000 --- a/dist/native-modules/property-accessor-parser.js +++ /dev/null @@ -1,33 +0,0 @@ -import { Parser, AccessMember, AccessScope } from 'aurelia-binding'; -import { isString, isNumber } from './util'; -var PropertyAccessorParser = /** @class */ (function () { - function PropertyAccessorParser(parser) { - this.parser = parser; - } - PropertyAccessorParser.prototype.parse = function (property) { - if (isString(property) || isNumber(property)) { - return property; - } - var accessorText = getAccessorExpression(property.toString()); - var accessor = this.parser.parse(accessorText); - if (accessor instanceof AccessScope - || accessor instanceof AccessMember && accessor.object instanceof AccessScope) { - return accessor.name; - } - throw new Error("Invalid property expression: \"" + accessor + "\""); - }; - PropertyAccessorParser.inject = [Parser]; - return PropertyAccessorParser; -}()); -export { PropertyAccessorParser }; -export function getAccessorExpression(fn) { - /* tslint:disable:max-line-length */ - var classic = /^function\s*\([$_\w\d]+\)\s*\{(?:\s*"use strict";)?\s*(?:[$_\w\d.['"\]+;]+)?\s*return\s+[$_\w\d]+\.([$_\w\d]+)\s*;?\s*\}$/; - /* tslint:enable:max-line-length */ - var arrow = /^\(?[$_\w\d]+\)?\s*=>\s*[$_\w\d]+\.([$_\w\d]+)$/; - var match = classic.exec(fn) || arrow.exec(fn); - if (match === null) { - throw new Error("Unable to parse accessor function:\n" + fn); - } - return match[1]; -} diff --git a/dist/native-modules/property-info.d.ts b/dist/native-modules/property-info.d.ts deleted file mode 100644 index 35fef1d5..00000000 --- a/dist/native-modules/property-info.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Expression, Scope } from 'aurelia-binding'; -/** - * Retrieves the object and property name for the specified expression. - * @param expression The expression - * @param source The scope - */ -export declare function getPropertyInfo(expression: Expression, source: Scope): { - object: object; - propertyName: string; -} | null; diff --git a/dist/native-modules/property-info.js b/dist/native-modules/property-info.js deleted file mode 100644 index d6b39d2e..00000000 --- a/dist/native-modules/property-info.js +++ /dev/null @@ -1,41 +0,0 @@ -import { AccessMember, AccessScope, AccessKeyed, BindingBehavior, ValueConverter, getContextFor } from 'aurelia-binding'; -function getObject(expression, objectExpression, source) { - var value = objectExpression.evaluate(source, null); - if (value === null || value === undefined || value instanceof Object) { - return value; - } - // tslint:disable-next-line:max-line-length - throw new Error("The '" + objectExpression + "' part of '" + expression + "' evaluates to " + value + " instead of an object, null or undefined."); -} -/** - * Retrieves the object and property name for the specified expression. - * @param expression The expression - * @param source The scope - */ -export function getPropertyInfo(expression, source) { - var originalExpression = expression; - while (expression instanceof BindingBehavior || expression instanceof ValueConverter) { - expression = expression.expression; - } - var object; - var propertyName; - if (expression instanceof AccessScope) { - object = getContextFor(expression.name, source, expression.ancestor); - propertyName = expression.name; - } - else if (expression instanceof AccessMember) { - object = getObject(originalExpression, expression.object, source); - propertyName = expression.name; - } - else if (expression instanceof AccessKeyed) { - object = getObject(originalExpression, expression.object, source); - propertyName = expression.key.evaluate(source); - } - else { - throw new Error("Expression '" + originalExpression + "' is not compatible with the validate binding-behavior."); - } - if (object === null || object === undefined) { - return null; - } - return { object: object, propertyName: propertyName }; -} diff --git a/dist/native-modules/util.d.ts b/dist/native-modules/util.d.ts deleted file mode 100644 index f6873f03..00000000 --- a/dist/native-modules/util.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export declare function isString(value: any): boolean; -export declare function isNumber(value: any): boolean; diff --git a/dist/native-modules/util.js b/dist/native-modules/util.js deleted file mode 100644 index 8b4ad402..00000000 --- a/dist/native-modules/util.js +++ /dev/null @@ -1,6 +0,0 @@ -export function isString(value) { - return Object.prototype.toString.call(value) === '[object String]'; -} -export function isNumber(value) { - return Object.prototype.toString.call(value) === '[object Number]'; -} diff --git a/dist/native-modules/validate-binding-behavior-base.d.ts b/dist/native-modules/validate-binding-behavior-base.d.ts deleted file mode 100644 index 971c8e83..00000000 --- a/dist/native-modules/validate-binding-behavior-base.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { TaskQueue } from 'aurelia-task-queue'; -import { ValidationController } from './validation-controller'; -import { validateTrigger } from './validate-trigger'; -/** - * Binding behavior. Indicates the bound property should be validated. - */ -export declare abstract class ValidateBindingBehaviorBase { - private taskQueue; - constructor(taskQueue: TaskQueue); - protected abstract getValidateTrigger(controller: ValidationController): validateTrigger; - bind(binding: any, source: any, rulesOrController?: ValidationController | any, rules?: any): void; - unbind(binding: any): void; -} diff --git a/dist/native-modules/validate-binding-behavior-base.js b/dist/native-modules/validate-binding-behavior-base.js deleted file mode 100644 index b7f64619..00000000 --- a/dist/native-modules/validate-binding-behavior-base.js +++ /dev/null @@ -1,79 +0,0 @@ -import { Optional } from 'aurelia-dependency-injection'; -import { ValidationController } from './validation-controller'; -import { validateTrigger } from './validate-trigger'; -import { getTargetDOMElement } from './get-target-dom-element'; -/** - * Binding behavior. Indicates the bound property should be validated. - */ -var ValidateBindingBehaviorBase = /** @class */ (function () { - function ValidateBindingBehaviorBase(taskQueue) { - this.taskQueue = taskQueue; - } - ValidateBindingBehaviorBase.prototype.bind = function (binding, source, rulesOrController, rules) { - var _this = this; - // identify the target element. - var target = getTargetDOMElement(binding, source); - // locate the controller. - var controller; - if (rulesOrController instanceof ValidationController) { - controller = rulesOrController; - } - else { - controller = source.container.get(Optional.of(ValidationController)); - rules = rulesOrController; - } - if (controller === null) { - throw new Error("A ValidationController has not been registered."); - } - controller.registerBinding(binding, target, rules); - binding.validationController = controller; - var trigger = this.getValidateTrigger(controller); - // tslint:disable-next-line:no-bitwise - if (trigger & validateTrigger.change) { - binding.vbbUpdateSource = binding.updateSource; - // tslint:disable-next-line:only-arrow-functions - // tslint:disable-next-line:space-before-function-paren - binding.updateSource = function (value) { - this.vbbUpdateSource(value); - this.validationController.validateBinding(this); - }; - } - // tslint:disable-next-line:no-bitwise - if (trigger & validateTrigger.blur) { - binding.validateBlurHandler = function () { - _this.taskQueue.queueMicroTask(function () { return controller.validateBinding(binding); }); - }; - binding.validateTarget = target; - target.addEventListener('blur', binding.validateBlurHandler); - } - if (trigger !== validateTrigger.manual) { - binding.standardUpdateTarget = binding.updateTarget; - // tslint:disable-next-line:only-arrow-functions - // tslint:disable-next-line:space-before-function-paren - binding.updateTarget = function (value) { - this.standardUpdateTarget(value); - this.validationController.resetBinding(this); - }; - } - }; - ValidateBindingBehaviorBase.prototype.unbind = function (binding) { - // reset the binding to it's original state. - if (binding.vbbUpdateSource) { - binding.updateSource = binding.vbbUpdateSource; - binding.vbbUpdateSource = null; - } - if (binding.standardUpdateTarget) { - binding.updateTarget = binding.standardUpdateTarget; - binding.standardUpdateTarget = null; - } - if (binding.validateBlurHandler) { - binding.validateTarget.removeEventListener('blur', binding.validateBlurHandler); - binding.validateBlurHandler = null; - binding.validateTarget = null; - } - binding.validationController.unregisterBinding(binding); - binding.validationController = null; - }; - return ValidateBindingBehaviorBase; -}()); -export { ValidateBindingBehaviorBase }; diff --git a/dist/native-modules/validate-binding-behavior.d.ts b/dist/native-modules/validate-binding-behavior.d.ts deleted file mode 100644 index 08b5d9e0..00000000 --- a/dist/native-modules/validate-binding-behavior.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { TaskQueue } from 'aurelia-task-queue'; -import { ValidationController } from './validation-controller'; -import { validateTrigger } from './validate-trigger'; -import { ValidateBindingBehaviorBase } from './validate-binding-behavior-base'; -/** - * Binding behavior. Indicates the bound property should be validated - * when the validate trigger specified by the associated controller's - * validateTrigger property occurs. - */ -export declare class ValidateBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(controller: ValidationController): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property will be validated - * manually, by calling controller.validate(). No automatic validation - * triggered by data-entry or blur will occur. - */ -export declare class ValidateManuallyBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs. - */ -export declare class ValidateOnBlurBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element is changed by the user, causing a change - * to the model. - */ -export declare class ValidateOnChangeBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs or is changed by the user, causing - * a change to the model. - */ -export declare class ValidateOnChangeOrBlurBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} diff --git a/dist/native-modules/validate-binding-behavior.js b/dist/native-modules/validate-binding-behavior.js deleted file mode 100644 index 7c635e45..00000000 --- a/dist/native-modules/validate-binding-behavior.js +++ /dev/null @@ -1,97 +0,0 @@ -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -import { TaskQueue } from 'aurelia-task-queue'; -import { validateTrigger } from './validate-trigger'; -import { ValidateBindingBehaviorBase } from './validate-binding-behavior-base'; -/** - * Binding behavior. Indicates the bound property should be validated - * when the validate trigger specified by the associated controller's - * validateTrigger property occurs. - */ -var ValidateBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateBindingBehavior, _super); - function ValidateBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateBindingBehavior.prototype.getValidateTrigger = function (controller) { - return controller.validateTrigger; - }; - ValidateBindingBehavior.inject = [TaskQueue]; - return ValidateBindingBehavior; -}(ValidateBindingBehaviorBase)); -export { ValidateBindingBehavior }; -/** - * Binding behavior. Indicates the bound property will be validated - * manually, by calling controller.validate(). No automatic validation - * triggered by data-entry or blur will occur. - */ -var ValidateManuallyBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateManuallyBindingBehavior, _super); - function ValidateManuallyBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateManuallyBindingBehavior.prototype.getValidateTrigger = function () { - return validateTrigger.manual; - }; - ValidateManuallyBindingBehavior.inject = [TaskQueue]; - return ValidateManuallyBindingBehavior; -}(ValidateBindingBehaviorBase)); -export { ValidateManuallyBindingBehavior }; -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs. - */ -var ValidateOnBlurBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateOnBlurBindingBehavior, _super); - function ValidateOnBlurBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateOnBlurBindingBehavior.prototype.getValidateTrigger = function () { - return validateTrigger.blur; - }; - ValidateOnBlurBindingBehavior.inject = [TaskQueue]; - return ValidateOnBlurBindingBehavior; -}(ValidateBindingBehaviorBase)); -export { ValidateOnBlurBindingBehavior }; -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element is changed by the user, causing a change - * to the model. - */ -var ValidateOnChangeBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateOnChangeBindingBehavior, _super); - function ValidateOnChangeBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateOnChangeBindingBehavior.prototype.getValidateTrigger = function () { - return validateTrigger.change; - }; - ValidateOnChangeBindingBehavior.inject = [TaskQueue]; - return ValidateOnChangeBindingBehavior; -}(ValidateBindingBehaviorBase)); -export { ValidateOnChangeBindingBehavior }; -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs or is changed by the user, causing - * a change to the model. - */ -var ValidateOnChangeOrBlurBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateOnChangeOrBlurBindingBehavior, _super); - function ValidateOnChangeOrBlurBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateOnChangeOrBlurBindingBehavior.prototype.getValidateTrigger = function () { - return validateTrigger.changeOrBlur; - }; - ValidateOnChangeOrBlurBindingBehavior.inject = [TaskQueue]; - return ValidateOnChangeOrBlurBindingBehavior; -}(ValidateBindingBehaviorBase)); -export { ValidateOnChangeOrBlurBindingBehavior }; diff --git a/dist/native-modules/validate-event.d.ts b/dist/native-modules/validate-event.d.ts deleted file mode 100644 index 0fbacbb7..00000000 --- a/dist/native-modules/validate-event.d.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { ValidateResult } from './validate-result'; -import { ValidateInstruction } from './validate-instruction'; -import { ControllerValidateResult } from './controller-validate-result'; -export declare class ValidateEvent { - /** - * The type of validate event. Either "validate" or "reset". - */ - readonly type: 'validate' | 'reset'; - /** - * The controller's current array of errors. For an array containing both - * failed rules and passed rules, use the "results" property. - */ - readonly errors: ValidateResult[]; - /** - * The controller's current array of validate results. This - * includes both passed rules and failed rules. For an array of only failed rules, - * use the "errors" property. - */ - readonly results: ValidateResult[]; - /** - * The instruction passed to the "validate" or "reset" event. Will be null when - * the controller's validate/reset method was called with no instruction argument. - */ - readonly instruction: ValidateInstruction | null; - /** - * In events with type === "validate", this property will contain the result - * of validating the instruction (see "instruction" property). Use the controllerValidateResult - * to access the validate results specific to the call to "validate" - * (as opposed to using the "results" and "errors" properties to access the controller's entire - * set of results/errors). - */ - readonly controllerValidateResult: ControllerValidateResult | null; - constructor( - /** - * The type of validate event. Either "validate" or "reset". - */ - type: 'validate' | 'reset', - /** - * The controller's current array of errors. For an array containing both - * failed rules and passed rules, use the "results" property. - */ - errors: ValidateResult[], - /** - * The controller's current array of validate results. This - * includes both passed rules and failed rules. For an array of only failed rules, - * use the "errors" property. - */ - results: ValidateResult[], - /** - * The instruction passed to the "validate" or "reset" event. Will be null when - * the controller's validate/reset method was called with no instruction argument. - */ - instruction: ValidateInstruction | null, - /** - * In events with type === "validate", this property will contain the result - * of validating the instruction (see "instruction" property). Use the controllerValidateResult - * to access the validate results specific to the call to "validate" - * (as opposed to using the "results" and "errors" properties to access the controller's entire - * set of results/errors). - */ - controllerValidateResult: ControllerValidateResult | null); -} diff --git a/dist/native-modules/validate-event.js b/dist/native-modules/validate-event.js deleted file mode 100644 index 905d1199..00000000 --- a/dist/native-modules/validate-event.js +++ /dev/null @@ -1,39 +0,0 @@ -var ValidateEvent = /** @class */ (function () { - function ValidateEvent( - /** - * The type of validate event. Either "validate" or "reset". - */ - type, - /** - * The controller's current array of errors. For an array containing both - * failed rules and passed rules, use the "results" property. - */ - errors, - /** - * The controller's current array of validate results. This - * includes both passed rules and failed rules. For an array of only failed rules, - * use the "errors" property. - */ - results, - /** - * The instruction passed to the "validate" or "reset" event. Will be null when - * the controller's validate/reset method was called with no instruction argument. - */ - instruction, - /** - * In events with type === "validate", this property will contain the result - * of validating the instruction (see "instruction" property). Use the controllerValidateResult - * to access the validate results specific to the call to "validate" - * (as opposed to using the "results" and "errors" properties to access the controller's entire - * set of results/errors). - */ - controllerValidateResult) { - this.type = type; - this.errors = errors; - this.results = results; - this.instruction = instruction; - this.controllerValidateResult = controllerValidateResult; - } - return ValidateEvent; -}()); -export { ValidateEvent }; diff --git a/dist/native-modules/validate-instruction.d.ts b/dist/native-modules/validate-instruction.d.ts deleted file mode 100644 index 2f792a70..00000000 --- a/dist/native-modules/validate-instruction.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Instructions for the validation controller's validate method. - */ -export interface ValidateInstruction { - /** - * The object to validate. - */ - object: any; - /** - * The property to validate. Optional. - */ - propertyName?: any; - /** - * The rules to validate. Optional. - */ - rules?: any; -} diff --git a/dist/native-modules/validate-instruction.js b/dist/native-modules/validate-instruction.js deleted file mode 100644 index e69de29b..00000000 diff --git a/dist/native-modules/validate-result.d.ts b/dist/native-modules/validate-result.d.ts deleted file mode 100644 index 91d79995..00000000 --- a/dist/native-modules/validate-result.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * The result of validating an individual validation rule. - */ -export declare class ValidateResult { - rule: any; - object: any; - propertyName: string | number | null; - valid: boolean; - message: string | null; - private static nextId; - /** - * A number that uniquely identifies the result instance. - */ - id: number; - /** - * @param rule The rule associated with the result. Validator implementation specific. - * @param object The object that was validated. - * @param propertyName The name of the property that was validated. - * @param error The error, if the result is a validation error. - */ - constructor(rule: any, object: any, propertyName: string | number | null, valid: boolean, message?: string | null); - toString(): string | null; -} diff --git a/dist/native-modules/validate-result.js b/dist/native-modules/validate-result.js deleted file mode 100644 index 6381f3b6..00000000 --- a/dist/native-modules/validate-result.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * The result of validating an individual validation rule. - */ -var ValidateResult = /** @class */ (function () { - /** - * @param rule The rule associated with the result. Validator implementation specific. - * @param object The object that was validated. - * @param propertyName The name of the property that was validated. - * @param error The error, if the result is a validation error. - */ - function ValidateResult(rule, object, propertyName, valid, message) { - if (message === void 0) { message = null; } - this.rule = rule; - this.object = object; - this.propertyName = propertyName; - this.valid = valid; - this.message = message; - this.id = ValidateResult.nextId++; - } - ValidateResult.prototype.toString = function () { - return this.valid ? 'Valid.' : this.message; - }; - ValidateResult.nextId = 0; - return ValidateResult; -}()); -export { ValidateResult }; diff --git a/dist/native-modules/validate-trigger.d.ts b/dist/native-modules/validate-trigger.d.ts deleted file mode 100644 index 43e76851..00000000 --- a/dist/native-modules/validate-trigger.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Validation triggers. - */ -export declare enum validateTrigger { - /** - * Manual validation. Use the controller's `validate()` and `reset()` methods - * to validate all bindings. - */ - manual = 0, - /** - * Validate the binding when the binding's target element fires a DOM "blur" event. - */ - blur = 1, - /** - * Validate the binding when it updates the model due to a change in the view. - */ - change = 2, - /** - * Validate the binding when the binding's target element fires a DOM "blur" event and - * when it updates the model due to a change in the view. - */ - changeOrBlur = 3, -} diff --git a/dist/native-modules/validate-trigger.js b/dist/native-modules/validate-trigger.js deleted file mode 100644 index c00b9e21..00000000 --- a/dist/native-modules/validate-trigger.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Validation triggers. - */ -export var validateTrigger; -(function (validateTrigger) { - /** - * Manual validation. Use the controller's `validate()` and `reset()` methods - * to validate all bindings. - */ - validateTrigger[validateTrigger["manual"] = 0] = "manual"; - /** - * Validate the binding when the binding's target element fires a DOM "blur" event. - */ - validateTrigger[validateTrigger["blur"] = 1] = "blur"; - /** - * Validate the binding when it updates the model due to a change in the view. - */ - validateTrigger[validateTrigger["change"] = 2] = "change"; - /** - * Validate the binding when the binding's target element fires a DOM "blur" event and - * when it updates the model due to a change in the view. - */ - validateTrigger[validateTrigger["changeOrBlur"] = 3] = "changeOrBlur"; -})(validateTrigger || (validateTrigger = {})); diff --git a/dist/native-modules/validation-controller-factory.d.ts b/dist/native-modules/validation-controller-factory.d.ts deleted file mode 100644 index 2c51999e..00000000 --- a/dist/native-modules/validation-controller-factory.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Container } from 'aurelia-dependency-injection'; -import { ValidationController } from './validation-controller'; -import { Validator } from './validator'; -/** - * Creates ValidationController instances. - */ -export declare class ValidationControllerFactory { - private container; - static get(container: Container): ValidationControllerFactory; - constructor(container: Container); - /** - * Creates a new controller instance. - */ - create(validator?: Validator): ValidationController; - /** - * Creates a new controller and registers it in the current element's container so that it's - * available to the validate binding behavior and renderers. - */ - createForCurrentScope(validator?: Validator): ValidationController; -} diff --git a/dist/native-modules/validation-controller-factory.js b/dist/native-modules/validation-controller-factory.js deleted file mode 100644 index 43e3831f..00000000 --- a/dist/native-modules/validation-controller-factory.js +++ /dev/null @@ -1,36 +0,0 @@ -import { ValidationController } from './validation-controller'; -import { Validator } from './validator'; -import { PropertyAccessorParser } from './property-accessor-parser'; -/** - * Creates ValidationController instances. - */ -var ValidationControllerFactory = /** @class */ (function () { - function ValidationControllerFactory(container) { - this.container = container; - } - ValidationControllerFactory.get = function (container) { - return new ValidationControllerFactory(container); - }; - /** - * Creates a new controller instance. - */ - ValidationControllerFactory.prototype.create = function (validator) { - if (!validator) { - validator = this.container.get(Validator); - } - var propertyParser = this.container.get(PropertyAccessorParser); - return new ValidationController(validator, propertyParser); - }; - /** - * Creates a new controller and registers it in the current element's container so that it's - * available to the validate binding behavior and renderers. - */ - ValidationControllerFactory.prototype.createForCurrentScope = function (validator) { - var controller = this.create(validator); - this.container.registerInstance(ValidationController, controller); - return controller; - }; - return ValidationControllerFactory; -}()); -export { ValidationControllerFactory }; -ValidationControllerFactory['protocol:aurelia:resolver'] = true; diff --git a/dist/native-modules/validation-controller.d.ts b/dist/native-modules/validation-controller.d.ts deleted file mode 100644 index 7f208d49..00000000 --- a/dist/native-modules/validation-controller.d.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { Binding } from 'aurelia-binding'; -import { Validator } from './validator'; -import { validateTrigger } from './validate-trigger'; -import { ValidationRenderer } from './validation-renderer'; -import { ValidateResult } from './validate-result'; -import { ValidateInstruction } from './validate-instruction'; -import { ControllerValidateResult } from './controller-validate-result'; -import { PropertyAccessorParser, PropertyAccessor } from './property-accessor-parser'; -import { ValidateEvent } from './validate-event'; -/** - * Orchestrates validation. - * Manages a set of bindings, renderers and objects. - * Exposes the current list of validation results for binding purposes. - */ -export declare class ValidationController { - private validator; - private propertyParser; - static inject: (typeof PropertyAccessorParser | typeof Validator)[]; - private bindings; - private renderers; - /** - * Validation results that have been rendered by the controller. - */ - private results; - /** - * Validation errors that have been rendered by the controller. - */ - errors: ValidateResult[]; - /** - * Whether the controller is currently validating. - */ - validating: boolean; - private elements; - private objects; - /** - * The trigger that will invoke automatic validation of a property used in a binding. - */ - validateTrigger: validateTrigger; - private finishValidating; - private eventCallbacks; - constructor(validator: Validator, propertyParser: PropertyAccessorParser); - /** - * Subscribe to controller validate and reset events. These events occur when the - * controller's "validate"" and "reset" methods are called. - * @param callback The callback to be invoked when the controller validates or resets. - */ - subscribe(callback: (event: ValidateEvent) => void): { - dispose: () => void; - }; - /** - * Adds an object to the set of objects that should be validated when validate is called. - * @param object The object. - * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. - */ - addObject(object: any, rules?: any): void; - /** - * Removes an object from the set of objects that should be validated when validate is called. - * @param object The object. - */ - removeObject(object: any): void; - /** - * Adds and renders an error. - */ - addError(message: string, object: TObject, propertyName?: string | PropertyAccessor | null): ValidateResult; - /** - * Removes and unrenders an error. - */ - removeError(result: ValidateResult): void; - /** - * Adds a renderer. - * @param renderer The renderer. - */ - addRenderer(renderer: ValidationRenderer): void; - /** - * Removes a renderer. - * @param renderer The renderer. - */ - removeRenderer(renderer: ValidationRenderer): void; - /** - * Registers a binding with the controller. - * @param binding The binding instance. - * @param target The DOM element. - * @param rules (optional) rules associated with the binding. Validator implementation specific. - */ - registerBinding(binding: Binding, target: Element, rules?: any): void; - /** - * Unregisters a binding with the controller. - * @param binding The binding instance. - */ - unregisterBinding(binding: Binding): void; - /** - * Interprets the instruction and returns a predicate that will identify - * relevant results in the list of rendered validation results. - */ - private getInstructionPredicate(instruction?); - /** - * Validates and renders results. - * @param instruction Optional. Instructions on what to validate. If undefined, all - * objects and bindings will be validated. - */ - validate(instruction?: ValidateInstruction): Promise; - /** - * Resets any rendered validation results (unrenders). - * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results - * will be unrendered. - */ - reset(instruction?: ValidateInstruction): void; - /** - * Gets the elements associated with an object and propertyName (if any). - */ - private getAssociatedElements({object, propertyName}); - private processResultDelta(kind, oldResults, newResults); - /** - * Validates the property associated with a binding. - */ - validateBinding(binding: Binding): void; - /** - * Resets the results for a property associated with a binding. - */ - resetBinding(binding: Binding): void; - /** - * Changes the controller's validateTrigger. - * @param newTrigger The new validateTrigger - */ - changeTrigger(newTrigger: validateTrigger): void; - /** - * Revalidates the controller's current set of errors. - */ - revalidateErrors(): void; - private invokeCallbacks(instruction, result); -} diff --git a/dist/native-modules/validation-controller.js b/dist/native-modules/validation-controller.js deleted file mode 100644 index 71a545f3..00000000 --- a/dist/native-modules/validation-controller.js +++ /dev/null @@ -1,413 +0,0 @@ -import { Validator } from './validator'; -import { validateTrigger } from './validate-trigger'; -import { getPropertyInfo } from './property-info'; -import { ValidateResult } from './validate-result'; -import { PropertyAccessorParser } from './property-accessor-parser'; -import { ValidateEvent } from './validate-event'; -/** - * Orchestrates validation. - * Manages a set of bindings, renderers and objects. - * Exposes the current list of validation results for binding purposes. - */ -var ValidationController = /** @class */ (function () { - function ValidationController(validator, propertyParser) { - this.validator = validator; - this.propertyParser = propertyParser; - // Registered bindings (via the validate binding behavior) - this.bindings = new Map(); - // Renderers that have been added to the controller instance. - this.renderers = []; - /** - * Validation results that have been rendered by the controller. - */ - this.results = []; - /** - * Validation errors that have been rendered by the controller. - */ - this.errors = []; - /** - * Whether the controller is currently validating. - */ - this.validating = false; - // Elements related to validation results that have been rendered. - this.elements = new Map(); - // Objects that have been added to the controller instance (entity-style validation). - this.objects = new Map(); - /** - * The trigger that will invoke automatic validation of a property used in a binding. - */ - this.validateTrigger = validateTrigger.blur; - // Promise that resolves when validation has completed. - this.finishValidating = Promise.resolve(); - this.eventCallbacks = []; - } - /** - * Subscribe to controller validate and reset events. These events occur when the - * controller's "validate"" and "reset" methods are called. - * @param callback The callback to be invoked when the controller validates or resets. - */ - ValidationController.prototype.subscribe = function (callback) { - var _this = this; - this.eventCallbacks.push(callback); - return { - dispose: function () { - var index = _this.eventCallbacks.indexOf(callback); - if (index === -1) { - return; - } - _this.eventCallbacks.splice(index, 1); - } - }; - }; - /** - * Adds an object to the set of objects that should be validated when validate is called. - * @param object The object. - * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. - */ - ValidationController.prototype.addObject = function (object, rules) { - this.objects.set(object, rules); - }; - /** - * Removes an object from the set of objects that should be validated when validate is called. - * @param object The object. - */ - ValidationController.prototype.removeObject = function (object) { - this.objects.delete(object); - this.processResultDelta('reset', this.results.filter(function (result) { return result.object === object; }), []); - }; - /** - * Adds and renders an error. - */ - ValidationController.prototype.addError = function (message, object, propertyName) { - if (propertyName === void 0) { propertyName = null; } - var resolvedPropertyName; - if (propertyName === null) { - resolvedPropertyName = propertyName; - } - else { - resolvedPropertyName = this.propertyParser.parse(propertyName); - } - var result = new ValidateResult({ __manuallyAdded__: true }, object, resolvedPropertyName, false, message); - this.processResultDelta('validate', [], [result]); - return result; - }; - /** - * Removes and unrenders an error. - */ - ValidationController.prototype.removeError = function (result) { - if (this.results.indexOf(result) !== -1) { - this.processResultDelta('reset', [result], []); - } - }; - /** - * Adds a renderer. - * @param renderer The renderer. - */ - ValidationController.prototype.addRenderer = function (renderer) { - var _this = this; - this.renderers.push(renderer); - renderer.render({ - kind: 'validate', - render: this.results.map(function (result) { return ({ result: result, elements: _this.elements.get(result) }); }), - unrender: [] - }); - }; - /** - * Removes a renderer. - * @param renderer The renderer. - */ - ValidationController.prototype.removeRenderer = function (renderer) { - var _this = this; - this.renderers.splice(this.renderers.indexOf(renderer), 1); - renderer.render({ - kind: 'reset', - render: [], - unrender: this.results.map(function (result) { return ({ result: result, elements: _this.elements.get(result) }); }) - }); - }; - /** - * Registers a binding with the controller. - * @param binding The binding instance. - * @param target The DOM element. - * @param rules (optional) rules associated with the binding. Validator implementation specific. - */ - ValidationController.prototype.registerBinding = function (binding, target, rules) { - this.bindings.set(binding, { target: target, rules: rules, propertyInfo: null }); - }; - /** - * Unregisters a binding with the controller. - * @param binding The binding instance. - */ - ValidationController.prototype.unregisterBinding = function (binding) { - this.resetBinding(binding); - this.bindings.delete(binding); - }; - /** - * Interprets the instruction and returns a predicate that will identify - * relevant results in the list of rendered validation results. - */ - ValidationController.prototype.getInstructionPredicate = function (instruction) { - var _this = this; - if (instruction) { - var object_1 = instruction.object, propertyName_1 = instruction.propertyName, rules_1 = instruction.rules; - var predicate_1; - if (instruction.propertyName) { - predicate_1 = function (x) { return x.object === object_1 && x.propertyName === propertyName_1; }; - } - else { - predicate_1 = function (x) { return x.object === object_1; }; - } - if (rules_1) { - return function (x) { return predicate_1(x) && _this.validator.ruleExists(rules_1, x.rule); }; - } - return predicate_1; - } - else { - return function () { return true; }; - } - }; - /** - * Validates and renders results. - * @param instruction Optional. Instructions on what to validate. If undefined, all - * objects and bindings will be validated. - */ - ValidationController.prototype.validate = function (instruction) { - var _this = this; - // Get a function that will process the validation instruction. - var execute; - if (instruction) { - // tslint:disable-next-line:prefer-const - var object_2 = instruction.object, propertyName_2 = instruction.propertyName, rules_2 = instruction.rules; - // if rules were not specified, check the object map. - rules_2 = rules_2 || this.objects.get(object_2); - // property specified? - if (instruction.propertyName === undefined) { - // validate the specified object. - execute = function () { return _this.validator.validateObject(object_2, rules_2); }; - } - else { - // validate the specified property. - execute = function () { return _this.validator.validateProperty(object_2, propertyName_2, rules_2); }; - } - } - else { - // validate all objects and bindings. - execute = function () { - var promises = []; - for (var _i = 0, _a = Array.from(_this.objects); _i < _a.length; _i++) { - var _b = _a[_i], object = _b[0], rules = _b[1]; - promises.push(_this.validator.validateObject(object, rules)); - } - for (var _c = 0, _d = Array.from(_this.bindings); _c < _d.length; _c++) { - var _e = _d[_c], binding = _e[0], rules = _e[1].rules; - var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); - if (!propertyInfo || _this.objects.has(propertyInfo.object)) { - continue; - } - promises.push(_this.validator.validateProperty(propertyInfo.object, propertyInfo.propertyName, rules)); - } - return Promise.all(promises).then(function (resultSets) { return resultSets.reduce(function (a, b) { return a.concat(b); }, []); }); - }; - } - // Wait for any existing validation to finish, execute the instruction, render the results. - this.validating = true; - var returnPromise = this.finishValidating - .then(execute) - .then(function (newResults) { - var predicate = _this.getInstructionPredicate(instruction); - var oldResults = _this.results.filter(predicate); - _this.processResultDelta('validate', oldResults, newResults); - if (returnPromise === _this.finishValidating) { - _this.validating = false; - } - var result = { - instruction: instruction, - valid: newResults.find(function (x) { return !x.valid; }) === undefined, - results: newResults - }; - _this.invokeCallbacks(instruction, result); - return result; - }) - .catch(function (exception) { - // recover, to enable subsequent calls to validate() - _this.validating = false; - _this.finishValidating = Promise.resolve(); - return Promise.reject(exception); - }); - this.finishValidating = returnPromise; - return returnPromise; - }; - /** - * Resets any rendered validation results (unrenders). - * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results - * will be unrendered. - */ - ValidationController.prototype.reset = function (instruction) { - var predicate = this.getInstructionPredicate(instruction); - var oldResults = this.results.filter(predicate); - this.processResultDelta('reset', oldResults, []); - this.invokeCallbacks(instruction, null); - }; - /** - * Gets the elements associated with an object and propertyName (if any). - */ - ValidationController.prototype.getAssociatedElements = function (_a) { - var object = _a.object, propertyName = _a.propertyName; - var elements = []; - for (var _i = 0, _b = Array.from(this.bindings); _i < _b.length; _i++) { - var _c = _b[_i], binding = _c[0], target = _c[1].target; - var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); - if (propertyInfo && propertyInfo.object === object && propertyInfo.propertyName === propertyName) { - elements.push(target); - } - } - return elements; - }; - ValidationController.prototype.processResultDelta = function (kind, oldResults, newResults) { - // prepare the instruction. - var instruction = { - kind: kind, - render: [], - unrender: [] - }; - // create a shallow copy of newResults so we can mutate it without causing side-effects. - newResults = newResults.slice(0); - var _loop_1 = function (oldResult) { - // get the elements associated with the old result. - var elements = this_1.elements.get(oldResult); - // remove the old result from the element map. - this_1.elements.delete(oldResult); - // create the unrender instruction. - instruction.unrender.push({ result: oldResult, elements: elements }); - // determine if there's a corresponding new result for the old result we are unrendering. - var newResultIndex = newResults.findIndex(function (x) { return x.rule === oldResult.rule && x.object === oldResult.object && x.propertyName === oldResult.propertyName; }); - if (newResultIndex === -1) { - // no corresponding new result... simple remove. - this_1.results.splice(this_1.results.indexOf(oldResult), 1); - if (!oldResult.valid) { - this_1.errors.splice(this_1.errors.indexOf(oldResult), 1); - } - } - else { - // there is a corresponding new result... - var newResult = newResults.splice(newResultIndex, 1)[0]; - // get the elements that are associated with the new result. - var elements_1 = this_1.getAssociatedElements(newResult); - this_1.elements.set(newResult, elements_1); - // create a render instruction for the new result. - instruction.render.push({ result: newResult, elements: elements_1 }); - // do an in-place replacement of the old result with the new result. - // this ensures any repeats bound to this.results will not thrash. - this_1.results.splice(this_1.results.indexOf(oldResult), 1, newResult); - if (!oldResult.valid && newResult.valid) { - this_1.errors.splice(this_1.errors.indexOf(oldResult), 1); - } - else if (!oldResult.valid && !newResult.valid) { - this_1.errors.splice(this_1.errors.indexOf(oldResult), 1, newResult); - } - else if (!newResult.valid) { - this_1.errors.push(newResult); - } - } - }; - var this_1 = this; - // create unrender instructions from the old results. - for (var _i = 0, oldResults_1 = oldResults; _i < oldResults_1.length; _i++) { - var oldResult = oldResults_1[_i]; - _loop_1(oldResult); - } - // create render instructions from the remaining new results. - for (var _a = 0, newResults_1 = newResults; _a < newResults_1.length; _a++) { - var result = newResults_1[_a]; - var elements = this.getAssociatedElements(result); - instruction.render.push({ result: result, elements: elements }); - this.elements.set(result, elements); - this.results.push(result); - if (!result.valid) { - this.errors.push(result); - } - } - // render. - for (var _b = 0, _c = this.renderers; _b < _c.length; _b++) { - var renderer = _c[_b]; - renderer.render(instruction); - } - }; - /** - * Validates the property associated with a binding. - */ - ValidationController.prototype.validateBinding = function (binding) { - if (!binding.isBound) { - return; - } - var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); - var rules; - var registeredBinding = this.bindings.get(binding); - if (registeredBinding) { - rules = registeredBinding.rules; - registeredBinding.propertyInfo = propertyInfo; - } - if (!propertyInfo) { - return; - } - var object = propertyInfo.object, propertyName = propertyInfo.propertyName; - this.validate({ object: object, propertyName: propertyName, rules: rules }); - }; - /** - * Resets the results for a property associated with a binding. - */ - ValidationController.prototype.resetBinding = function (binding) { - var registeredBinding = this.bindings.get(binding); - var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); - if (!propertyInfo && registeredBinding) { - propertyInfo = registeredBinding.propertyInfo; - } - if (registeredBinding) { - registeredBinding.propertyInfo = null; - } - if (!propertyInfo) { - return; - } - var object = propertyInfo.object, propertyName = propertyInfo.propertyName; - this.reset({ object: object, propertyName: propertyName }); - }; - /** - * Changes the controller's validateTrigger. - * @param newTrigger The new validateTrigger - */ - ValidationController.prototype.changeTrigger = function (newTrigger) { - this.validateTrigger = newTrigger; - var bindings = Array.from(this.bindings.keys()); - for (var _i = 0, bindings_1 = bindings; _i < bindings_1.length; _i++) { - var binding = bindings_1[_i]; - var source = binding.source; - binding.unbind(); - binding.bind(source); - } - }; - /** - * Revalidates the controller's current set of errors. - */ - ValidationController.prototype.revalidateErrors = function () { - for (var _i = 0, _a = this.errors; _i < _a.length; _i++) { - var _b = _a[_i], object = _b.object, propertyName = _b.propertyName, rule = _b.rule; - if (rule.__manuallyAdded__) { - continue; - } - var rules = [[rule]]; - this.validate({ object: object, propertyName: propertyName, rules: rules }); - } - }; - ValidationController.prototype.invokeCallbacks = function (instruction, result) { - if (this.eventCallbacks.length === 0) { - return; - } - var event = new ValidateEvent(result ? 'validate' : 'reset', this.errors, this.results, instruction || null, result); - for (var i = 0; i < this.eventCallbacks.length; i++) { - this.eventCallbacks[i](event); - } - }; - ValidationController.inject = [Validator, PropertyAccessorParser]; - return ValidationController; -}()); -export { ValidationController }; diff --git a/dist/native-modules/validation-errors-custom-attribute.d.ts b/dist/native-modules/validation-errors-custom-attribute.d.ts deleted file mode 100644 index 056e08ea..00000000 --- a/dist/native-modules/validation-errors-custom-attribute.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Lazy } from 'aurelia-dependency-injection'; -import { ValidationController } from './validation-controller'; -import { ValidateResult } from './validate-result'; -import { ValidationRenderer, RenderInstruction } from './validation-renderer'; -export interface RenderedError { - error: ValidateResult; - targets: Element[]; -} -export declare class ValidationErrorsCustomAttribute implements ValidationRenderer { - private boundaryElement; - private controllerAccessor; - static inject(): ({ - new (): Element; - prototype: Element; - } | Lazy)[]; - controller: ValidationController | null; - errors: RenderedError[]; - private errorsInternal; - constructor(boundaryElement: Element, controllerAccessor: () => ValidationController); - sort(): void; - interestingElements(elements: Element[]): Element[]; - render(instruction: RenderInstruction): void; - bind(): void; - unbind(): void; -} diff --git a/dist/native-modules/validation-errors-custom-attribute.js b/dist/native-modules/validation-errors-custom-attribute.js deleted file mode 100644 index 629efe28..00000000 --- a/dist/native-modules/validation-errors-custom-attribute.js +++ /dev/null @@ -1,82 +0,0 @@ -var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -}; -import { bindingMode } from 'aurelia-binding'; -import { Lazy } from 'aurelia-dependency-injection'; -import { customAttribute, bindable } from 'aurelia-templating'; -import { ValidationController } from './validation-controller'; -import { DOM } from 'aurelia-pal'; -var ValidationErrorsCustomAttribute = /** @class */ (function () { - function ValidationErrorsCustomAttribute(boundaryElement, controllerAccessor) { - this.boundaryElement = boundaryElement; - this.controllerAccessor = controllerAccessor; - this.controller = null; - this.errors = []; - this.errorsInternal = []; - } - ValidationErrorsCustomAttribute.inject = function () { return [DOM.Element, Lazy.of(ValidationController)]; }; - ValidationErrorsCustomAttribute.prototype.sort = function () { - this.errorsInternal.sort(function (a, b) { - if (a.targets[0] === b.targets[0]) { - return 0; - } - // tslint:disable-next-line:no-bitwise - return a.targets[0].compareDocumentPosition(b.targets[0]) & 2 ? 1 : -1; - }); - }; - ValidationErrorsCustomAttribute.prototype.interestingElements = function (elements) { - var _this = this; - return elements.filter(function (e) { return _this.boundaryElement.contains(e); }); - }; - ValidationErrorsCustomAttribute.prototype.render = function (instruction) { - var _loop_1 = function (result) { - var index = this_1.errorsInternal.findIndex(function (x) { return x.error === result; }); - if (index !== -1) { - this_1.errorsInternal.splice(index, 1); - } - }; - var this_1 = this; - for (var _i = 0, _a = instruction.unrender; _i < _a.length; _i++) { - var result = _a[_i].result; - _loop_1(result); - } - for (var _b = 0, _c = instruction.render; _b < _c.length; _b++) { - var _d = _c[_b], result = _d.result, elements = _d.elements; - if (result.valid) { - continue; - } - var targets = this.interestingElements(elements); - if (targets.length) { - this.errorsInternal.push({ error: result, targets: targets }); - } - } - this.sort(); - this.errors = this.errorsInternal; - }; - ValidationErrorsCustomAttribute.prototype.bind = function () { - if (!this.controller) { - this.controller = this.controllerAccessor(); - } - // this will call render() with the side-effect of updating this.errors - this.controller.addRenderer(this); - }; - ValidationErrorsCustomAttribute.prototype.unbind = function () { - if (this.controller) { - this.controller.removeRenderer(this); - } - }; - __decorate([ - bindable({ defaultBindingMode: bindingMode.oneWay }) - ], ValidationErrorsCustomAttribute.prototype, "controller", void 0); - __decorate([ - bindable({ primaryProperty: true, defaultBindingMode: bindingMode.twoWay }) - ], ValidationErrorsCustomAttribute.prototype, "errors", void 0); - ValidationErrorsCustomAttribute = __decorate([ - customAttribute('validation-errors') - ], ValidationErrorsCustomAttribute); - return ValidationErrorsCustomAttribute; -}()); -export { ValidationErrorsCustomAttribute }; diff --git a/dist/native-modules/validation-renderer-custom-attribute.d.ts b/dist/native-modules/validation-renderer-custom-attribute.d.ts deleted file mode 100644 index 9f48614e..00000000 --- a/dist/native-modules/validation-renderer-custom-attribute.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export declare class ValidationRendererCustomAttribute { - private container; - private controller; - private value; - private renderer; - created(view: any): void; - bind(): void; - unbind(): void; -} diff --git a/dist/native-modules/validation-renderer-custom-attribute.js b/dist/native-modules/validation-renderer-custom-attribute.js deleted file mode 100644 index 07f071d2..00000000 --- a/dist/native-modules/validation-renderer-custom-attribute.js +++ /dev/null @@ -1,20 +0,0 @@ -import { ValidationController } from './validation-controller'; -var ValidationRendererCustomAttribute = /** @class */ (function () { - function ValidationRendererCustomAttribute() { - } - ValidationRendererCustomAttribute.prototype.created = function (view) { - this.container = view.container; - }; - ValidationRendererCustomAttribute.prototype.bind = function () { - this.controller = this.container.get(ValidationController); - this.renderer = this.container.get(this.value); - this.controller.addRenderer(this.renderer); - }; - ValidationRendererCustomAttribute.prototype.unbind = function () { - this.controller.removeRenderer(this.renderer); - this.controller = null; - this.renderer = null; - }; - return ValidationRendererCustomAttribute; -}()); -export { ValidationRendererCustomAttribute }; diff --git a/dist/native-modules/validation-renderer.d.ts b/dist/native-modules/validation-renderer.d.ts deleted file mode 100644 index eb430d9d..00000000 --- a/dist/native-modules/validation-renderer.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { ValidateResult } from './validate-result'; -/** - * A result to render (or unrender) and the associated elements (if any) - */ -export interface ResultInstruction { - /** - * The validation result. - */ - result: ValidateResult; - /** - * The associated elements (if any). - */ - elements: Element[]; -} -/** - * Defines which validation results to render and which validation results to unrender. - */ -export interface RenderInstruction { - /** - * The "kind" of render instruction. Either 'validate' or 'reset'. - */ - kind: 'validate' | 'reset'; - /** - * The results to render. - */ - render: ResultInstruction[]; - /** - * The results to unrender. - */ - unrender: ResultInstruction[]; -} -/** - * Renders validation results. - */ -export interface ValidationRenderer { - /** - * Render the validation results. - * @param instruction The render instruction. Defines which results to render and which - * results to unrender. - */ - render(instruction: RenderInstruction): void; -} diff --git a/dist/native-modules/validation-renderer.js b/dist/native-modules/validation-renderer.js deleted file mode 100644 index e69de29b..00000000 diff --git a/dist/native-modules/validator.d.ts b/dist/native-modules/validator.d.ts deleted file mode 100644 index 82c045e8..00000000 --- a/dist/native-modules/validator.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ValidateResult } from './validate-result'; -/** - * Validates objects and properties. - */ -export declare abstract class Validator { - /** - * Validates the specified property. - * @param object The object to validate. - * @param propertyName The name of the property to validate. - * @param rules Optional. If unspecified, the implementation should lookup the rules for the - * specified object. This may not be possible for all implementations of this interface. - */ - abstract validateProperty(object: any, propertyName: string, rules?: any): Promise; - /** - * Validates all rules for specified object and it's properties. - * @param object The object to validate. - * @param rules Optional. If unspecified, the implementation should lookup the rules for the - * specified object. This may not be possible for all implementations of this interface. - */ - abstract validateObject(object: any, rules?: any): Promise; - /** - * Determines whether a rule exists in a set of rules. - * @param rules The rules to search. - * @parem rule The rule to find. - */ - abstract ruleExists(rules: any, rule: any): boolean; -} diff --git a/dist/native-modules/validator.js b/dist/native-modules/validator.js deleted file mode 100644 index 801fae55..00000000 --- a/dist/native-modules/validator.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Validates objects and properties. - */ -var Validator = /** @class */ (function () { - function Validator() { - } - return Validator; -}()); -export { Validator }; diff --git a/dist/system/aurelia-validation.d.ts b/dist/system/aurelia-validation.d.ts deleted file mode 100644 index d744ccfb..00000000 --- a/dist/system/aurelia-validation.d.ts +++ /dev/null @@ -1,46 +0,0 @@ -export * from './controller-validate-result'; -export * from './get-target-dom-element'; -export * from './property-info'; -export * from './property-accessor-parser'; -export * from './validate-binding-behavior'; -export * from './validate-event'; -export * from './validate-instruction'; -export * from './validate-result'; -export * from './validate-trigger'; -export * from './validation-controller'; -export * from './validation-controller-factory'; -export * from './validation-errors-custom-attribute'; -export * from './validation-renderer-custom-attribute'; -export * from './validation-renderer'; -export * from './validator'; -export * from './implementation/rule'; -export * from './implementation/rules'; -export * from './implementation/standard-validator'; -export * from './implementation/validation-messages'; -export * from './implementation/validation-message-parser'; -export * from './implementation/validation-rules'; -import { Container } from 'aurelia-dependency-injection'; -import { Validator } from './validator'; -/** - * Aurelia Validation Configuration API - */ -export declare class AureliaValidationConfiguration { - private validatorType; - /** - * Use a custom Validator implementation. - */ - customValidator(type: { - new (...args: any[]): Validator; - }): void; - /** - * Applies the configuration. - */ - apply(container: Container): void; -} -/** - * Configures the plugin. - */ -export declare function configure(frameworkConfig: { - container: Container; - globalResources?: (...resources: string[]) => any; -}, callback?: (config: AureliaValidationConfiguration) => void): void; diff --git a/dist/system/aurelia-validation.js b/dist/system/aurelia-validation.js index 0c1054e0..7e6fa206 100644 --- a/dist/system/aurelia-validation.js +++ b/dist/system/aurelia-validation.js @@ -1,126 +1,1811 @@ -// Exports -System.register(["./get-target-dom-element", "./property-info", "./property-accessor-parser", "./validate-binding-behavior", "./validate-event", "./validate-result", "./validate-trigger", "./validation-controller", "./validation-controller-factory", "./validation-errors-custom-attribute", "./validation-renderer-custom-attribute", "./validator", "./implementation/rules", "./implementation/standard-validator", "./implementation/validation-messages", "./implementation/validation-message-parser", "./implementation/validation-rules", "aurelia-pal"], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - /** - * Configures the plugin. - */ - function configure(frameworkConfig, callback) { - // the fluent rule definition API needs the parser to translate messages - // to interpolation expressions. - var messageParser = frameworkConfig.container.get(validation_message_parser_1.ValidationMessageParser); - var propertyParser = frameworkConfig.container.get(property_accessor_parser_1.PropertyAccessorParser); - validation_rules_1.ValidationRules.initialize(messageParser, propertyParser); - // configure... - var config = new AureliaValidationConfiguration(); - if (callback instanceof Function) { - callback(config); - } - config.apply(frameworkConfig.container); - // globalize the behaviors. - if (frameworkConfig.globalResources) { - frameworkConfig.globalResources(aurelia_pal_1.PLATFORM.moduleName('./validate-binding-behavior'), aurelia_pal_1.PLATFORM.moduleName('./validation-errors-custom-attribute'), aurelia_pal_1.PLATFORM.moduleName('./validation-renderer-custom-attribute')); - } +System.register(['aurelia-pal', 'aurelia-binding', 'aurelia-dependency-injection', 'aurelia-task-queue', 'aurelia-templating', 'aurelia-framework', 'aurelia-logging'], function (exports, module) { + 'use strict'; + var DOM, AccessMember, AccessScope, AccessKeyed, BindingBehavior, ValueConverter, getContextFor, Parser, bindingMode, LiteralString, Binary, Conditional, LiteralPrimitive, CallMember, Optional, Lazy, TaskQueue, customAttribute, bindable, BindingLanguage, ViewResources, customAttribute$1, getLogger; + return { + setters: [function (module) { + DOM = module.DOM; + }, function (module) { + AccessMember = module.AccessMember; + AccessScope = module.AccessScope; + AccessKeyed = module.AccessKeyed; + BindingBehavior = module.BindingBehavior; + ValueConverter = module.ValueConverter; + getContextFor = module.getContextFor; + Parser = module.Parser; + bindingMode = module.bindingMode; + LiteralString = module.LiteralString; + Binary = module.Binary; + Conditional = module.Conditional; + LiteralPrimitive = module.LiteralPrimitive; + CallMember = module.CallMember; + }, function (module) { + Optional = module.Optional; + Lazy = module.Lazy; + }, function (module) { + TaskQueue = module.TaskQueue; + }, function (module) { + customAttribute = module.customAttribute; + bindable = module.bindable; + BindingLanguage = module.BindingLanguage; + ViewResources = module.ViewResources; + }, function (module) { + customAttribute$1 = module.customAttribute; + }, function (module) { + getLogger = module.getLogger; + }], + execute: function () { + + exports({ + configure: configure, + getTargetDOMElement: getTargetDOMElement, + getPropertyInfo: getPropertyInfo, + getAccessorExpression: getAccessorExpression, + validateTrigger: void 0 + }); + + /** + * Gets the DOM element associated with the data-binding. Most of the time it's + * the binding.target but sometimes binding.target is an aurelia custom element, + * or custom attribute which is a javascript "class" instance, so we need to use + * the controller's container to retrieve the actual DOM element. + */ + function getTargetDOMElement(binding, view) { + var target = binding.target; + // DOM element + if (target instanceof Element) { + return target; + } + // custom element or custom attribute + // tslint:disable-next-line:prefer-const + for (var i = 0, ii = view.controllers.length; i < ii; i++) { + var controller = view.controllers[i]; + if (controller.viewModel === target) { + var element = controller.container.get(DOM.Element); + if (element) { + return element; + } + throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\"."); + } + } + throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\"."); + } + + function getObject(expression, objectExpression, source) { + var value = objectExpression.evaluate(source, null); + if (value === null || value === undefined || value instanceof Object) { + return value; + } + // tslint:disable-next-line:max-line-length + throw new Error("The '" + objectExpression + "' part of '" + expression + "' evaluates to " + value + " instead of an object, null or undefined."); + } + /** + * Retrieves the object and property name for the specified expression. + * @param expression The expression + * @param source The scope + */ + function getPropertyInfo(expression, source) { + var originalExpression = expression; + while (expression instanceof BindingBehavior || expression instanceof ValueConverter) { + expression = expression.expression; + } + var object; + var propertyName; + if (expression instanceof AccessScope) { + object = getContextFor(expression.name, source, expression.ancestor); + propertyName = expression.name; + } + else if (expression instanceof AccessMember) { + object = getObject(originalExpression, expression.object, source); + propertyName = expression.name; + } + else if (expression instanceof AccessKeyed) { + object = getObject(originalExpression, expression.object, source); + propertyName = expression.key.evaluate(source); + } + else { + throw new Error("Expression '" + originalExpression + "' is not compatible with the validate binding-behavior."); + } + if (object === null || object === undefined) { + return null; + } + return { object: object, propertyName: propertyName }; + } + + function isString(value) { + return Object.prototype.toString.call(value) === '[object String]'; + } + function isNumber(value) { + return Object.prototype.toString.call(value) === '[object Number]'; + } + + var PropertyAccessorParser = exports('PropertyAccessorParser', /** @class */ (function () { + function PropertyAccessorParser(parser) { + this.parser = parser; + } + PropertyAccessorParser.prototype.parse = function (property) { + if (isString(property) || isNumber(property)) { + return property; + } + var accessorText = getAccessorExpression(property.toString()); + var accessor = this.parser.parse(accessorText); + if (accessor instanceof AccessScope + || accessor instanceof AccessMember && accessor.object instanceof AccessScope) { + return accessor.name; + } + throw new Error("Invalid property expression: \"" + accessor + "\""); + }; + PropertyAccessorParser.inject = [Parser]; + return PropertyAccessorParser; + }())); + function getAccessorExpression(fn) { + /* tslint:disable:max-line-length */ + var classic = /^function\s*\([$_\w\d]+\)\s*\{(?:\s*"use strict";)?\s*(?:[$_\w\d.['"\]+;]+)?\s*return\s+[$_\w\d]+\.([$_\w\d]+)\s*;?\s*\}$/; + /* tslint:enable:max-line-length */ + var arrow = /^\(?[$_\w\d]+\)?\s*=>\s*[$_\w\d]+\.([$_\w\d]+)$/; + var match = classic.exec(fn) || arrow.exec(fn); + if (match === null) { + throw new Error("Unable to parse accessor function:\n" + fn); + } + return match[1]; + } + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. All rights reserved. + Licensed under the Apache License, Version 2.0 (the "License"); you may not use + this file except in compliance with the License. You may obtain a copy of the + License at http://www.apache.org/licenses/LICENSE-2.0 + + THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED + WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, + MERCHANTABLITY OR NON-INFRINGEMENT. + + See the Apache Version 2.0 License for specific language governing permissions + and limitations under the License. + ***************************************************************************** */ + /* global Reflect, Promise */ + + var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + + function __extends(d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + + function __decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + } + + /** + * Validation triggers. + */ + var validateTrigger; + (function (validateTrigger) { + /** + * Manual validation. Use the controller's `validate()` and `reset()` methods + * to validate all bindings. + */ + validateTrigger[validateTrigger["manual"] = 0] = "manual"; + /** + * Validate the binding when the binding's target element fires a DOM "blur" event. + */ + validateTrigger[validateTrigger["blur"] = 1] = "blur"; + /** + * Validate the binding when it updates the model due to a change in the view. + */ + validateTrigger[validateTrigger["change"] = 2] = "change"; + /** + * Validate the binding when the binding's target element fires a DOM "blur" event and + * when it updates the model due to a change in the view. + */ + validateTrigger[validateTrigger["changeOrBlur"] = 3] = "changeOrBlur"; + })(validateTrigger || (validateTrigger = exports('validateTrigger', {}))); + + /** + * Validates objects and properties. + */ + var Validator = exports('Validator', /** @class */ (function () { + function Validator() { + } + return Validator; + }())); + + /** + * The result of validating an individual validation rule. + */ + var ValidateResult = exports('ValidateResult', /** @class */ (function () { + /** + * @param rule The rule associated with the result. Validator implementation specific. + * @param object The object that was validated. + * @param propertyName The name of the property that was validated. + * @param error The error, if the result is a validation error. + */ + function ValidateResult(rule, object, propertyName, valid, message) { + if (message === void 0) { message = null; } + this.rule = rule; + this.object = object; + this.propertyName = propertyName; + this.valid = valid; + this.message = message; + this.id = ValidateResult.nextId++; + } + ValidateResult.prototype.toString = function () { + return this.valid ? 'Valid.' : this.message; + }; + ValidateResult.nextId = 0; + return ValidateResult; + }())); + + var ValidateEvent = exports('ValidateEvent', /** @class */ (function () { + function ValidateEvent( + /** + * The type of validate event. Either "validate" or "reset". + */ + type, + /** + * The controller's current array of errors. For an array containing both + * failed rules and passed rules, use the "results" property. + */ + errors, + /** + * The controller's current array of validate results. This + * includes both passed rules and failed rules. For an array of only failed rules, + * use the "errors" property. + */ + results, + /** + * The instruction passed to the "validate" or "reset" event. Will be null when + * the controller's validate/reset method was called with no instruction argument. + */ + instruction, + /** + * In events with type === "validate", this property will contain the result + * of validating the instruction (see "instruction" property). Use the controllerValidateResult + * to access the validate results specific to the call to "validate" + * (as opposed to using the "results" and "errors" properties to access the controller's entire + * set of results/errors). + */ + controllerValidateResult) { + this.type = type; + this.errors = errors; + this.results = results; + this.instruction = instruction; + this.controllerValidateResult = controllerValidateResult; + } + return ValidateEvent; + }())); + + /** + * Orchestrates validation. + * Manages a set of bindings, renderers and objects. + * Exposes the current list of validation results for binding purposes. + */ + var ValidationController = exports('ValidationController', /** @class */ (function () { + function ValidationController(validator, propertyParser) { + this.validator = validator; + this.propertyParser = propertyParser; + // Registered bindings (via the validate binding behavior) + this.bindings = new Map(); + // Renderers that have been added to the controller instance. + this.renderers = []; + /** + * Validation results that have been rendered by the controller. + */ + this.results = []; + /** + * Validation errors that have been rendered by the controller. + */ + this.errors = []; + /** + * Whether the controller is currently validating. + */ + this.validating = false; + // Elements related to validation results that have been rendered. + this.elements = new Map(); + // Objects that have been added to the controller instance (entity-style validation). + this.objects = new Map(); + /** + * The trigger that will invoke automatic validation of a property used in a binding. + */ + this.validateTrigger = validateTrigger.blur; + // Promise that resolves when validation has completed. + this.finishValidating = Promise.resolve(); + this.eventCallbacks = []; + } + /** + * Subscribe to controller validate and reset events. These events occur when the + * controller's "validate"" and "reset" methods are called. + * @param callback The callback to be invoked when the controller validates or resets. + */ + ValidationController.prototype.subscribe = function (callback) { + var _this = this; + this.eventCallbacks.push(callback); + return { + dispose: function () { + var index = _this.eventCallbacks.indexOf(callback); + if (index === -1) { + return; + } + _this.eventCallbacks.splice(index, 1); + } + }; + }; + /** + * Adds an object to the set of objects that should be validated when validate is called. + * @param object The object. + * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. + */ + ValidationController.prototype.addObject = function (object, rules) { + this.objects.set(object, rules); + }; + /** + * Removes an object from the set of objects that should be validated when validate is called. + * @param object The object. + */ + ValidationController.prototype.removeObject = function (object) { + this.objects.delete(object); + this.processResultDelta('reset', this.results.filter(function (result) { return result.object === object; }), []); + }; + /** + * Adds and renders an error. + */ + ValidationController.prototype.addError = function (message, object, propertyName) { + if (propertyName === void 0) { propertyName = null; } + var resolvedPropertyName; + if (propertyName === null) { + resolvedPropertyName = propertyName; + } + else { + resolvedPropertyName = this.propertyParser.parse(propertyName); + } + var result = new ValidateResult({ __manuallyAdded__: true }, object, resolvedPropertyName, false, message); + this.processResultDelta('validate', [], [result]); + return result; + }; + /** + * Removes and unrenders an error. + */ + ValidationController.prototype.removeError = function (result) { + if (this.results.indexOf(result) !== -1) { + this.processResultDelta('reset', [result], []); + } + }; + /** + * Adds a renderer. + * @param renderer The renderer. + */ + ValidationController.prototype.addRenderer = function (renderer) { + var _this = this; + this.renderers.push(renderer); + renderer.render({ + kind: 'validate', + render: this.results.map(function (result) { return ({ result: result, elements: _this.elements.get(result) }); }), + unrender: [] + }); + }; + /** + * Removes a renderer. + * @param renderer The renderer. + */ + ValidationController.prototype.removeRenderer = function (renderer) { + var _this = this; + this.renderers.splice(this.renderers.indexOf(renderer), 1); + renderer.render({ + kind: 'reset', + render: [], + unrender: this.results.map(function (result) { return ({ result: result, elements: _this.elements.get(result) }); }) + }); + }; + /** + * Registers a binding with the controller. + * @param binding The binding instance. + * @param target The DOM element. + * @param rules (optional) rules associated with the binding. Validator implementation specific. + */ + ValidationController.prototype.registerBinding = function (binding, target, rules) { + this.bindings.set(binding, { target: target, rules: rules, propertyInfo: null }); + }; + /** + * Unregisters a binding with the controller. + * @param binding The binding instance. + */ + ValidationController.prototype.unregisterBinding = function (binding) { + this.resetBinding(binding); + this.bindings.delete(binding); + }; + /** + * Interprets the instruction and returns a predicate that will identify + * relevant results in the list of rendered validation results. + */ + ValidationController.prototype.getInstructionPredicate = function (instruction) { + var _this = this; + if (instruction) { + var object_1 = instruction.object, propertyName_1 = instruction.propertyName, rules_1 = instruction.rules; + var predicate_1; + if (instruction.propertyName) { + predicate_1 = function (x) { return x.object === object_1 && x.propertyName === propertyName_1; }; + } + else { + predicate_1 = function (x) { return x.object === object_1; }; + } + if (rules_1) { + return function (x) { return predicate_1(x) && _this.validator.ruleExists(rules_1, x.rule); }; + } + return predicate_1; + } + else { + return function () { return true; }; + } + }; + /** + * Validates and renders results. + * @param instruction Optional. Instructions on what to validate. If undefined, all + * objects and bindings will be validated. + */ + ValidationController.prototype.validate = function (instruction) { + var _this = this; + // Get a function that will process the validation instruction. + var execute; + if (instruction) { + // tslint:disable-next-line:prefer-const + var object_2 = instruction.object, propertyName_2 = instruction.propertyName, rules_2 = instruction.rules; + // if rules were not specified, check the object map. + rules_2 = rules_2 || this.objects.get(object_2); + // property specified? + if (instruction.propertyName === undefined) { + // validate the specified object. + execute = function () { return _this.validator.validateObject(object_2, rules_2); }; + } + else { + // validate the specified property. + execute = function () { return _this.validator.validateProperty(object_2, propertyName_2, rules_2); }; + } + } + else { + // validate all objects and bindings. + execute = function () { + var promises = []; + for (var _i = 0, _a = Array.from(_this.objects); _i < _a.length; _i++) { + var _b = _a[_i], object = _b[0], rules = _b[1]; + promises.push(_this.validator.validateObject(object, rules)); + } + for (var _c = 0, _d = Array.from(_this.bindings); _c < _d.length; _c++) { + var _e = _d[_c], binding = _e[0], rules = _e[1].rules; + var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + if (!propertyInfo || _this.objects.has(propertyInfo.object)) { + continue; + } + promises.push(_this.validator.validateProperty(propertyInfo.object, propertyInfo.propertyName, rules)); + } + return Promise.all(promises).then(function (resultSets) { return resultSets.reduce(function (a, b) { return a.concat(b); }, []); }); + }; + } + // Wait for any existing validation to finish, execute the instruction, render the results. + this.validating = true; + var returnPromise = this.finishValidating + .then(execute) + .then(function (newResults) { + var predicate = _this.getInstructionPredicate(instruction); + var oldResults = _this.results.filter(predicate); + _this.processResultDelta('validate', oldResults, newResults); + if (returnPromise === _this.finishValidating) { + _this.validating = false; + } + var result = { + instruction: instruction, + valid: newResults.find(function (x) { return !x.valid; }) === undefined, + results: newResults + }; + _this.invokeCallbacks(instruction, result); + return result; + }) + .catch(function (exception) { + // recover, to enable subsequent calls to validate() + _this.validating = false; + _this.finishValidating = Promise.resolve(); + return Promise.reject(exception); + }); + this.finishValidating = returnPromise; + return returnPromise; + }; + /** + * Resets any rendered validation results (unrenders). + * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results + * will be unrendered. + */ + ValidationController.prototype.reset = function (instruction) { + var predicate = this.getInstructionPredicate(instruction); + var oldResults = this.results.filter(predicate); + this.processResultDelta('reset', oldResults, []); + this.invokeCallbacks(instruction, null); + }; + /** + * Gets the elements associated with an object and propertyName (if any). + */ + ValidationController.prototype.getAssociatedElements = function (_a) { + var object = _a.object, propertyName = _a.propertyName; + var elements = []; + for (var _i = 0, _b = Array.from(this.bindings); _i < _b.length; _i++) { + var _c = _b[_i], binding = _c[0], target = _c[1].target; + var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + if (propertyInfo && propertyInfo.object === object && propertyInfo.propertyName === propertyName) { + elements.push(target); + } + } + return elements; + }; + ValidationController.prototype.processResultDelta = function (kind, oldResults, newResults) { + // prepare the instruction. + var instruction = { + kind: kind, + render: [], + unrender: [] + }; + // create a shallow copy of newResults so we can mutate it without causing side-effects. + newResults = newResults.slice(0); + var _loop_1 = function (oldResult) { + // get the elements associated with the old result. + var elements = this_1.elements.get(oldResult); + // remove the old result from the element map. + this_1.elements.delete(oldResult); + // create the unrender instruction. + instruction.unrender.push({ result: oldResult, elements: elements }); + // determine if there's a corresponding new result for the old result we are unrendering. + var newResultIndex = newResults.findIndex(function (x) { return x.rule === oldResult.rule && x.object === oldResult.object && x.propertyName === oldResult.propertyName; }); + if (newResultIndex === -1) { + // no corresponding new result... simple remove. + this_1.results.splice(this_1.results.indexOf(oldResult), 1); + if (!oldResult.valid) { + this_1.errors.splice(this_1.errors.indexOf(oldResult), 1); + } + } + else { + // there is a corresponding new result... + var newResult = newResults.splice(newResultIndex, 1)[0]; + // get the elements that are associated with the new result. + var elements_1 = this_1.getAssociatedElements(newResult); + this_1.elements.set(newResult, elements_1); + // create a render instruction for the new result. + instruction.render.push({ result: newResult, elements: elements_1 }); + // do an in-place replacement of the old result with the new result. + // this ensures any repeats bound to this.results will not thrash. + this_1.results.splice(this_1.results.indexOf(oldResult), 1, newResult); + if (!oldResult.valid && newResult.valid) { + this_1.errors.splice(this_1.errors.indexOf(oldResult), 1); + } + else if (!oldResult.valid && !newResult.valid) { + this_1.errors.splice(this_1.errors.indexOf(oldResult), 1, newResult); + } + else if (!newResult.valid) { + this_1.errors.push(newResult); + } + } + }; + var this_1 = this; + // create unrender instructions from the old results. + for (var _i = 0, oldResults_1 = oldResults; _i < oldResults_1.length; _i++) { + var oldResult = oldResults_1[_i]; + _loop_1(oldResult); + } + // create render instructions from the remaining new results. + for (var _a = 0, newResults_1 = newResults; _a < newResults_1.length; _a++) { + var result = newResults_1[_a]; + var elements = this.getAssociatedElements(result); + instruction.render.push({ result: result, elements: elements }); + this.elements.set(result, elements); + this.results.push(result); + if (!result.valid) { + this.errors.push(result); + } + } + // render. + for (var _b = 0, _c = this.renderers; _b < _c.length; _b++) { + var renderer = _c[_b]; + renderer.render(instruction); + } + }; + /** + * Validates the property associated with a binding. + */ + ValidationController.prototype.validateBinding = function (binding) { + if (!binding.isBound) { + return; + } + var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + var rules; + var registeredBinding = this.bindings.get(binding); + if (registeredBinding) { + rules = registeredBinding.rules; + registeredBinding.propertyInfo = propertyInfo; + } + if (!propertyInfo) { + return; + } + var object = propertyInfo.object, propertyName = propertyInfo.propertyName; + this.validate({ object: object, propertyName: propertyName, rules: rules }); + }; + /** + * Resets the results for a property associated with a binding. + */ + ValidationController.prototype.resetBinding = function (binding) { + var registeredBinding = this.bindings.get(binding); + var propertyInfo = getPropertyInfo(binding.sourceExpression, binding.source); + if (!propertyInfo && registeredBinding) { + propertyInfo = registeredBinding.propertyInfo; + } + if (registeredBinding) { + registeredBinding.propertyInfo = null; + } + if (!propertyInfo) { + return; + } + var object = propertyInfo.object, propertyName = propertyInfo.propertyName; + this.reset({ object: object, propertyName: propertyName }); + }; + /** + * Changes the controller's validateTrigger. + * @param newTrigger The new validateTrigger + */ + ValidationController.prototype.changeTrigger = function (newTrigger) { + this.validateTrigger = newTrigger; + var bindings = Array.from(this.bindings.keys()); + for (var _i = 0, bindings_1 = bindings; _i < bindings_1.length; _i++) { + var binding = bindings_1[_i]; + var source = binding.source; + binding.unbind(); + binding.bind(source); + } + }; + /** + * Revalidates the controller's current set of errors. + */ + ValidationController.prototype.revalidateErrors = function () { + for (var _i = 0, _a = this.errors; _i < _a.length; _i++) { + var _b = _a[_i], object = _b.object, propertyName = _b.propertyName, rule = _b.rule; + if (rule.__manuallyAdded__) { + continue; + } + var rules = [[rule]]; + this.validate({ object: object, propertyName: propertyName, rules: rules }); + } + }; + ValidationController.prototype.invokeCallbacks = function (instruction, result) { + if (this.eventCallbacks.length === 0) { + return; + } + var event = new ValidateEvent(result ? 'validate' : 'reset', this.errors, this.results, instruction || null, result); + for (var i = 0; i < this.eventCallbacks.length; i++) { + this.eventCallbacks[i](event); + } + }; + ValidationController.inject = [Validator, PropertyAccessorParser]; + return ValidationController; + }())); + + /** + * Binding behavior. Indicates the bound property should be validated. + */ + var ValidateBindingBehaviorBase = /** @class */ (function () { + function ValidateBindingBehaviorBase(taskQueue) { + this.taskQueue = taskQueue; + } + ValidateBindingBehaviorBase.prototype.bind = function (binding, source, rulesOrController, rules) { + var _this = this; + // identify the target element. + var target = getTargetDOMElement(binding, source); + // locate the controller. + var controller; + if (rulesOrController instanceof ValidationController) { + controller = rulesOrController; + } + else { + controller = source.container.get(Optional.of(ValidationController)); + rules = rulesOrController; + } + if (controller === null) { + throw new Error("A ValidationController has not been registered."); + } + controller.registerBinding(binding, target, rules); + binding.validationController = controller; + var trigger = this.getValidateTrigger(controller); + // tslint:disable-next-line:no-bitwise + if (trigger & validateTrigger.change) { + binding.vbbUpdateSource = binding.updateSource; + // tslint:disable-next-line:only-arrow-functions + // tslint:disable-next-line:space-before-function-paren + binding.updateSource = function (value) { + this.vbbUpdateSource(value); + this.validationController.validateBinding(this); + }; + } + // tslint:disable-next-line:no-bitwise + if (trigger & validateTrigger.blur) { + binding.validateBlurHandler = function () { + _this.taskQueue.queueMicroTask(function () { return controller.validateBinding(binding); }); + }; + binding.validateTarget = target; + target.addEventListener('blur', binding.validateBlurHandler); + } + if (trigger !== validateTrigger.manual) { + binding.standardUpdateTarget = binding.updateTarget; + // tslint:disable-next-line:only-arrow-functions + // tslint:disable-next-line:space-before-function-paren + binding.updateTarget = function (value) { + this.standardUpdateTarget(value); + this.validationController.resetBinding(this); + }; + } + }; + ValidateBindingBehaviorBase.prototype.unbind = function (binding) { + // reset the binding to it's original state. + if (binding.vbbUpdateSource) { + binding.updateSource = binding.vbbUpdateSource; + binding.vbbUpdateSource = null; + } + if (binding.standardUpdateTarget) { + binding.updateTarget = binding.standardUpdateTarget; + binding.standardUpdateTarget = null; + } + if (binding.validateBlurHandler) { + binding.validateTarget.removeEventListener('blur', binding.validateBlurHandler); + binding.validateBlurHandler = null; + binding.validateTarget = null; + } + binding.validationController.unregisterBinding(binding); + binding.validationController = null; + }; + return ValidateBindingBehaviorBase; + }()); + + /** + * Binding behavior. Indicates the bound property should be validated + * when the validate trigger specified by the associated controller's + * validateTrigger property occurs. + */ + var ValidateBindingBehavior = exports('ValidateBindingBehavior', /** @class */ (function (_super) { + __extends(ValidateBindingBehavior, _super); + function ValidateBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateBindingBehavior.prototype.getValidateTrigger = function (controller) { + return controller.validateTrigger; + }; + ValidateBindingBehavior.inject = [TaskQueue]; + return ValidateBindingBehavior; + }(ValidateBindingBehaviorBase))); + /** + * Binding behavior. Indicates the bound property will be validated + * manually, by calling controller.validate(). No automatic validation + * triggered by data-entry or blur will occur. + */ + var ValidateManuallyBindingBehavior = exports('ValidateManuallyBindingBehavior', /** @class */ (function (_super) { + __extends(ValidateManuallyBindingBehavior, _super); + function ValidateManuallyBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateManuallyBindingBehavior.prototype.getValidateTrigger = function () { + return validateTrigger.manual; + }; + ValidateManuallyBindingBehavior.inject = [TaskQueue]; + return ValidateManuallyBindingBehavior; + }(ValidateBindingBehaviorBase))); + /** + * Binding behavior. Indicates the bound property should be validated + * when the associated element blurs. + */ + var ValidateOnBlurBindingBehavior = exports('ValidateOnBlurBindingBehavior', /** @class */ (function (_super) { + __extends(ValidateOnBlurBindingBehavior, _super); + function ValidateOnBlurBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateOnBlurBindingBehavior.prototype.getValidateTrigger = function () { + return validateTrigger.blur; + }; + ValidateOnBlurBindingBehavior.inject = [TaskQueue]; + return ValidateOnBlurBindingBehavior; + }(ValidateBindingBehaviorBase))); + /** + * Binding behavior. Indicates the bound property should be validated + * when the associated element is changed by the user, causing a change + * to the model. + */ + var ValidateOnChangeBindingBehavior = exports('ValidateOnChangeBindingBehavior', /** @class */ (function (_super) { + __extends(ValidateOnChangeBindingBehavior, _super); + function ValidateOnChangeBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateOnChangeBindingBehavior.prototype.getValidateTrigger = function () { + return validateTrigger.change; + }; + ValidateOnChangeBindingBehavior.inject = [TaskQueue]; + return ValidateOnChangeBindingBehavior; + }(ValidateBindingBehaviorBase))); + /** + * Binding behavior. Indicates the bound property should be validated + * when the associated element blurs or is changed by the user, causing + * a change to the model. + */ + var ValidateOnChangeOrBlurBindingBehavior = exports('ValidateOnChangeOrBlurBindingBehavior', /** @class */ (function (_super) { + __extends(ValidateOnChangeOrBlurBindingBehavior, _super); + function ValidateOnChangeOrBlurBindingBehavior() { + return _super !== null && _super.apply(this, arguments) || this; + } + ValidateOnChangeOrBlurBindingBehavior.prototype.getValidateTrigger = function () { + return validateTrigger.changeOrBlur; + }; + ValidateOnChangeOrBlurBindingBehavior.inject = [TaskQueue]; + return ValidateOnChangeOrBlurBindingBehavior; + }(ValidateBindingBehaviorBase))); + + /** + * Creates ValidationController instances. + */ + var ValidationControllerFactory = exports('ValidationControllerFactory', /** @class */ (function () { + function ValidationControllerFactory(container) { + this.container = container; + } + ValidationControllerFactory.get = function (container) { + return new ValidationControllerFactory(container); + }; + /** + * Creates a new controller instance. + */ + ValidationControllerFactory.prototype.create = function (validator) { + if (!validator) { + validator = this.container.get(Validator); + } + var propertyParser = this.container.get(PropertyAccessorParser); + return new ValidationController(validator, propertyParser); + }; + /** + * Creates a new controller and registers it in the current element's container so that it's + * available to the validate binding behavior and renderers. + */ + ValidationControllerFactory.prototype.createForCurrentScope = function (validator) { + var controller = this.create(validator); + this.container.registerInstance(ValidationController, controller); + return controller; + }; + return ValidationControllerFactory; + }())); + ValidationControllerFactory['protocol:aurelia:resolver'] = true; + + var ValidationErrorsCustomAttribute = exports('ValidationErrorsCustomAttribute', /** @class */ (function () { + function ValidationErrorsCustomAttribute(boundaryElement, controllerAccessor) { + this.boundaryElement = boundaryElement; + this.controllerAccessor = controllerAccessor; + this.controller = null; + this.errors = []; + this.errorsInternal = []; + } + ValidationErrorsCustomAttribute.inject = function () { + return [DOM.Element, Lazy.of(ValidationController)]; + }; + ValidationErrorsCustomAttribute.prototype.sort = function () { + this.errorsInternal.sort(function (a, b) { + if (a.targets[0] === b.targets[0]) { + return 0; + } + // tslint:disable-next-line:no-bitwise + return a.targets[0].compareDocumentPosition(b.targets[0]) & 2 ? 1 : -1; + }); + }; + ValidationErrorsCustomAttribute.prototype.interestingElements = function (elements) { + var _this = this; + return elements.filter(function (e) { return _this.boundaryElement.contains(e); }); + }; + ValidationErrorsCustomAttribute.prototype.render = function (instruction) { + var _loop_1 = function (result) { + var index = this_1.errorsInternal.findIndex(function (x) { return x.error === result; }); + if (index !== -1) { + this_1.errorsInternal.splice(index, 1); + } + }; + var this_1 = this; + for (var _i = 0, _a = instruction.unrender; _i < _a.length; _i++) { + var result = _a[_i].result; + _loop_1(result); + } + for (var _b = 0, _c = instruction.render; _b < _c.length; _b++) { + var _d = _c[_b], result = _d.result, elements = _d.elements; + if (result.valid) { + continue; + } + var targets = this.interestingElements(elements); + if (targets.length) { + this.errorsInternal.push({ error: result, targets: targets }); + } + } + this.sort(); + this.errors = this.errorsInternal; + }; + ValidationErrorsCustomAttribute.prototype.bind = function () { + if (!this.controller) { + this.controller = this.controllerAccessor(); + } + // this will call render() with the side-effect of updating this.errors + this.controller.addRenderer(this); + }; + ValidationErrorsCustomAttribute.prototype.unbind = function () { + if (this.controller) { + this.controller.removeRenderer(this); + } + }; + __decorate([ + bindable({ defaultBindingMode: bindingMode.oneWay }) + ], ValidationErrorsCustomAttribute.prototype, "controller", void 0); + __decorate([ + bindable({ primaryProperty: true, defaultBindingMode: bindingMode.twoWay }) + ], ValidationErrorsCustomAttribute.prototype, "errors", void 0); + ValidationErrorsCustomAttribute = __decorate([ + customAttribute('validation-errors') + ], ValidationErrorsCustomAttribute); + return ValidationErrorsCustomAttribute; + }())); + + var ValidationRendererCustomAttribute = exports('ValidationRendererCustomAttribute', /** @class */ (function () { + function ValidationRendererCustomAttribute() { + } + ValidationRendererCustomAttribute.prototype.created = function (view) { + this.container = view.container; + }; + ValidationRendererCustomAttribute.prototype.bind = function () { + this.controller = this.container.get(ValidationController); + this.renderer = this.container.get(this.value); + this.controller.addRenderer(this.renderer); + }; + ValidationRendererCustomAttribute.prototype.unbind = function () { + this.controller.removeRenderer(this.renderer); + this.controller = null; + this.renderer = null; + }; + ValidationRendererCustomAttribute = __decorate([ + customAttribute$1('validation-renderer') + ], ValidationRendererCustomAttribute); + return ValidationRendererCustomAttribute; + }())); + + /** + * Sets, unsets and retrieves rules on an object or constructor function. + */ + var Rules = exports('Rules', /** @class */ (function () { + function Rules() { + } + /** + * Applies the rules to a target. + */ + Rules.set = function (target, rules) { + if (target instanceof Function) { + target = target.prototype; + } + Object.defineProperty(target, Rules.key, { enumerable: false, configurable: false, writable: true, value: rules }); + }; + /** + * Removes rules from a target. + */ + Rules.unset = function (target) { + if (target instanceof Function) { + target = target.prototype; + } + target[Rules.key] = null; + }; + /** + * Retrieves the target's rules. + */ + Rules.get = function (target) { + return target[Rules.key] || null; + }; + /** + * The name of the property that stores the rules. + */ + Rules.key = '__rules__'; + return Rules; + }())); + + // tslint:disable:no-empty + var ExpressionVisitor = /** @class */ (function () { + function ExpressionVisitor() { + } + ExpressionVisitor.prototype.visitChain = function (chain) { + this.visitArgs(chain.expressions); + }; + ExpressionVisitor.prototype.visitBindingBehavior = function (behavior) { + behavior.expression.accept(this); + this.visitArgs(behavior.args); + }; + ExpressionVisitor.prototype.visitValueConverter = function (converter) { + converter.expression.accept(this); + this.visitArgs(converter.args); + }; + ExpressionVisitor.prototype.visitAssign = function (assign) { + assign.target.accept(this); + assign.value.accept(this); + }; + ExpressionVisitor.prototype.visitConditional = function (conditional) { + conditional.condition.accept(this); + conditional.yes.accept(this); + conditional.no.accept(this); + }; + ExpressionVisitor.prototype.visitAccessThis = function (access) { + access.ancestor = access.ancestor; + }; + ExpressionVisitor.prototype.visitAccessScope = function (access) { + access.name = access.name; + }; + ExpressionVisitor.prototype.visitAccessMember = function (access) { + access.object.accept(this); + }; + ExpressionVisitor.prototype.visitAccessKeyed = function (access) { + access.object.accept(this); + access.key.accept(this); + }; + ExpressionVisitor.prototype.visitCallScope = function (call) { + this.visitArgs(call.args); + }; + ExpressionVisitor.prototype.visitCallFunction = function (call) { + call.func.accept(this); + this.visitArgs(call.args); + }; + ExpressionVisitor.prototype.visitCallMember = function (call) { + call.object.accept(this); + this.visitArgs(call.args); + }; + ExpressionVisitor.prototype.visitPrefix = function (prefix) { + prefix.expression.accept(this); + }; + ExpressionVisitor.prototype.visitBinary = function (binary) { + binary.left.accept(this); + binary.right.accept(this); + }; + ExpressionVisitor.prototype.visitLiteralPrimitive = function (literal) { + literal.value = literal.value; + }; + ExpressionVisitor.prototype.visitLiteralArray = function (literal) { + this.visitArgs(literal.elements); + }; + ExpressionVisitor.prototype.visitLiteralObject = function (literal) { + this.visitArgs(literal.values); + }; + ExpressionVisitor.prototype.visitLiteralString = function (literal) { + literal.value = literal.value; + }; + ExpressionVisitor.prototype.visitArgs = function (args) { + for (var i = 0; i < args.length; i++) { + args[i].accept(this); + } + }; + return ExpressionVisitor; + }()); + + var ValidationMessageParser = exports('ValidationMessageParser', /** @class */ (function () { + function ValidationMessageParser(bindinqLanguage) { + this.bindinqLanguage = bindinqLanguage; + this.emptyStringExpression = new LiteralString(''); + this.nullExpression = new LiteralPrimitive(null); + this.undefinedExpression = new LiteralPrimitive(undefined); + this.cache = {}; + } + ValidationMessageParser.prototype.parse = function (message) { + if (this.cache[message] !== undefined) { + return this.cache[message]; + } + var parts = this.bindinqLanguage.parseInterpolation(null, message); + if (parts === null) { + return new LiteralString(message); + } + var expression = new LiteralString(parts[0]); + for (var i = 1; i < parts.length; i += 2) { + expression = new Binary('+', expression, new Binary('+', this.coalesce(parts[i]), new LiteralString(parts[i + 1]))); + } + MessageExpressionValidator.validate(expression, message); + this.cache[message] = expression; + return expression; + }; + ValidationMessageParser.prototype.coalesce = function (part) { + // part === null || part === undefined ? '' : part + return new Conditional(new Binary('||', new Binary('===', part, this.nullExpression), new Binary('===', part, this.undefinedExpression)), this.emptyStringExpression, new CallMember(part, 'toString', [])); + }; + ValidationMessageParser.inject = [BindingLanguage]; + return ValidationMessageParser; + }())); + var MessageExpressionValidator = exports('MessageExpressionValidator', /** @class */ (function (_super) { + __extends(MessageExpressionValidator, _super); + function MessageExpressionValidator(originalMessage) { + var _this = _super.call(this) || this; + _this.originalMessage = originalMessage; + return _this; + } + MessageExpressionValidator.validate = function (expression, originalMessage) { + var visitor = new MessageExpressionValidator(originalMessage); + expression.accept(visitor); + }; + MessageExpressionValidator.prototype.visitAccessScope = function (access) { + if (access.ancestor !== 0) { + throw new Error('$parent is not permitted in validation message expressions.'); + } + if (['displayName', 'propertyName', 'value', 'object', 'config', 'getDisplayName'].indexOf(access.name) !== -1) { + getLogger('aurelia-validation') + // tslint:disable-next-line:max-line-length + .warn("Did you mean to use \"$" + access.name + "\" instead of \"" + access.name + "\" in this validation message template: \"" + this.originalMessage + "\"?"); + } + }; + return MessageExpressionValidator; + }(ExpressionVisitor))); + + /** + * Dictionary of validation messages. [messageKey]: messageExpression + */ + var validationMessages = exports('validationMessages', { + /** + * The default validation message. Used with rules that have no standard message. + */ + default: "${$displayName} is invalid.", + required: "${$displayName} is required.", + matches: "${$displayName} is not correctly formatted.", + email: "${$displayName} is not a valid email.", + minLength: "${$displayName} must be at least ${$config.length} character${$config.length === 1 ? '' : 's'}.", + maxLength: "${$displayName} cannot be longer than ${$config.length} character${$config.length === 1 ? '' : 's'}.", + minItems: "${$displayName} must contain at least ${$config.count} item${$config.count === 1 ? '' : 's'}.", + maxItems: "${$displayName} cannot contain more than ${$config.count} item${$config.count === 1 ? '' : 's'}.", + equals: "${$displayName} must be ${$config.expectedValue}.", + }); + /** + * Retrieves validation messages and property display names. + */ + var ValidationMessageProvider = exports('ValidationMessageProvider', /** @class */ (function () { + function ValidationMessageProvider(parser) { + this.parser = parser; + } + /** + * Returns a message binding expression that corresponds to the key. + * @param key The message key. + */ + ValidationMessageProvider.prototype.getMessage = function (key) { + var message; + if (key in validationMessages) { + message = validationMessages[key]; + } + else { + message = validationMessages['default']; + } + return this.parser.parse(message); + }; + /** + * Formulates a property display name using the property name and the configured + * displayName (if provided). + * Override this with your own custom logic. + * @param propertyName The property name. + */ + ValidationMessageProvider.prototype.getDisplayName = function (propertyName, displayName) { + if (displayName !== null && displayName !== undefined) { + return (displayName instanceof Function) ? displayName() : displayName; + } + // split on upper-case letters. + var words = propertyName.toString().split(/(?=[A-Z])/).join(' '); + // capitalize first letter. + return words.charAt(0).toUpperCase() + words.slice(1); + }; + ValidationMessageProvider.inject = [ValidationMessageParser]; + return ValidationMessageProvider; + }())); + + /** + * Validates. + * Responsible for validating objects and properties. + */ + var StandardValidator = exports('StandardValidator', /** @class */ (function (_super) { + __extends(StandardValidator, _super); + function StandardValidator(messageProvider, resources) { + var _this = _super.call(this) || this; + _this.messageProvider = messageProvider; + _this.lookupFunctions = resources.lookupFunctions; + _this.getDisplayName = messageProvider.getDisplayName.bind(messageProvider); + return _this; + } + /** + * Validates the specified property. + * @param object The object to validate. + * @param propertyName The name of the property to validate. + * @param rules Optional. If unspecified, the rules will be looked up using the metadata + * for the object created by ValidationRules....on(class/object) + */ + StandardValidator.prototype.validateProperty = function (object, propertyName, rules) { + return this.validate(object, propertyName, rules || null); + }; + /** + * Validates all rules for specified object and it's properties. + * @param object The object to validate. + * @param rules Optional. If unspecified, the rules will be looked up using the metadata + * for the object created by ValidationRules....on(class/object) + */ + StandardValidator.prototype.validateObject = function (object, rules) { + return this.validate(object, null, rules || null); + }; + /** + * Determines whether a rule exists in a set of rules. + * @param rules The rules to search. + * @parem rule The rule to find. + */ + StandardValidator.prototype.ruleExists = function (rules, rule) { + var i = rules.length; + while (i--) { + if (rules[i].indexOf(rule) !== -1) { + return true; + } + } + return false; + }; + StandardValidator.prototype.getMessage = function (rule, object, value) { + var expression = rule.message || this.messageProvider.getMessage(rule.messageKey); + // tslint:disable-next-line:prefer-const + var _a = rule.property, propertyName = _a.name, displayName = _a.displayName; + if (propertyName !== null) { + displayName = this.messageProvider.getDisplayName(propertyName, displayName); + } + var overrideContext = { + $displayName: displayName, + $propertyName: propertyName, + $value: value, + $object: object, + $config: rule.config, + // returns the name of a given property, given just the property name (irrespective of the property's displayName) + // split on capital letters, first letter ensured to be capitalized + $getDisplayName: this.getDisplayName + }; + return expression.evaluate({ bindingContext: object, overrideContext: overrideContext }, this.lookupFunctions); + }; + StandardValidator.prototype.validateRuleSequence = function (object, propertyName, ruleSequence, sequence, results) { + var _this = this; + // are we validating all properties or a single property? + var validateAllProperties = propertyName === null || propertyName === undefined; + var rules = ruleSequence[sequence]; + var allValid = true; + // validate each rule. + var promises = []; + var _loop_1 = function (i) { + var rule = rules[i]; + // is the rule related to the property we're validating. + // tslint:disable-next-line:triple-equals | Use loose equality for property keys + if (!validateAllProperties && rule.property.name != propertyName) { + return "continue"; + } + // is this a conditional rule? is the condition met? + if (rule.when && !rule.when(object)) { + return "continue"; + } + // validate. + var value = rule.property.name === null ? object : object[rule.property.name]; + var promiseOrBoolean = rule.condition(value, object); + if (!(promiseOrBoolean instanceof Promise)) { + promiseOrBoolean = Promise.resolve(promiseOrBoolean); + } + promises.push(promiseOrBoolean.then(function (valid) { + var message = valid ? null : _this.getMessage(rule, object, value); + results.push(new ValidateResult(rule, object, rule.property.name, valid, message)); + allValid = allValid && valid; + return valid; + })); + }; + for (var i = 0; i < rules.length; i++) { + _loop_1(i); + } + return Promise.all(promises) + .then(function () { + sequence++; + if (allValid && sequence < ruleSequence.length) { + return _this.validateRuleSequence(object, propertyName, ruleSequence, sequence, results); + } + return results; + }); + }; + StandardValidator.prototype.validate = function (object, propertyName, rules) { + // rules specified? + if (!rules) { + // no. attempt to locate the rules. + rules = Rules.get(object); + } + // any rules? + if (!rules || rules.length === 0) { + return Promise.resolve([]); + } + return this.validateRuleSequence(object, propertyName, rules, 0, []); + }; + StandardValidator.inject = [ValidationMessageProvider, ViewResources]; + return StandardValidator; + }(Validator))); + + /** + * Part of the fluent rule API. Enables customizing property rules. + */ + var FluentRuleCustomizer = exports('FluentRuleCustomizer', /** @class */ (function () { + function FluentRuleCustomizer(property, condition, config, fluentEnsure, fluentRules, parsers) { + if (config === void 0) { config = {}; } + this.fluentEnsure = fluentEnsure; + this.fluentRules = fluentRules; + this.parsers = parsers; + this.rule = { + property: property, + condition: condition, + config: config, + when: null, + messageKey: 'default', + message: null, + sequence: fluentRules.sequence + }; + this.fluentEnsure._addRule(this.rule); + } + /** + * Validate subsequent rules after previously declared rules have + * been validated successfully. Use to postpone validation of costly + * rules until less expensive rules pass validation. + */ + FluentRuleCustomizer.prototype.then = function () { + this.fluentRules.sequence++; + return this; + }; + /** + * Specifies the key to use when looking up the rule's validation message. + */ + FluentRuleCustomizer.prototype.withMessageKey = function (key) { + this.rule.messageKey = key; + this.rule.message = null; + return this; + }; + /** + * Specifies rule's validation message. + */ + FluentRuleCustomizer.prototype.withMessage = function (message) { + this.rule.messageKey = 'custom'; + this.rule.message = this.parsers.message.parse(message); + return this; + }; + /** + * Specifies a condition that must be met before attempting to validate the rule. + * @param condition A function that accepts the object as a parameter and returns true + * or false whether the rule should be evaluated. + */ + FluentRuleCustomizer.prototype.when = function (condition) { + this.rule.when = condition; + return this; + }; + /** + * Tags the rule instance, enabling the rule to be found easily + * using ValidationRules.taggedRules(rules, tag) + */ + FluentRuleCustomizer.prototype.tag = function (tag) { + this.rule.tag = tag; + return this; + }; + ///// FluentEnsure APIs ///// + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor function. + */ + FluentRuleCustomizer.prototype.ensure = function (subject) { + return this.fluentEnsure.ensure(subject); + }; + /** + * Targets an object with validation rules. + */ + FluentRuleCustomizer.prototype.ensureObject = function () { + return this.fluentEnsure.ensureObject(); + }; + Object.defineProperty(FluentRuleCustomizer.prototype, "rules", { + /** + * Rules that have been defined using the fluent API. + */ + get: function () { + return this.fluentEnsure.rules; + }, + enumerable: true, + configurable: true + }); + /** + * Applies the rules to a class or object, making them discoverable by the StandardValidator. + * @param target A class or object. + */ + FluentRuleCustomizer.prototype.on = function (target) { + return this.fluentEnsure.on(target); + }; + ///////// FluentRules APIs ///////// + /** + * Applies an ad-hoc rule function to the ensured property or object. + * @param condition The function to validate the rule. + * Will be called with two arguments, the property value and the object. + * Should return a boolean or a Promise that resolves to a boolean. + */ + FluentRuleCustomizer.prototype.satisfies = function (condition, config) { + return this.fluentRules.satisfies(condition, config); + }; + /** + * Applies a rule by name. + * @param name The name of the custom or standard rule. + * @param args The rule's arguments. + */ + FluentRuleCustomizer.prototype.satisfiesRule = function (name) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + var _a; + return (_a = this.fluentRules).satisfiesRule.apply(_a, [name].concat(args)); + }; + /** + * Applies the "required" rule to the property. + * The value cannot be null, undefined or whitespace. + */ + FluentRuleCustomizer.prototype.required = function () { + return this.fluentRules.required(); + }; + /** + * Applies the "matches" rule to the property. + * Value must match the specified regular expression. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.matches = function (regex) { + return this.fluentRules.matches(regex); + }; + /** + * Applies the "email" rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.email = function () { + return this.fluentRules.email(); + }; + /** + * Applies the "minLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.minLength = function (length) { + return this.fluentRules.minLength(length); + }; + /** + * Applies the "maxLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.maxLength = function (length) { + return this.fluentRules.maxLength(length); + }; + /** + * Applies the "minItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRuleCustomizer.prototype.minItems = function (count) { + return this.fluentRules.minItems(count); + }; + /** + * Applies the "maxItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRuleCustomizer.prototype.maxItems = function (count) { + return this.fluentRules.maxItems(count); + }; + /** + * Applies the "equals" validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRuleCustomizer.prototype.equals = function (expectedValue) { + return this.fluentRules.equals(expectedValue); + }; + return FluentRuleCustomizer; + }())); + /** + * Part of the fluent rule API. Enables applying rules to properties and objects. + */ + var FluentRules = exports('FluentRules', /** @class */ (function () { + function FluentRules(fluentEnsure, parsers, property) { + this.fluentEnsure = fluentEnsure; + this.parsers = parsers; + this.property = property; + /** + * Current rule sequence number. Used to postpone evaluation of rules until rules + * with lower sequence number have successfully validated. The "then" fluent API method + * manages this property, there's usually no need to set it directly. + */ + this.sequence = 0; + } + /** + * Sets the display name of the ensured property. + */ + FluentRules.prototype.displayName = function (name) { + this.property.displayName = name; + return this; + }; + /** + * Applies an ad-hoc rule function to the ensured property or object. + * @param condition The function to validate the rule. + * Will be called with two arguments, the property value and the object. + * Should return a boolean or a Promise that resolves to a boolean. + */ + FluentRules.prototype.satisfies = function (condition, config) { + return new FluentRuleCustomizer(this.property, condition, config, this.fluentEnsure, this, this.parsers); + }; + /** + * Applies a rule by name. + * @param name The name of the custom or standard rule. + * @param args The rule's arguments. + */ + FluentRules.prototype.satisfiesRule = function (name) { + var _this = this; + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + var rule = FluentRules.customRules[name]; + if (!rule) { + // standard rule? + rule = this[name]; + if (rule instanceof Function) { + return rule.call.apply(rule, [this].concat(args)); + } + throw new Error("Rule with name \"" + name + "\" does not exist."); + } + var config = rule.argsToConfig ? rule.argsToConfig.apply(rule, args) : undefined; + return this.satisfies(function (value, obj) { + var _a; + return (_a = rule.condition).call.apply(_a, [_this, value, obj].concat(args)); + }, config) + .withMessageKey(name); + }; + /** + * Applies the "required" rule to the property. + * The value cannot be null, undefined or whitespace. + */ + FluentRules.prototype.required = function () { + return this.satisfies(function (value) { + return value !== null + && value !== undefined + && !(isString(value) && !/\S/.test(value)); + }).withMessageKey('required'); + }; + /** + * Applies the "matches" rule to the property. + * Value must match the specified regular expression. + * null, undefined and empty-string values are considered valid. + */ + FluentRules.prototype.matches = function (regex) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || regex.test(value); }) + .withMessageKey('matches'); + }; + /** + * Applies the "email" rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRules.prototype.email = function () { + // regex from https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address + /* tslint:disable:max-line-length */ + return this.matches(/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/) + /* tslint:enable:max-line-length */ + .withMessageKey('email'); + }; + /** + * Applies the "minLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRules.prototype.minLength = function (length) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || value.length >= length; }, { length: length }) + .withMessageKey('minLength'); + }; + /** + * Applies the "maxLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + FluentRules.prototype.maxLength = function (length) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || value.length <= length; }, { length: length }) + .withMessageKey('maxLength'); + }; + /** + * Applies the "minItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRules.prototype.minItems = function (count) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length >= count; }, { count: count }) + .withMessageKey('minItems'); + }; + /** + * Applies the "maxItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRules.prototype.maxItems = function (count) { + return this.satisfies(function (value) { return value === null || value === undefined || value.length <= count; }, { count: count }) + .withMessageKey('maxItems'); + }; + /** + * Applies the "equals" validation rule to the property. + * null and undefined values are considered valid. + */ + FluentRules.prototype.equals = function (expectedValue) { + return this.satisfies(function (value) { return value === null || value === undefined || value === '' || value === expectedValue; }, { expectedValue: expectedValue }) + .withMessageKey('equals'); + }; + FluentRules.customRules = {}; + return FluentRules; + }())); + /** + * Part of the fluent rule API. Enables targeting properties and objects with rules. + */ + var FluentEnsure = exports('FluentEnsure', /** @class */ (function () { + function FluentEnsure(parsers) { + this.parsers = parsers; + /** + * Rules that have been defined using the fluent API. + */ + this.rules = []; + } + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor + * function. + */ + FluentEnsure.prototype.ensure = function (property) { + this.assertInitialized(); + var name = this.parsers.property.parse(property); + var fluentRules = new FluentRules(this, this.parsers, { name: name, displayName: null }); + return this.mergeRules(fluentRules, name); + }; + /** + * Targets an object with validation rules. + */ + FluentEnsure.prototype.ensureObject = function () { + this.assertInitialized(); + var fluentRules = new FluentRules(this, this.parsers, { name: null, displayName: null }); + return this.mergeRules(fluentRules, null); + }; + /** + * Applies the rules to a class or object, making them discoverable by the StandardValidator. + * @param target A class or object. + */ + FluentEnsure.prototype.on = function (target) { + Rules.set(target, this.rules); + return this; + }; + /** + * Adds a rule definition to the sequenced ruleset. + * @internal + */ + FluentEnsure.prototype._addRule = function (rule) { + while (this.rules.length < rule.sequence + 1) { + this.rules.push([]); + } + this.rules[rule.sequence].push(rule); + }; + FluentEnsure.prototype.assertInitialized = function () { + if (this.parsers) { + return; + } + throw new Error("Did you forget to add \".plugin('aurelia-validation')\" to your main.js?"); + }; + FluentEnsure.prototype.mergeRules = function (fluentRules, propertyName) { + // tslint:disable-next-line:triple-equals | Use loose equality for property keys + var existingRules = this.rules.find(function (r) { return r.length > 0 && r[0].property.name == propertyName; }); + if (existingRules) { + var rule = existingRules[existingRules.length - 1]; + fluentRules.sequence = rule.sequence; + if (rule.property.displayName !== null) { + fluentRules = fluentRules.displayName(rule.property.displayName); + } + } + return fluentRules; + }; + return FluentEnsure; + }())); + /** + * Fluent rule definition API. + */ + var ValidationRules = exports('ValidationRules', /** @class */ (function () { + function ValidationRules() { + } + ValidationRules.initialize = function (messageParser, propertyParser) { + this.parsers = { + message: messageParser, + property: propertyParser + }; + }; + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor function. + */ + ValidationRules.ensure = function (property) { + return new FluentEnsure(ValidationRules.parsers).ensure(property); + }; + /** + * Targets an object with validation rules. + */ + ValidationRules.ensureObject = function () { + return new FluentEnsure(ValidationRules.parsers).ensureObject(); + }; + /** + * Defines a custom rule. + * @param name The name of the custom rule. Also serves as the message key. + * @param condition The rule function. + * @param message The message expression + * @param argsToConfig A function that maps the rule's arguments to a "config" + * object that can be used when evaluating the message expression. + */ + ValidationRules.customRule = function (name, condition, message, argsToConfig) { + validationMessages[name] = message; + FluentRules.customRules[name] = { condition: condition, argsToConfig: argsToConfig }; + }; + /** + * Returns rules with the matching tag. + * @param rules The rules to search. + * @param tag The tag to search for. + */ + ValidationRules.taggedRules = function (rules, tag) { + return rules.map(function (x) { return x.filter(function (r) { return r.tag === tag; }); }); + }; + /** + * Returns rules that have no tag. + * @param rules The rules to search. + */ + ValidationRules.untaggedRules = function (rules) { + return rules.map(function (x) { return x.filter(function (r) { return r.tag === undefined; }); }); + }; + /** + * Removes the rules from a class or object. + * @param target A class or object. + */ + ValidationRules.off = function (target) { + Rules.unset(target); + }; + return ValidationRules; + }())); + + // Exports + /** + * Aurelia Validation Configuration API + */ + var AureliaValidationConfiguration = exports('AureliaValidationConfiguration', /** @class */ (function () { + function AureliaValidationConfiguration() { + this.validatorType = StandardValidator; + } + /** + * Use a custom Validator implementation. + */ + AureliaValidationConfiguration.prototype.customValidator = function (type) { + this.validatorType = type; + }; + /** + * Applies the configuration. + */ + AureliaValidationConfiguration.prototype.apply = function (container) { + var validator = container.get(this.validatorType); + container.registerInstance(Validator, validator); + }; + return AureliaValidationConfiguration; + }())); + /** + * Configures the plugin. + */ + function configure( + // tslint:disable-next-line:ban-types + frameworkConfig, callback) { + // the fluent rule definition API needs the parser to translate messages + // to interpolation expressions. + var messageParser = frameworkConfig.container.get(ValidationMessageParser); + var propertyParser = frameworkConfig.container.get(PropertyAccessorParser); + ValidationRules.initialize(messageParser, propertyParser); + // configure... + var config = new AureliaValidationConfiguration(); + if (callback instanceof Function) { + callback(config); + } + config.apply(frameworkConfig.container); + // globalize the behaviors. + if (frameworkConfig.globalResources) { + frameworkConfig.globalResources(ValidateBindingBehavior, ValidateManuallyBindingBehavior, ValidateOnBlurBindingBehavior, ValidateOnChangeBindingBehavior, ValidateOnChangeOrBlurBindingBehavior, ValidationErrorsCustomAttribute, ValidationRendererCustomAttribute); + } + } + } - exports_1("configure", configure); - var aurelia_pal_1, validator_1, standard_validator_1, validation_message_parser_1, property_accessor_parser_1, validation_rules_1, AureliaValidationConfiguration; - var exportedNames_1 = { - "AureliaValidationConfiguration": true, - "configure": true - }; - function exportStar_1(m) { - var exports = {}; - for (var n in m) { - if (n !== "default" && !exportedNames_1.hasOwnProperty(n)) exports[n] = m[n]; - } - exports_1(exports); - } - return { - setters: [ - function (get_target_dom_element_1_1) { - exportStar_1(get_target_dom_element_1_1); - }, - function (property_info_1_1) { - exportStar_1(property_info_1_1); - }, - function (property_accessor_parser_2_1) { - exportStar_1(property_accessor_parser_2_1); - property_accessor_parser_1 = property_accessor_parser_2_1; - }, - function (validate_binding_behavior_1_1) { - exportStar_1(validate_binding_behavior_1_1); - }, - function (validate_event_1_1) { - exportStar_1(validate_event_1_1); - }, - function (validate_result_1_1) { - exportStar_1(validate_result_1_1); - }, - function (validate_trigger_1_1) { - exportStar_1(validate_trigger_1_1); - }, - function (validation_controller_1_1) { - exportStar_1(validation_controller_1_1); - }, - function (validation_controller_factory_1_1) { - exportStar_1(validation_controller_factory_1_1); - }, - function (validation_errors_custom_attribute_1_1) { - exportStar_1(validation_errors_custom_attribute_1_1); - }, - function (validation_renderer_custom_attribute_1_1) { - exportStar_1(validation_renderer_custom_attribute_1_1); - }, - function (validator_2_1) { - exportStar_1(validator_2_1); - validator_1 = validator_2_1; - }, - function (rules_1_1) { - exportStar_1(rules_1_1); - }, - function (standard_validator_2_1) { - exportStar_1(standard_validator_2_1); - standard_validator_1 = standard_validator_2_1; - }, - function (validation_messages_1_1) { - exportStar_1(validation_messages_1_1); - }, - function (validation_message_parser_2_1) { - exportStar_1(validation_message_parser_2_1); - validation_message_parser_1 = validation_message_parser_2_1; - }, - function (validation_rules_2_1) { - exportStar_1(validation_rules_2_1); - validation_rules_1 = validation_rules_2_1; - }, - function (aurelia_pal_1_1) { - aurelia_pal_1 = aurelia_pal_1_1; - } - ], - execute: function () {// Exports - /** - * Aurelia Validation Configuration API - */ - AureliaValidationConfiguration = /** @class */ (function () { - function AureliaValidationConfiguration() { - this.validatorType = standard_validator_1.StandardValidator; - } - /** - * Use a custom Validator implementation. - */ - AureliaValidationConfiguration.prototype.customValidator = function (type) { - this.validatorType = type; - }; - /** - * Applies the configuration. - */ - AureliaValidationConfiguration.prototype.apply = function (container) { - var validator = container.get(this.validatorType); - container.registerInstance(validator_1.Validator, validator); - }; - return AureliaValidationConfiguration; - }()); - exports_1("AureliaValidationConfiguration", AureliaValidationConfiguration); - } - }; + }; }); diff --git a/dist/system/controller-validate-result.d.ts b/dist/system/controller-validate-result.d.ts deleted file mode 100644 index 5f814ed0..00000000 --- a/dist/system/controller-validate-result.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { ValidateResult } from './validate-result'; -import { ValidateInstruction } from './validate-instruction'; -/** - * The result of a call to the validation controller's validate method. - */ -export interface ControllerValidateResult { - /** - * Whether validation passed. - */ - valid: boolean; - /** - * The validation result of every rule that was evaluated. - */ - results: ValidateResult[]; - /** - * The instruction passed to the controller's validate method. - */ - instruction?: ValidateInstruction; -} diff --git a/dist/system/controller-validate-result.js b/dist/system/controller-validate-result.js deleted file mode 100644 index 083dc444..00000000 --- a/dist/system/controller-validate-result.js +++ /dev/null @@ -1,9 +0,0 @@ -System.register([], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - return { - setters: [], - execute: function () { - } - }; -}); diff --git a/dist/system/get-target-dom-element.d.ts b/dist/system/get-target-dom-element.d.ts deleted file mode 100644 index 314fc952..00000000 --- a/dist/system/get-target-dom-element.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Gets the DOM element associated with the data-binding. Most of the time it's - * the binding.target but sometimes binding.target is an aurelia custom element, - * or custom attribute which is a javascript "class" instance, so we need to use - * the controller's container to retrieve the actual DOM element. - */ -export declare function getTargetDOMElement(binding: any, view: any): Element; diff --git a/dist/system/get-target-dom-element.js b/dist/system/get-target-dom-element.js deleted file mode 100644 index 28ec0a2e..00000000 --- a/dist/system/get-target-dom-element.js +++ /dev/null @@ -1,41 +0,0 @@ -System.register(["aurelia-pal"], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - /** - * Gets the DOM element associated with the data-binding. Most of the time it's - * the binding.target but sometimes binding.target is an aurelia custom element, - * or custom attribute which is a javascript "class" instance, so we need to use - * the controller's container to retrieve the actual DOM element. - */ - function getTargetDOMElement(binding, view) { - var target = binding.target; - // DOM element - if (target instanceof Element) { - return target; - } - // custom element or custom attribute - // tslint:disable-next-line:prefer-const - for (var i = 0, ii = view.controllers.length; i < ii; i++) { - var controller = view.controllers[i]; - if (controller.viewModel === target) { - var element = controller.container.get(aurelia_pal_1.DOM.Element); - if (element) { - return element; - } - throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\"."); - } - } - throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\"."); - } - exports_1("getTargetDOMElement", getTargetDOMElement); - var aurelia_pal_1; - return { - setters: [ - function (aurelia_pal_1_1) { - aurelia_pal_1 = aurelia_pal_1_1; - } - ], - execute: function () { - } - }; -}); diff --git a/dist/system/implementation/expression-visitor.d.ts b/dist/system/implementation/expression-visitor.d.ts deleted file mode 100644 index 47769fae..00000000 --- a/dist/system/implementation/expression-visitor.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { ValueConverter, Conditional, AccessMember, AccessKeyed, CallMember, BindingBehavior, Binary } from 'aurelia-binding'; -export declare type Chain = any; -export declare type Assign = any; -export declare type AccessThis = any; -export declare type AccessScope = any; -export declare type CallScope = any; -export declare type CallFunction = any; -export declare type PrefixNot = any; -export declare type LiteralPrimitive = any; -export declare type LiteralArray = any; -export declare type LiteralObject = any; -export declare type LiteralString = any; -export declare class ExpressionVisitor { - visitChain(chain: Chain): void; - visitBindingBehavior(behavior: BindingBehavior): void; - visitValueConverter(converter: ValueConverter): void; - visitAssign(assign: Assign): void; - visitConditional(conditional: Conditional): void; - visitAccessThis(access: AccessThis): void; - visitAccessScope(access: AccessScope): void; - visitAccessMember(access: AccessMember): void; - visitAccessKeyed(access: AccessKeyed): void; - visitCallScope(call: CallScope): void; - visitCallFunction(call: CallFunction): void; - visitCallMember(call: CallMember): void; - visitPrefix(prefix: PrefixNot): void; - visitBinary(binary: Binary): void; - visitLiteralPrimitive(literal: LiteralPrimitive): void; - visitLiteralArray(literal: LiteralArray): void; - visitLiteralObject(literal: LiteralObject): void; - visitLiteralString(literal: LiteralString): void; - private visitArgs(args); -} diff --git a/dist/system/implementation/expression-visitor.js b/dist/system/implementation/expression-visitor.js deleted file mode 100644 index 60d8b44a..00000000 --- a/dist/system/implementation/expression-visitor.js +++ /dev/null @@ -1,85 +0,0 @@ -System.register([], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var ExpressionVisitor; - return { - setters: [], - execute: function () { - // tslint:disable:no-empty - ExpressionVisitor = /** @class */ (function () { - function ExpressionVisitor() { - } - ExpressionVisitor.prototype.visitChain = function (chain) { - this.visitArgs(chain.expressions); - }; - ExpressionVisitor.prototype.visitBindingBehavior = function (behavior) { - behavior.expression.accept(this); - this.visitArgs(behavior.args); - }; - ExpressionVisitor.prototype.visitValueConverter = function (converter) { - converter.expression.accept(this); - this.visitArgs(converter.args); - }; - ExpressionVisitor.prototype.visitAssign = function (assign) { - assign.target.accept(this); - assign.value.accept(this); - }; - ExpressionVisitor.prototype.visitConditional = function (conditional) { - conditional.condition.accept(this); - conditional.yes.accept(this); - conditional.no.accept(this); - }; - ExpressionVisitor.prototype.visitAccessThis = function (access) { - access.ancestor = access.ancestor; - }; - ExpressionVisitor.prototype.visitAccessScope = function (access) { - access.name = access.name; - }; - ExpressionVisitor.prototype.visitAccessMember = function (access) { - access.object.accept(this); - }; - ExpressionVisitor.prototype.visitAccessKeyed = function (access) { - access.object.accept(this); - access.key.accept(this); - }; - ExpressionVisitor.prototype.visitCallScope = function (call) { - this.visitArgs(call.args); - }; - ExpressionVisitor.prototype.visitCallFunction = function (call) { - call.func.accept(this); - this.visitArgs(call.args); - }; - ExpressionVisitor.prototype.visitCallMember = function (call) { - call.object.accept(this); - this.visitArgs(call.args); - }; - ExpressionVisitor.prototype.visitPrefix = function (prefix) { - prefix.expression.accept(this); - }; - ExpressionVisitor.prototype.visitBinary = function (binary) { - binary.left.accept(this); - binary.right.accept(this); - }; - ExpressionVisitor.prototype.visitLiteralPrimitive = function (literal) { - literal.value = literal.value; - }; - ExpressionVisitor.prototype.visitLiteralArray = function (literal) { - this.visitArgs(literal.elements); - }; - ExpressionVisitor.prototype.visitLiteralObject = function (literal) { - this.visitArgs(literal.values); - }; - ExpressionVisitor.prototype.visitLiteralString = function (literal) { - literal.value = literal.value; - }; - ExpressionVisitor.prototype.visitArgs = function (args) { - for (var i = 0; i < args.length; i++) { - args[i].accept(this); - } - }; - return ExpressionVisitor; - }()); - exports_1("ExpressionVisitor", ExpressionVisitor); - } - }; -}); diff --git a/dist/system/implementation/rule.d.ts b/dist/system/implementation/rule.d.ts deleted file mode 100644 index ffbb7b21..00000000 --- a/dist/system/implementation/rule.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Expression } from 'aurelia-binding'; -export declare type ValidationDisplayNameAccessor = () => string; -/** - * Information related to a property that is the subject of validation. - */ -export interface RuleProperty { - /** - * The property name. null indicates the rule targets the object itself. - */ - name: string | number | null; - /** - * The displayName of the property (or object). - */ - displayName: string | ValidationDisplayNameAccessor | null; -} -/** - * A rule definition. Associations a rule with a property or object. - */ -export interface Rule { - property: RuleProperty; - condition: (value: TValue, object?: TObject) => boolean | Promise; - config: object; - when: ((object: TObject) => boolean) | null; - messageKey: string; - message: Expression | null; - sequence: number; - tag?: string; -} diff --git a/dist/system/implementation/rule.js b/dist/system/implementation/rule.js deleted file mode 100644 index 083dc444..00000000 --- a/dist/system/implementation/rule.js +++ /dev/null @@ -1,9 +0,0 @@ -System.register([], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - return { - setters: [], - execute: function () { - } - }; -}); diff --git a/dist/system/implementation/rules.d.ts b/dist/system/implementation/rules.d.ts deleted file mode 100644 index 30947f6f..00000000 --- a/dist/system/implementation/rules.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Rule } from './rule'; -/** - * Sets, unsets and retrieves rules on an object or constructor function. - */ -export declare class Rules { - /** - * The name of the property that stores the rules. - */ - private static key; - /** - * Applies the rules to a target. - */ - static set(target: any, rules: Rule[][]): void; - /** - * Removes rules from a target. - */ - static unset(target: any): void; - /** - * Retrieves the target's rules. - */ - static get(target: any): Rule[][] | null; -} diff --git a/dist/system/implementation/rules.js b/dist/system/implementation/rules.js deleted file mode 100644 index 4274f4f9..00000000 --- a/dist/system/implementation/rules.js +++ /dev/null @@ -1,47 +0,0 @@ -System.register([], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var Rules; - return { - setters: [], - execute: function () { - Rules = /** @class */ (function () { - /** - * Sets, unsets and retrieves rules on an object or constructor function. - */ - function Rules() { - } - /** - * Applies the rules to a target. - */ - Rules.set = function (target, rules) { - if (target instanceof Function) { - target = target.prototype; - } - Object.defineProperty(target, Rules.key, { enumerable: false, configurable: false, writable: true, value: rules }); - }; - /** - * Removes rules from a target. - */ - Rules.unset = function (target) { - if (target instanceof Function) { - target = target.prototype; - } - target[Rules.key] = null; - }; - /** - * Retrieves the target's rules. - */ - Rules.get = function (target) { - return target[Rules.key] || null; - }; - /** - * The name of the property that stores the rules. - */ - Rules.key = '__rules__'; - return Rules; - }()); - exports_1("Rules", Rules); - } - }; -}); diff --git a/dist/system/implementation/standard-validator.d.ts b/dist/system/implementation/standard-validator.d.ts deleted file mode 100644 index c47a7d2e..00000000 --- a/dist/system/implementation/standard-validator.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { ViewResources } from 'aurelia-templating'; -import { Validator } from '../validator'; -import { ValidateResult } from '../validate-result'; -import { Rule } from './rule'; -import { ValidationMessageProvider } from './validation-messages'; -/** - * Validates. - * Responsible for validating objects and properties. - */ -export declare class StandardValidator extends Validator { - static inject: (typeof ViewResources | typeof ValidationMessageProvider)[]; - private messageProvider; - private lookupFunctions; - private getDisplayName; - constructor(messageProvider: ValidationMessageProvider, resources: ViewResources); - /** - * Validates the specified property. - * @param object The object to validate. - * @param propertyName The name of the property to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - validateProperty(object: any, propertyName: string | number, rules?: any): Promise; - /** - * Validates all rules for specified object and it's properties. - * @param object The object to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - validateObject(object: any, rules?: any): Promise; - /** - * Determines whether a rule exists in a set of rules. - * @param rules The rules to search. - * @parem rule The rule to find. - */ - ruleExists(rules: Rule[][], rule: Rule): boolean; - private getMessage(rule, object, value); - private validateRuleSequence(object, propertyName, ruleSequence, sequence, results); - private validate(object, propertyName, rules); -} diff --git a/dist/system/implementation/standard-validator.js b/dist/system/implementation/standard-validator.js deleted file mode 100644 index 72cf6b2b..00000000 --- a/dist/system/implementation/standard-validator.js +++ /dev/null @@ -1,157 +0,0 @@ -System.register(["aurelia-templating", "../validator", "../validate-result", "./rules", "./validation-messages"], function (exports_1, context_1) { - "use strict"; - var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; - })(); - var __moduleName = context_1 && context_1.id; - var aurelia_templating_1, validator_1, validate_result_1, rules_1, validation_messages_1, StandardValidator; - return { - setters: [ - function (aurelia_templating_1_1) { - aurelia_templating_1 = aurelia_templating_1_1; - }, - function (validator_1_1) { - validator_1 = validator_1_1; - }, - function (validate_result_1_1) { - validate_result_1 = validate_result_1_1; - }, - function (rules_1_1) { - rules_1 = rules_1_1; - }, - function (validation_messages_1_1) { - validation_messages_1 = validation_messages_1_1; - } - ], - execute: function () { - StandardValidator = /** @class */ (function (_super) { - __extends(StandardValidator, _super); - function StandardValidator(messageProvider, resources) { - var _this = _super.call(this) || this; - _this.messageProvider = messageProvider; - _this.lookupFunctions = resources.lookupFunctions; - _this.getDisplayName = messageProvider.getDisplayName.bind(messageProvider); - return _this; - } - /** - * Validates the specified property. - * @param object The object to validate. - * @param propertyName The name of the property to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - StandardValidator.prototype.validateProperty = function (object, propertyName, rules) { - return this.validate(object, propertyName, rules || null); - }; - /** - * Validates all rules for specified object and it's properties. - * @param object The object to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - StandardValidator.prototype.validateObject = function (object, rules) { - return this.validate(object, null, rules || null); - }; - /** - * Determines whether a rule exists in a set of rules. - * @param rules The rules to search. - * @parem rule The rule to find. - */ - StandardValidator.prototype.ruleExists = function (rules, rule) { - var i = rules.length; - while (i--) { - if (rules[i].indexOf(rule) !== -1) { - return true; - } - } - return false; - }; - StandardValidator.prototype.getMessage = function (rule, object, value) { - var expression = rule.message || this.messageProvider.getMessage(rule.messageKey); - // tslint:disable-next-line:prefer-const - var _a = rule.property, propertyName = _a.name, displayName = _a.displayName; - if (propertyName !== null) { - displayName = this.messageProvider.getDisplayName(propertyName, displayName); - } - var overrideContext = { - $displayName: displayName, - $propertyName: propertyName, - $value: value, - $object: object, - $config: rule.config, - // returns the name of a given property, given just the property name (irrespective of the property's displayName) - // split on capital letters, first letter ensured to be capitalized - $getDisplayName: this.getDisplayName - }; - return expression.evaluate({ bindingContext: object, overrideContext: overrideContext }, this.lookupFunctions); - }; - StandardValidator.prototype.validateRuleSequence = function (object, propertyName, ruleSequence, sequence, results) { - var _this = this; - // are we validating all properties or a single property? - var validateAllProperties = propertyName === null || propertyName === undefined; - var rules = ruleSequence[sequence]; - var allValid = true; - // validate each rule. - var promises = []; - var _loop_1 = function (i) { - var rule = rules[i]; - // is the rule related to the property we're validating. - // tslint:disable-next-line:triple-equals | Use loose equality for property keys - if (!validateAllProperties && rule.property.name != propertyName) { - return "continue"; - } - // is this a conditional rule? is the condition met? - if (rule.when && !rule.when(object)) { - return "continue"; - } - // validate. - var value = rule.property.name === null ? object : object[rule.property.name]; - var promiseOrBoolean = rule.condition(value, object); - if (!(promiseOrBoolean instanceof Promise)) { - promiseOrBoolean = Promise.resolve(promiseOrBoolean); - } - promises.push(promiseOrBoolean.then(function (valid) { - var message = valid ? null : _this.getMessage(rule, object, value); - results.push(new validate_result_1.ValidateResult(rule, object, rule.property.name, valid, message)); - allValid = allValid && valid; - return valid; - })); - }; - for (var i = 0; i < rules.length; i++) { - _loop_1(i); - } - return Promise.all(promises) - .then(function () { - sequence++; - if (allValid && sequence < ruleSequence.length) { - return _this.validateRuleSequence(object, propertyName, ruleSequence, sequence, results); - } - return results; - }); - }; - StandardValidator.prototype.validate = function (object, propertyName, rules) { - // rules specified? - if (!rules) { - // no. attempt to locate the rules. - rules = rules_1.Rules.get(object); - } - // any rules? - if (!rules || rules.length === 0) { - return Promise.resolve([]); - } - return this.validateRuleSequence(object, propertyName, rules, 0, []); - }; - StandardValidator.inject = [validation_messages_1.ValidationMessageProvider, aurelia_templating_1.ViewResources]; - return StandardValidator; - }(validator_1.Validator)); - exports_1("StandardValidator", StandardValidator); - } - }; -}); diff --git a/dist/system/implementation/validation-message-parser.d.ts b/dist/system/implementation/validation-message-parser.d.ts deleted file mode 100644 index 39d288c0..00000000 --- a/dist/system/implementation/validation-message-parser.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Expression, AccessScope } from 'aurelia-binding'; -import { BindingLanguage } from 'aurelia-templating'; -import { ExpressionVisitor } from './expression-visitor'; -export declare class ValidationMessageParser { - private bindinqLanguage; - static inject: (typeof BindingLanguage)[]; - private emptyStringExpression; - private nullExpression; - private undefinedExpression; - private cache; - constructor(bindinqLanguage: BindingLanguage); - parse(message: string): Expression; - private coalesce(part); -} -export declare class MessageExpressionValidator extends ExpressionVisitor { - private originalMessage; - static validate(expression: Expression, originalMessage: string): void; - constructor(originalMessage: string); - visitAccessScope(access: AccessScope): void; -} diff --git a/dist/system/implementation/validation-message-parser.js b/dist/system/implementation/validation-message-parser.js deleted file mode 100644 index 706d1c62..00000000 --- a/dist/system/implementation/validation-message-parser.js +++ /dev/null @@ -1,88 +0,0 @@ -System.register(["aurelia-binding", "aurelia-templating", "aurelia-logging", "./expression-visitor"], function (exports_1, context_1) { - "use strict"; - var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; - })(); - var __moduleName = context_1 && context_1.id; - var aurelia_binding_1, aurelia_templating_1, LogManager, expression_visitor_1, ValidationMessageParser, MessageExpressionValidator; - return { - setters: [ - function (aurelia_binding_1_1) { - aurelia_binding_1 = aurelia_binding_1_1; - }, - function (aurelia_templating_1_1) { - aurelia_templating_1 = aurelia_templating_1_1; - }, - function (LogManager_1) { - LogManager = LogManager_1; - }, - function (expression_visitor_1_1) { - expression_visitor_1 = expression_visitor_1_1; - } - ], - execute: function () { - ValidationMessageParser = /** @class */ (function () { - function ValidationMessageParser(bindinqLanguage) { - this.bindinqLanguage = bindinqLanguage; - this.emptyStringExpression = new aurelia_binding_1.LiteralString(''); - this.nullExpression = new aurelia_binding_1.LiteralPrimitive(null); - this.undefinedExpression = new aurelia_binding_1.LiteralPrimitive(undefined); - this.cache = {}; - } - ValidationMessageParser.prototype.parse = function (message) { - if (this.cache[message] !== undefined) { - return this.cache[message]; - } - var parts = this.bindinqLanguage.parseInterpolation(null, message); - if (parts === null) { - return new aurelia_binding_1.LiteralString(message); - } - var expression = new aurelia_binding_1.LiteralString(parts[0]); - for (var i = 1; i < parts.length; i += 2) { - expression = new aurelia_binding_1.Binary('+', expression, new aurelia_binding_1.Binary('+', this.coalesce(parts[i]), new aurelia_binding_1.LiteralString(parts[i + 1]))); - } - MessageExpressionValidator.validate(expression, message); - this.cache[message] = expression; - return expression; - }; - ValidationMessageParser.prototype.coalesce = function (part) { - // part === null || part === undefined ? '' : part - return new aurelia_binding_1.Conditional(new aurelia_binding_1.Binary('||', new aurelia_binding_1.Binary('===', part, this.nullExpression), new aurelia_binding_1.Binary('===', part, this.undefinedExpression)), this.emptyStringExpression, new aurelia_binding_1.CallMember(part, 'toString', [])); - }; - ValidationMessageParser.inject = [aurelia_templating_1.BindingLanguage]; - return ValidationMessageParser; - }()); - exports_1("ValidationMessageParser", ValidationMessageParser); - MessageExpressionValidator = /** @class */ (function (_super) { - __extends(MessageExpressionValidator, _super); - function MessageExpressionValidator(originalMessage) { - var _this = _super.call(this) || this; - _this.originalMessage = originalMessage; - return _this; - } - MessageExpressionValidator.validate = function (expression, originalMessage) { - var visitor = new MessageExpressionValidator(originalMessage); - expression.accept(visitor); - }; - MessageExpressionValidator.prototype.visitAccessScope = function (access) { - if (access.ancestor !== 0) { - throw new Error('$parent is not permitted in validation message expressions.'); - } - if (['displayName', 'propertyName', 'value', 'object', 'config', 'getDisplayName'].indexOf(access.name) !== -1) { - LogManager.getLogger('aurelia-validation') - .warn("Did you mean to use \"$" + access.name + "\" instead of \"" + access.name + "\" in this validation message template: \"" + this.originalMessage + "\"?"); - } - }; - return MessageExpressionValidator; - }(expression_visitor_1.ExpressionVisitor)); - exports_1("MessageExpressionValidator", MessageExpressionValidator); - } - }; -}); diff --git a/dist/system/implementation/validation-messages.d.ts b/dist/system/implementation/validation-messages.d.ts deleted file mode 100644 index eb4cb9d4..00000000 --- a/dist/system/implementation/validation-messages.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Expression } from 'aurelia-binding'; -import { ValidationMessageParser } from './validation-message-parser'; -export interface ValidationMessages { - [key: string]: string; -} -/** - * Dictionary of validation messages. [messageKey]: messageExpression - */ -export declare const validationMessages: ValidationMessages; -/** - * Retrieves validation messages and property display names. - */ -export declare class ValidationMessageProvider { - parser: ValidationMessageParser; - static inject: (typeof ValidationMessageParser)[]; - constructor(parser: ValidationMessageParser); - /** - * Returns a message binding expression that corresponds to the key. - * @param key The message key. - */ - getMessage(key: string): Expression; - /** - * Formulates a property display name using the property name and the configured - * displayName (if provided). - * Override this with your own custom logic. - * @param propertyName The property name. - */ - getDisplayName(propertyName: string | number, displayName?: string | null | (() => string)): string; -} diff --git a/dist/system/implementation/validation-messages.js b/dist/system/implementation/validation-messages.js deleted file mode 100644 index fdde957d..00000000 --- a/dist/system/implementation/validation-messages.js +++ /dev/null @@ -1,68 +0,0 @@ -System.register(["./validation-message-parser"], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var validation_message_parser_1, validationMessages, ValidationMessageProvider; - return { - setters: [ - function (validation_message_parser_1_1) { - validation_message_parser_1 = validation_message_parser_1_1; - } - ], - execute: function () { - /** - * Dictionary of validation messages. [messageKey]: messageExpression - */ - exports_1("validationMessages", validationMessages = { - /** - * The default validation message. Used with rules that have no standard message. - */ - default: "${$displayName} is invalid.", - required: "${$displayName} is required.", - matches: "${$displayName} is not correctly formatted.", - email: "${$displayName} is not a valid email.", - minLength: "${$displayName} must be at least ${$config.length} character${$config.length === 1 ? '' : 's'}.", - maxLength: "${$displayName} cannot be longer than ${$config.length} character${$config.length === 1 ? '' : 's'}.", - minItems: "${$displayName} must contain at least ${$config.count} item${$config.count === 1 ? '' : 's'}.", - maxItems: "${$displayName} cannot contain more than ${$config.count} item${$config.count === 1 ? '' : 's'}.", - equals: "${$displayName} must be ${$config.expectedValue}.", - }); - ValidationMessageProvider = /** @class */ (function () { - function ValidationMessageProvider(parser) { - this.parser = parser; - } - /** - * Returns a message binding expression that corresponds to the key. - * @param key The message key. - */ - ValidationMessageProvider.prototype.getMessage = function (key) { - var message; - if (key in validationMessages) { - message = validationMessages[key]; - } - else { - message = validationMessages['default']; - } - return this.parser.parse(message); - }; - /** - * Formulates a property display name using the property name and the configured - * displayName (if provided). - * Override this with your own custom logic. - * @param propertyName The property name. - */ - ValidationMessageProvider.prototype.getDisplayName = function (propertyName, displayName) { - if (displayName !== null && displayName !== undefined) { - return (displayName instanceof Function) ? displayName() : displayName; - } - // split on upper-case letters. - var words = propertyName.toString().split(/(?=[A-Z])/).join(' '); - // capitalize first letter. - return words.charAt(0).toUpperCase() + words.slice(1); - }; - ValidationMessageProvider.inject = [validation_message_parser_1.ValidationMessageParser]; - return ValidationMessageProvider; - }()); - exports_1("ValidationMessageProvider", ValidationMessageProvider); - } - }; -}); diff --git a/dist/system/implementation/validation-rules.d.ts b/dist/system/implementation/validation-rules.d.ts deleted file mode 100644 index 995b2a8a..00000000 --- a/dist/system/implementation/validation-rules.d.ts +++ /dev/null @@ -1,262 +0,0 @@ -import { Rule, RuleProperty, ValidationDisplayNameAccessor } from './rule'; -import { ValidationMessageParser } from './validation-message-parser'; -import { PropertyAccessorParser, PropertyAccessor } from '../property-accessor-parser'; -/** - * Part of the fluent rule API. Enables customizing property rules. - */ -export declare class FluentRuleCustomizer { - private fluentEnsure; - private fluentRules; - private parsers; - private rule; - constructor(property: RuleProperty, condition: (value: TValue, object?: TObject) => boolean | Promise, config: object | undefined, fluentEnsure: FluentEnsure, fluentRules: FluentRules, parsers: Parsers); - /** - * Validate subsequent rules after previously declared rules have - * been validated successfully. Use to postpone validation of costly - * rules until less expensive rules pass validation. - */ - then(): this; - /** - * Specifies the key to use when looking up the rule's validation message. - */ - withMessageKey(key: string): this; - /** - * Specifies rule's validation message. - */ - withMessage(message: string): this; - /** - * Specifies a condition that must be met before attempting to validate the rule. - * @param condition A function that accepts the object as a parameter and returns true - * or false whether the rule should be evaluated. - */ - when(condition: (object: TObject) => boolean): this; - /** - * Tags the rule instance, enabling the rule to be found easily - * using ValidationRules.taggedRules(rules, tag) - */ - tag(tag: string): this; - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - ensure(subject: string | ((model: TObject) => TValue2)): FluentRules; - /** - * Targets an object with validation rules. - */ - ensureObject(): FluentRules; - /** - * Rules that have been defined using the fluent API. - */ - readonly rules: Rule[][]; - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - on(target: any): FluentEnsure; - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - satisfies(condition: (value: TValue, object: TObject) => boolean | Promise, config?: object): FluentRuleCustomizer; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - satisfiesRule(name: string, ...args: any[]): FluentRuleCustomizer; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - required(): FluentRuleCustomizer; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - matches(regex: RegExp): FluentRuleCustomizer; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - email(): FluentRuleCustomizer; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - minLength(length: number): FluentRuleCustomizer; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - maxLength(length: number): FluentRuleCustomizer; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - minItems(count: number): FluentRuleCustomizer; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - maxItems(count: number): FluentRuleCustomizer; - /** - * Applies the "equals" validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - equals(expectedValue: TValue): FluentRuleCustomizer; -} -/** - * Part of the fluent rule API. Enables applying rules to properties and objects. - */ -export declare class FluentRules { - private fluentEnsure; - private parsers; - private property; - static customRules: { - [name: string]: { - condition: (value: any, object?: any, ...fluentArgs: any[]) => boolean | Promise; - argsToConfig?: (...args: any[]) => any; - }; - }; - /** - * Current rule sequence number. Used to postpone evaluation of rules until rules - * with lower sequence number have successfully validated. The "then" fluent API method - * manages this property, there's usually no need to set it directly. - */ - sequence: number; - constructor(fluentEnsure: FluentEnsure, parsers: Parsers, property: RuleProperty); - /** - * Sets the display name of the ensured property. - */ - displayName(name: string | ValidationDisplayNameAccessor | null): this; - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - satisfies(condition: (value: TValue, object?: TObject) => boolean | Promise, config?: object): FluentRuleCustomizer; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - satisfiesRule(name: string, ...args: any[]): FluentRuleCustomizer; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - required(): FluentRuleCustomizer; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - matches(regex: RegExp): FluentRuleCustomizer; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - email(): FluentRuleCustomizer; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - minLength(length: number): FluentRuleCustomizer; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - maxLength(length: number): FluentRuleCustomizer; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - minItems(count: number): FluentRuleCustomizer; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - maxItems(count: number): FluentRuleCustomizer; - /** - * Applies the "equals" validation rule to the property. - * null and undefined values are considered valid. - */ - equals(expectedValue: TValue): FluentRuleCustomizer; -} -/** - * Part of the fluent rule API. Enables targeting properties and objects with rules. - */ -export declare class FluentEnsure { - private parsers; - /** - * Rules that have been defined using the fluent API. - */ - rules: Rule[][]; - constructor(parsers: Parsers); - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor - * function. - */ - ensure(property: string | number | PropertyAccessor): FluentRules; - /** - * Targets an object with validation rules. - */ - ensureObject(): FluentRules; - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - on(target: any): this; - private assertInitialized(); - private mergeRules(fluentRules, propertyName); -} -/** - * Fluent rule definition API. - */ -export declare class ValidationRules { - private static parsers; - static initialize(messageParser: ValidationMessageParser, propertyParser: PropertyAccessorParser): void; - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - static ensure(property: string | number | PropertyAccessor): FluentRules; - /** - * Targets an object with validation rules. - */ - static ensureObject(): FluentRules; - /** - * Defines a custom rule. - * @param name The name of the custom rule. Also serves as the message key. - * @param condition The rule function. - * @param message The message expression - * @param argsToConfig A function that maps the rule's arguments to a "config" - * object that can be used when evaluating the message expression. - */ - static customRule(name: string, condition: (value: any, object?: any, ...args: any[]) => boolean | Promise, message: string, argsToConfig?: (...args: any[]) => any): void; - /** - * Returns rules with the matching tag. - * @param rules The rules to search. - * @param tag The tag to search for. - */ - static taggedRules(rules: Rule[][], tag: string): Rule[][]; - /** - * Returns rules that have no tag. - * @param rules The rules to search. - */ - static untaggedRules(rules: Rule[][]): Rule[][]; - /** - * Removes the rules from a class or object. - * @param target A class or object. - */ - static off(target: any): void; -} -export interface Parsers { - message: ValidationMessageParser; - property: PropertyAccessorParser; -} diff --git a/dist/system/implementation/validation-rules.js b/dist/system/implementation/validation-rules.js deleted file mode 100644 index 7adcfb72..00000000 --- a/dist/system/implementation/validation-rules.js +++ /dev/null @@ -1,456 +0,0 @@ -System.register(["./rules", "./validation-messages", "../util"], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var rules_1, validation_messages_1, util_1, FluentRuleCustomizer, FluentRules, FluentEnsure, ValidationRules; - return { - setters: [ - function (rules_1_1) { - rules_1 = rules_1_1; - }, - function (validation_messages_1_1) { - validation_messages_1 = validation_messages_1_1; - }, - function (util_1_1) { - util_1 = util_1_1; - } - ], - execute: function () { - /** - * Part of the fluent rule API. Enables customizing property rules. - */ - FluentRuleCustomizer = /** @class */ (function () { - function FluentRuleCustomizer(property, condition, config, fluentEnsure, fluentRules, parsers) { - if (config === void 0) { config = {}; } - this.fluentEnsure = fluentEnsure; - this.fluentRules = fluentRules; - this.parsers = parsers; - this.rule = { - property: property, - condition: condition, - config: config, - when: null, - messageKey: 'default', - message: null, - sequence: fluentRules.sequence - }; - this.fluentEnsure._addRule(this.rule); - } - /** - * Validate subsequent rules after previously declared rules have - * been validated successfully. Use to postpone validation of costly - * rules until less expensive rules pass validation. - */ - FluentRuleCustomizer.prototype.then = function () { - this.fluentRules.sequence++; - return this; - }; - /** - * Specifies the key to use when looking up the rule's validation message. - */ - FluentRuleCustomizer.prototype.withMessageKey = function (key) { - this.rule.messageKey = key; - this.rule.message = null; - return this; - }; - /** - * Specifies rule's validation message. - */ - FluentRuleCustomizer.prototype.withMessage = function (message) { - this.rule.messageKey = 'custom'; - this.rule.message = this.parsers.message.parse(message); - return this; - }; - /** - * Specifies a condition that must be met before attempting to validate the rule. - * @param condition A function that accepts the object as a parameter and returns true - * or false whether the rule should be evaluated. - */ - FluentRuleCustomizer.prototype.when = function (condition) { - this.rule.when = condition; - return this; - }; - /** - * Tags the rule instance, enabling the rule to be found easily - * using ValidationRules.taggedRules(rules, tag) - */ - FluentRuleCustomizer.prototype.tag = function (tag) { - this.rule.tag = tag; - return this; - }; - ///// FluentEnsure APIs ///// - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - FluentRuleCustomizer.prototype.ensure = function (subject) { - return this.fluentEnsure.ensure(subject); - }; - /** - * Targets an object with validation rules. - */ - FluentRuleCustomizer.prototype.ensureObject = function () { - return this.fluentEnsure.ensureObject(); - }; - Object.defineProperty(FluentRuleCustomizer.prototype, "rules", { - /** - * Rules that have been defined using the fluent API. - */ - get: function () { - return this.fluentEnsure.rules; - }, - enumerable: true, - configurable: true - }); - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - FluentRuleCustomizer.prototype.on = function (target) { - return this.fluentEnsure.on(target); - }; - ///////// FluentRules APIs ///////// - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - FluentRuleCustomizer.prototype.satisfies = function (condition, config) { - return this.fluentRules.satisfies(condition, config); - }; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - FluentRuleCustomizer.prototype.satisfiesRule = function (name) { - var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; - } - return (_a = this.fluentRules).satisfiesRule.apply(_a, [name].concat(args)); - var _a; - }; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - FluentRuleCustomizer.prototype.required = function () { - return this.fluentRules.required(); - }; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.matches = function (regex) { - return this.fluentRules.matches(regex); - }; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.email = function () { - return this.fluentRules.email(); - }; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.minLength = function (length) { - return this.fluentRules.minLength(length); - }; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.maxLength = function (length) { - return this.fluentRules.maxLength(length); - }; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRuleCustomizer.prototype.minItems = function (count) { - return this.fluentRules.minItems(count); - }; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRuleCustomizer.prototype.maxItems = function (count) { - return this.fluentRules.maxItems(count); - }; - /** - * Applies the "equals" validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRuleCustomizer.prototype.equals = function (expectedValue) { - return this.fluentRules.equals(expectedValue); - }; - return FluentRuleCustomizer; - }()); - exports_1("FluentRuleCustomizer", FluentRuleCustomizer); - FluentRules = /** @class */ (function () { - function FluentRules(fluentEnsure, parsers, property) { - this.fluentEnsure = fluentEnsure; - this.parsers = parsers; - this.property = property; - /** - * Current rule sequence number. Used to postpone evaluation of rules until rules - * with lower sequence number have successfully validated. The "then" fluent API method - * manages this property, there's usually no need to set it directly. - */ - this.sequence = 0; - } - /** - * Sets the display name of the ensured property. - */ - FluentRules.prototype.displayName = function (name) { - this.property.displayName = name; - return this; - }; - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - FluentRules.prototype.satisfies = function (condition, config) { - return new FluentRuleCustomizer(this.property, condition, config, this.fluentEnsure, this, this.parsers); - }; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - FluentRules.prototype.satisfiesRule = function (name) { - var _this = this; - var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; - } - var rule = FluentRules.customRules[name]; - if (!rule) { - // standard rule? - rule = this[name]; - if (rule instanceof Function) { - return rule.call.apply(rule, [this].concat(args)); - } - throw new Error("Rule with name \"" + name + "\" does not exist."); - } - var config = rule.argsToConfig ? rule.argsToConfig.apply(rule, args) : undefined; - return this.satisfies(function (value, obj) { - return (_a = rule.condition).call.apply(_a, [_this, value, obj].concat(args)); - var _a; - }, config) - .withMessageKey(name); - }; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - FluentRules.prototype.required = function () { - return this.satisfies(function (value) { - return value !== null - && value !== undefined - && !(util_1.isString(value) && !/\S/.test(value)); - }).withMessageKey('required'); - }; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - FluentRules.prototype.matches = function (regex) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || regex.test(value); }) - .withMessageKey('matches'); - }; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRules.prototype.email = function () { - // regex from https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address - /* tslint:disable:max-line-length */ - return this.matches(/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/) - .withMessageKey('email'); - }; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRules.prototype.minLength = function (length) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || value.length >= length; }, { length: length }) - .withMessageKey('minLength'); - }; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - FluentRules.prototype.maxLength = function (length) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length === 0 || value.length <= length; }, { length: length }) - .withMessageKey('maxLength'); - }; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRules.prototype.minItems = function (count) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length >= count; }, { count: count }) - .withMessageKey('minItems'); - }; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRules.prototype.maxItems = function (count) { - return this.satisfies(function (value) { return value === null || value === undefined || value.length <= count; }, { count: count }) - .withMessageKey('maxItems'); - }; - /** - * Applies the "equals" validation rule to the property. - * null and undefined values are considered valid. - */ - FluentRules.prototype.equals = function (expectedValue) { - return this.satisfies(function (value) { return value === null || value === undefined || value === '' || value === expectedValue; }, { expectedValue: expectedValue }) - .withMessageKey('equals'); - }; - FluentRules.customRules = {}; - return FluentRules; - }()); - exports_1("FluentRules", FluentRules); - /** - * Part of the fluent rule API. Enables targeting properties and objects with rules. - */ - FluentEnsure = /** @class */ (function () { - function FluentEnsure(parsers) { - this.parsers = parsers; - /** - * Rules that have been defined using the fluent API. - */ - this.rules = []; - } - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor - * function. - */ - FluentEnsure.prototype.ensure = function (property) { - this.assertInitialized(); - var name = this.parsers.property.parse(property); - var fluentRules = new FluentRules(this, this.parsers, { name: name, displayName: null }); - return this.mergeRules(fluentRules, name); - }; - /** - * Targets an object with validation rules. - */ - FluentEnsure.prototype.ensureObject = function () { - this.assertInitialized(); - var fluentRules = new FluentRules(this, this.parsers, { name: null, displayName: null }); - return this.mergeRules(fluentRules, null); - }; - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - FluentEnsure.prototype.on = function (target) { - rules_1.Rules.set(target, this.rules); - return this; - }; - /** - * Adds a rule definition to the sequenced ruleset. - * @internal - */ - FluentEnsure.prototype._addRule = function (rule) { - while (this.rules.length < rule.sequence + 1) { - this.rules.push([]); - } - this.rules[rule.sequence].push(rule); - }; - FluentEnsure.prototype.assertInitialized = function () { - if (this.parsers) { - return; - } - throw new Error("Did you forget to add \".plugin('aurelia-validation')\" to your main.js?"); - }; - FluentEnsure.prototype.mergeRules = function (fluentRules, propertyName) { - // tslint:disable-next-line:triple-equals | Use loose equality for property keys - var existingRules = this.rules.find(function (r) { return r.length > 0 && r[0].property.name == propertyName; }); - if (existingRules) { - var rule = existingRules[existingRules.length - 1]; - fluentRules.sequence = rule.sequence; - if (rule.property.displayName !== null) { - fluentRules = fluentRules.displayName(rule.property.displayName); - } - } - return fluentRules; - }; - return FluentEnsure; - }()); - exports_1("FluentEnsure", FluentEnsure); - /** - * Fluent rule definition API. - */ - ValidationRules = /** @class */ (function () { - function ValidationRules() { - } - ValidationRules.initialize = function (messageParser, propertyParser) { - this.parsers = { - message: messageParser, - property: propertyParser - }; - }; - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - ValidationRules.ensure = function (property) { - return new FluentEnsure(ValidationRules.parsers).ensure(property); - }; - /** - * Targets an object with validation rules. - */ - ValidationRules.ensureObject = function () { - return new FluentEnsure(ValidationRules.parsers).ensureObject(); - }; - /** - * Defines a custom rule. - * @param name The name of the custom rule. Also serves as the message key. - * @param condition The rule function. - * @param message The message expression - * @param argsToConfig A function that maps the rule's arguments to a "config" - * object that can be used when evaluating the message expression. - */ - ValidationRules.customRule = function (name, condition, message, argsToConfig) { - validation_messages_1.validationMessages[name] = message; - FluentRules.customRules[name] = { condition: condition, argsToConfig: argsToConfig }; - }; - /** - * Returns rules with the matching tag. - * @param rules The rules to search. - * @param tag The tag to search for. - */ - ValidationRules.taggedRules = function (rules, tag) { - return rules.map(function (x) { return x.filter(function (r) { return r.tag === tag; }); }); - }; - /** - * Returns rules that have no tag. - * @param rules The rules to search. - */ - ValidationRules.untaggedRules = function (rules) { - return rules.map(function (x) { return x.filter(function (r) { return r.tag === undefined; }); }); - }; - /** - * Removes the rules from a class or object. - * @param target A class or object. - */ - ValidationRules.off = function (target) { - rules_1.Rules.unset(target); - }; - return ValidationRules; - }()); - exports_1("ValidationRules", ValidationRules); - } - }; -}); diff --git a/dist/system/property-accessor-parser.d.ts b/dist/system/property-accessor-parser.d.ts deleted file mode 100644 index ba64614b..00000000 --- a/dist/system/property-accessor-parser.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Parser } from 'aurelia-binding'; -export declare type PropertyAccessor = (object: TObject) => TValue; -export declare class PropertyAccessorParser { - private parser; - static inject: (typeof Parser)[]; - constructor(parser: Parser); - parse(property: string | number | PropertyAccessor): string | number; -} -export declare function getAccessorExpression(fn: string): string; diff --git a/dist/system/property-accessor-parser.js b/dist/system/property-accessor-parser.js deleted file mode 100644 index d027b6a8..00000000 --- a/dist/system/property-accessor-parser.js +++ /dev/null @@ -1,49 +0,0 @@ -System.register(["aurelia-binding", "./util"], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - function getAccessorExpression(fn) { - /* tslint:disable:max-line-length */ - var classic = /^function\s*\([$_\w\d]+\)\s*\{(?:\s*"use strict";)?\s*(?:[$_\w\d.['"\]+;]+)?\s*return\s+[$_\w\d]+\.([$_\w\d]+)\s*;?\s*\}$/; - /* tslint:enable:max-line-length */ - var arrow = /^\(?[$_\w\d]+\)?\s*=>\s*[$_\w\d]+\.([$_\w\d]+)$/; - var match = classic.exec(fn) || arrow.exec(fn); - if (match === null) { - throw new Error("Unable to parse accessor function:\n" + fn); - } - return match[1]; - } - exports_1("getAccessorExpression", getAccessorExpression); - var aurelia_binding_1, util_1, PropertyAccessorParser; - return { - setters: [ - function (aurelia_binding_1_1) { - aurelia_binding_1 = aurelia_binding_1_1; - }, - function (util_1_1) { - util_1 = util_1_1; - } - ], - execute: function () { - PropertyAccessorParser = /** @class */ (function () { - function PropertyAccessorParser(parser) { - this.parser = parser; - } - PropertyAccessorParser.prototype.parse = function (property) { - if (util_1.isString(property) || util_1.isNumber(property)) { - return property; - } - var accessorText = getAccessorExpression(property.toString()); - var accessor = this.parser.parse(accessorText); - if (accessor instanceof aurelia_binding_1.AccessScope - || accessor instanceof aurelia_binding_1.AccessMember && accessor.object instanceof aurelia_binding_1.AccessScope) { - return accessor.name; - } - throw new Error("Invalid property expression: \"" + accessor + "\""); - }; - PropertyAccessorParser.inject = [aurelia_binding_1.Parser]; - return PropertyAccessorParser; - }()); - exports_1("PropertyAccessorParser", PropertyAccessorParser); - } - }; -}); diff --git a/dist/system/property-info.d.ts b/dist/system/property-info.d.ts deleted file mode 100644 index 35fef1d5..00000000 --- a/dist/system/property-info.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Expression, Scope } from 'aurelia-binding'; -/** - * Retrieves the object and property name for the specified expression. - * @param expression The expression - * @param source The scope - */ -export declare function getPropertyInfo(expression: Expression, source: Scope): { - object: object; - propertyName: string; -} | null; diff --git a/dist/system/property-info.js b/dist/system/property-info.js deleted file mode 100644 index 462545d4..00000000 --- a/dist/system/property-info.js +++ /dev/null @@ -1,55 +0,0 @@ -System.register(["aurelia-binding"], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - function getObject(expression, objectExpression, source) { - var value = objectExpression.evaluate(source, null); - if (value === null || value === undefined || value instanceof Object) { - return value; - } - // tslint:disable-next-line:max-line-length - throw new Error("The '" + objectExpression + "' part of '" + expression + "' evaluates to " + value + " instead of an object, null or undefined."); - } - /** - * Retrieves the object and property name for the specified expression. - * @param expression The expression - * @param source The scope - */ - function getPropertyInfo(expression, source) { - var originalExpression = expression; - while (expression instanceof aurelia_binding_1.BindingBehavior || expression instanceof aurelia_binding_1.ValueConverter) { - expression = expression.expression; - } - var object; - var propertyName; - if (expression instanceof aurelia_binding_1.AccessScope) { - object = aurelia_binding_1.getContextFor(expression.name, source, expression.ancestor); - propertyName = expression.name; - } - else if (expression instanceof aurelia_binding_1.AccessMember) { - object = getObject(originalExpression, expression.object, source); - propertyName = expression.name; - } - else if (expression instanceof aurelia_binding_1.AccessKeyed) { - object = getObject(originalExpression, expression.object, source); - propertyName = expression.key.evaluate(source); - } - else { - throw new Error("Expression '" + originalExpression + "' is not compatible with the validate binding-behavior."); - } - if (object === null || object === undefined) { - return null; - } - return { object: object, propertyName: propertyName }; - } - exports_1("getPropertyInfo", getPropertyInfo); - var aurelia_binding_1; - return { - setters: [ - function (aurelia_binding_1_1) { - aurelia_binding_1 = aurelia_binding_1_1; - } - ], - execute: function () { - } - }; -}); diff --git a/dist/system/util.d.ts b/dist/system/util.d.ts deleted file mode 100644 index f6873f03..00000000 --- a/dist/system/util.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export declare function isString(value: any): boolean; -export declare function isNumber(value: any): boolean; diff --git a/dist/system/util.js b/dist/system/util.js deleted file mode 100644 index 78786a23..00000000 --- a/dist/system/util.js +++ /dev/null @@ -1,17 +0,0 @@ -System.register([], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - function isString(value) { - return Object.prototype.toString.call(value) === '[object String]'; - } - exports_1("isString", isString); - function isNumber(value) { - return Object.prototype.toString.call(value) === '[object Number]'; - } - exports_1("isNumber", isNumber); - return { - setters: [], - execute: function () { - } - }; -}); diff --git a/dist/system/validate-binding-behavior-base.d.ts b/dist/system/validate-binding-behavior-base.d.ts deleted file mode 100644 index 971c8e83..00000000 --- a/dist/system/validate-binding-behavior-base.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { TaskQueue } from 'aurelia-task-queue'; -import { ValidationController } from './validation-controller'; -import { validateTrigger } from './validate-trigger'; -/** - * Binding behavior. Indicates the bound property should be validated. - */ -export declare abstract class ValidateBindingBehaviorBase { - private taskQueue; - constructor(taskQueue: TaskQueue); - protected abstract getValidateTrigger(controller: ValidationController): validateTrigger; - bind(binding: any, source: any, rulesOrController?: ValidationController | any, rules?: any): void; - unbind(binding: any): void; -} diff --git a/dist/system/validate-binding-behavior-base.js b/dist/system/validate-binding-behavior-base.js deleted file mode 100644 index b364839e..00000000 --- a/dist/system/validate-binding-behavior-base.js +++ /dev/null @@ -1,98 +0,0 @@ -System.register(["aurelia-dependency-injection", "./validation-controller", "./validate-trigger", "./get-target-dom-element"], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var aurelia_dependency_injection_1, validation_controller_1, validate_trigger_1, get_target_dom_element_1, ValidateBindingBehaviorBase; - return { - setters: [ - function (aurelia_dependency_injection_1_1) { - aurelia_dependency_injection_1 = aurelia_dependency_injection_1_1; - }, - function (validation_controller_1_1) { - validation_controller_1 = validation_controller_1_1; - }, - function (validate_trigger_1_1) { - validate_trigger_1 = validate_trigger_1_1; - }, - function (get_target_dom_element_1_1) { - get_target_dom_element_1 = get_target_dom_element_1_1; - } - ], - execute: function () { - /** - * Binding behavior. Indicates the bound property should be validated. - */ - ValidateBindingBehaviorBase = /** @class */ (function () { - function ValidateBindingBehaviorBase(taskQueue) { - this.taskQueue = taskQueue; - } - ValidateBindingBehaviorBase.prototype.bind = function (binding, source, rulesOrController, rules) { - var _this = this; - // identify the target element. - var target = get_target_dom_element_1.getTargetDOMElement(binding, source); - // locate the controller. - var controller; - if (rulesOrController instanceof validation_controller_1.ValidationController) { - controller = rulesOrController; - } - else { - controller = source.container.get(aurelia_dependency_injection_1.Optional.of(validation_controller_1.ValidationController)); - rules = rulesOrController; - } - if (controller === null) { - throw new Error("A ValidationController has not been registered."); - } - controller.registerBinding(binding, target, rules); - binding.validationController = controller; - var trigger = this.getValidateTrigger(controller); - // tslint:disable-next-line:no-bitwise - if (trigger & validate_trigger_1.validateTrigger.change) { - binding.vbbUpdateSource = binding.updateSource; - // tslint:disable-next-line:only-arrow-functions - // tslint:disable-next-line:space-before-function-paren - binding.updateSource = function (value) { - this.vbbUpdateSource(value); - this.validationController.validateBinding(this); - }; - } - // tslint:disable-next-line:no-bitwise - if (trigger & validate_trigger_1.validateTrigger.blur) { - binding.validateBlurHandler = function () { - _this.taskQueue.queueMicroTask(function () { return controller.validateBinding(binding); }); - }; - binding.validateTarget = target; - target.addEventListener('blur', binding.validateBlurHandler); - } - if (trigger !== validate_trigger_1.validateTrigger.manual) { - binding.standardUpdateTarget = binding.updateTarget; - // tslint:disable-next-line:only-arrow-functions - // tslint:disable-next-line:space-before-function-paren - binding.updateTarget = function (value) { - this.standardUpdateTarget(value); - this.validationController.resetBinding(this); - }; - } - }; - ValidateBindingBehaviorBase.prototype.unbind = function (binding) { - // reset the binding to it's original state. - if (binding.vbbUpdateSource) { - binding.updateSource = binding.vbbUpdateSource; - binding.vbbUpdateSource = null; - } - if (binding.standardUpdateTarget) { - binding.updateTarget = binding.standardUpdateTarget; - binding.standardUpdateTarget = null; - } - if (binding.validateBlurHandler) { - binding.validateTarget.removeEventListener('blur', binding.validateBlurHandler); - binding.validateBlurHandler = null; - binding.validateTarget = null; - } - binding.validationController.unregisterBinding(binding); - binding.validationController = null; - }; - return ValidateBindingBehaviorBase; - }()); - exports_1("ValidateBindingBehaviorBase", ValidateBindingBehaviorBase); - } - }; -}); diff --git a/dist/system/validate-binding-behavior.d.ts b/dist/system/validate-binding-behavior.d.ts deleted file mode 100644 index 08b5d9e0..00000000 --- a/dist/system/validate-binding-behavior.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { TaskQueue } from 'aurelia-task-queue'; -import { ValidationController } from './validation-controller'; -import { validateTrigger } from './validate-trigger'; -import { ValidateBindingBehaviorBase } from './validate-binding-behavior-base'; -/** - * Binding behavior. Indicates the bound property should be validated - * when the validate trigger specified by the associated controller's - * validateTrigger property occurs. - */ -export declare class ValidateBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(controller: ValidationController): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property will be validated - * manually, by calling controller.validate(). No automatic validation - * triggered by data-entry or blur will occur. - */ -export declare class ValidateManuallyBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs. - */ -export declare class ValidateOnBlurBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element is changed by the user, causing a change - * to the model. - */ -export declare class ValidateOnChangeBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs or is changed by the user, causing - * a change to the model. - */ -export declare class ValidateOnChangeOrBlurBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} diff --git a/dist/system/validate-binding-behavior.js b/dist/system/validate-binding-behavior.js deleted file mode 100644 index 2032378a..00000000 --- a/dist/system/validate-binding-behavior.js +++ /dev/null @@ -1,114 +0,0 @@ -System.register(["aurelia-task-queue", "./validate-trigger", "./validate-binding-behavior-base"], function (exports_1, context_1) { - "use strict"; - var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; - })(); - var __moduleName = context_1 && context_1.id; - var aurelia_task_queue_1, validate_trigger_1, validate_binding_behavior_base_1, ValidateBindingBehavior, ValidateManuallyBindingBehavior, ValidateOnBlurBindingBehavior, ValidateOnChangeBindingBehavior, ValidateOnChangeOrBlurBindingBehavior; - return { - setters: [ - function (aurelia_task_queue_1_1) { - aurelia_task_queue_1 = aurelia_task_queue_1_1; - }, - function (validate_trigger_1_1) { - validate_trigger_1 = validate_trigger_1_1; - }, - function (validate_binding_behavior_base_1_1) { - validate_binding_behavior_base_1 = validate_binding_behavior_base_1_1; - } - ], - execute: function () { - ValidateBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateBindingBehavior, _super); - /** - * Binding behavior. Indicates the bound property should be validated - * when the validate trigger specified by the associated controller's - * validateTrigger property occurs. - */ - function ValidateBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateBindingBehavior.prototype.getValidateTrigger = function (controller) { - return controller.validateTrigger; - }; - ValidateBindingBehavior.inject = [aurelia_task_queue_1.TaskQueue]; - return ValidateBindingBehavior; - }(validate_binding_behavior_base_1.ValidateBindingBehaviorBase)); - exports_1("ValidateBindingBehavior", ValidateBindingBehavior); - ValidateManuallyBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateManuallyBindingBehavior, _super); - /** - * Binding behavior. Indicates the bound property will be validated - * manually, by calling controller.validate(). No automatic validation - * triggered by data-entry or blur will occur. - */ - function ValidateManuallyBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateManuallyBindingBehavior.prototype.getValidateTrigger = function () { - return validate_trigger_1.validateTrigger.manual; - }; - ValidateManuallyBindingBehavior.inject = [aurelia_task_queue_1.TaskQueue]; - return ValidateManuallyBindingBehavior; - }(validate_binding_behavior_base_1.ValidateBindingBehaviorBase)); - exports_1("ValidateManuallyBindingBehavior", ValidateManuallyBindingBehavior); - ValidateOnBlurBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateOnBlurBindingBehavior, _super); - /** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs. - */ - function ValidateOnBlurBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateOnBlurBindingBehavior.prototype.getValidateTrigger = function () { - return validate_trigger_1.validateTrigger.blur; - }; - ValidateOnBlurBindingBehavior.inject = [aurelia_task_queue_1.TaskQueue]; - return ValidateOnBlurBindingBehavior; - }(validate_binding_behavior_base_1.ValidateBindingBehaviorBase)); - exports_1("ValidateOnBlurBindingBehavior", ValidateOnBlurBindingBehavior); - ValidateOnChangeBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateOnChangeBindingBehavior, _super); - /** - * Binding behavior. Indicates the bound property should be validated - * when the associated element is changed by the user, causing a change - * to the model. - */ - function ValidateOnChangeBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateOnChangeBindingBehavior.prototype.getValidateTrigger = function () { - return validate_trigger_1.validateTrigger.change; - }; - ValidateOnChangeBindingBehavior.inject = [aurelia_task_queue_1.TaskQueue]; - return ValidateOnChangeBindingBehavior; - }(validate_binding_behavior_base_1.ValidateBindingBehaviorBase)); - exports_1("ValidateOnChangeBindingBehavior", ValidateOnChangeBindingBehavior); - ValidateOnChangeOrBlurBindingBehavior = /** @class */ (function (_super) { - __extends(ValidateOnChangeOrBlurBindingBehavior, _super); - /** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs or is changed by the user, causing - * a change to the model. - */ - function ValidateOnChangeOrBlurBindingBehavior() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidateOnChangeOrBlurBindingBehavior.prototype.getValidateTrigger = function () { - return validate_trigger_1.validateTrigger.changeOrBlur; - }; - ValidateOnChangeOrBlurBindingBehavior.inject = [aurelia_task_queue_1.TaskQueue]; - return ValidateOnChangeOrBlurBindingBehavior; - }(validate_binding_behavior_base_1.ValidateBindingBehaviorBase)); - exports_1("ValidateOnChangeOrBlurBindingBehavior", ValidateOnChangeOrBlurBindingBehavior); - } - }; -}); diff --git a/dist/system/validate-event.d.ts b/dist/system/validate-event.d.ts deleted file mode 100644 index 0fbacbb7..00000000 --- a/dist/system/validate-event.d.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { ValidateResult } from './validate-result'; -import { ValidateInstruction } from './validate-instruction'; -import { ControllerValidateResult } from './controller-validate-result'; -export declare class ValidateEvent { - /** - * The type of validate event. Either "validate" or "reset". - */ - readonly type: 'validate' | 'reset'; - /** - * The controller's current array of errors. For an array containing both - * failed rules and passed rules, use the "results" property. - */ - readonly errors: ValidateResult[]; - /** - * The controller's current array of validate results. This - * includes both passed rules and failed rules. For an array of only failed rules, - * use the "errors" property. - */ - readonly results: ValidateResult[]; - /** - * The instruction passed to the "validate" or "reset" event. Will be null when - * the controller's validate/reset method was called with no instruction argument. - */ - readonly instruction: ValidateInstruction | null; - /** - * In events with type === "validate", this property will contain the result - * of validating the instruction (see "instruction" property). Use the controllerValidateResult - * to access the validate results specific to the call to "validate" - * (as opposed to using the "results" and "errors" properties to access the controller's entire - * set of results/errors). - */ - readonly controllerValidateResult: ControllerValidateResult | null; - constructor( - /** - * The type of validate event. Either "validate" or "reset". - */ - type: 'validate' | 'reset', - /** - * The controller's current array of errors. For an array containing both - * failed rules and passed rules, use the "results" property. - */ - errors: ValidateResult[], - /** - * The controller's current array of validate results. This - * includes both passed rules and failed rules. For an array of only failed rules, - * use the "errors" property. - */ - results: ValidateResult[], - /** - * The instruction passed to the "validate" or "reset" event. Will be null when - * the controller's validate/reset method was called with no instruction argument. - */ - instruction: ValidateInstruction | null, - /** - * In events with type === "validate", this property will contain the result - * of validating the instruction (see "instruction" property). Use the controllerValidateResult - * to access the validate results specific to the call to "validate" - * (as opposed to using the "results" and "errors" properties to access the controller's entire - * set of results/errors). - */ - controllerValidateResult: ControllerValidateResult | null); -} diff --git a/dist/system/validate-event.js b/dist/system/validate-event.js deleted file mode 100644 index 832fd04f..00000000 --- a/dist/system/validate-event.js +++ /dev/null @@ -1,49 +0,0 @@ -System.register([], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var ValidateEvent; - return { - setters: [], - execute: function () { - ValidateEvent = /** @class */ (function () { - function ValidateEvent( - /** - * The type of validate event. Either "validate" or "reset". - */ - type, - /** - * The controller's current array of errors. For an array containing both - * failed rules and passed rules, use the "results" property. - */ - errors, - /** - * The controller's current array of validate results. This - * includes both passed rules and failed rules. For an array of only failed rules, - * use the "errors" property. - */ - results, - /** - * The instruction passed to the "validate" or "reset" event. Will be null when - * the controller's validate/reset method was called with no instruction argument. - */ - instruction, - /** - * In events with type === "validate", this property will contain the result - * of validating the instruction (see "instruction" property). Use the controllerValidateResult - * to access the validate results specific to the call to "validate" - * (as opposed to using the "results" and "errors" properties to access the controller's entire - * set of results/errors). - */ - controllerValidateResult) { - this.type = type; - this.errors = errors; - this.results = results; - this.instruction = instruction; - this.controllerValidateResult = controllerValidateResult; - } - return ValidateEvent; - }()); - exports_1("ValidateEvent", ValidateEvent); - } - }; -}); diff --git a/dist/system/validate-instruction.d.ts b/dist/system/validate-instruction.d.ts deleted file mode 100644 index 2f792a70..00000000 --- a/dist/system/validate-instruction.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Instructions for the validation controller's validate method. - */ -export interface ValidateInstruction { - /** - * The object to validate. - */ - object: any; - /** - * The property to validate. Optional. - */ - propertyName?: any; - /** - * The rules to validate. Optional. - */ - rules?: any; -} diff --git a/dist/system/validate-instruction.js b/dist/system/validate-instruction.js deleted file mode 100644 index 083dc444..00000000 --- a/dist/system/validate-instruction.js +++ /dev/null @@ -1,9 +0,0 @@ -System.register([], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - return { - setters: [], - execute: function () { - } - }; -}); diff --git a/dist/system/validate-result.d.ts b/dist/system/validate-result.d.ts deleted file mode 100644 index 91d79995..00000000 --- a/dist/system/validate-result.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * The result of validating an individual validation rule. - */ -export declare class ValidateResult { - rule: any; - object: any; - propertyName: string | number | null; - valid: boolean; - message: string | null; - private static nextId; - /** - * A number that uniquely identifies the result instance. - */ - id: number; - /** - * @param rule The rule associated with the result. Validator implementation specific. - * @param object The object that was validated. - * @param propertyName The name of the property that was validated. - * @param error The error, if the result is a validation error. - */ - constructor(rule: any, object: any, propertyName: string | number | null, valid: boolean, message?: string | null); - toString(): string | null; -} diff --git a/dist/system/validate-result.js b/dist/system/validate-result.js deleted file mode 100644 index da06f9fe..00000000 --- a/dist/system/validate-result.js +++ /dev/null @@ -1,33 +0,0 @@ -System.register([], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var ValidateResult; - return { - setters: [], - execute: function () { - ValidateResult = /** @class */ (function () { - /** - * @param rule The rule associated with the result. Validator implementation specific. - * @param object The object that was validated. - * @param propertyName The name of the property that was validated. - * @param error The error, if the result is a validation error. - */ - function ValidateResult(rule, object, propertyName, valid, message) { - if (message === void 0) { message = null; } - this.rule = rule; - this.object = object; - this.propertyName = propertyName; - this.valid = valid; - this.message = message; - this.id = ValidateResult.nextId++; - } - ValidateResult.prototype.toString = function () { - return this.valid ? 'Valid.' : this.message; - }; - ValidateResult.nextId = 0; - return ValidateResult; - }()); - exports_1("ValidateResult", ValidateResult); - } - }; -}); diff --git a/dist/system/validate-trigger.d.ts b/dist/system/validate-trigger.d.ts deleted file mode 100644 index 43e76851..00000000 --- a/dist/system/validate-trigger.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Validation triggers. - */ -export declare enum validateTrigger { - /** - * Manual validation. Use the controller's `validate()` and `reset()` methods - * to validate all bindings. - */ - manual = 0, - /** - * Validate the binding when the binding's target element fires a DOM "blur" event. - */ - blur = 1, - /** - * Validate the binding when it updates the model due to a change in the view. - */ - change = 2, - /** - * Validate the binding when the binding's target element fires a DOM "blur" event and - * when it updates the model due to a change in the view. - */ - changeOrBlur = 3, -} diff --git a/dist/system/validate-trigger.js b/dist/system/validate-trigger.js deleted file mode 100644 index 7cf2a364..00000000 --- a/dist/system/validate-trigger.js +++ /dev/null @@ -1,34 +0,0 @@ -System.register([], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var validateTrigger; - return { - setters: [], - execute: function () { - /** - * Validation triggers. - */ - (function (validateTrigger) { - /** - * Manual validation. Use the controller's `validate()` and `reset()` methods - * to validate all bindings. - */ - validateTrigger[validateTrigger["manual"] = 0] = "manual"; - /** - * Validate the binding when the binding's target element fires a DOM "blur" event. - */ - validateTrigger[validateTrigger["blur"] = 1] = "blur"; - /** - * Validate the binding when it updates the model due to a change in the view. - */ - validateTrigger[validateTrigger["change"] = 2] = "change"; - /** - * Validate the binding when the binding's target element fires a DOM "blur" event and - * when it updates the model due to a change in the view. - */ - validateTrigger[validateTrigger["changeOrBlur"] = 3] = "changeOrBlur"; - })(validateTrigger || (validateTrigger = {})); - exports_1("validateTrigger", validateTrigger); - } - }; -}); diff --git a/dist/system/validation-controller-factory.d.ts b/dist/system/validation-controller-factory.d.ts deleted file mode 100644 index 2c51999e..00000000 --- a/dist/system/validation-controller-factory.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Container } from 'aurelia-dependency-injection'; -import { ValidationController } from './validation-controller'; -import { Validator } from './validator'; -/** - * Creates ValidationController instances. - */ -export declare class ValidationControllerFactory { - private container; - static get(container: Container): ValidationControllerFactory; - constructor(container: Container); - /** - * Creates a new controller instance. - */ - create(validator?: Validator): ValidationController; - /** - * Creates a new controller and registers it in the current element's container so that it's - * available to the validate binding behavior and renderers. - */ - createForCurrentScope(validator?: Validator): ValidationController; -} diff --git a/dist/system/validation-controller-factory.js b/dist/system/validation-controller-factory.js deleted file mode 100644 index fa48f1a0..00000000 --- a/dist/system/validation-controller-factory.js +++ /dev/null @@ -1,53 +0,0 @@ -System.register(["./validation-controller", "./validator", "./property-accessor-parser"], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var validation_controller_1, validator_1, property_accessor_parser_1, ValidationControllerFactory; - return { - setters: [ - function (validation_controller_1_1) { - validation_controller_1 = validation_controller_1_1; - }, - function (validator_1_1) { - validator_1 = validator_1_1; - }, - function (property_accessor_parser_1_1) { - property_accessor_parser_1 = property_accessor_parser_1_1; - } - ], - execute: function () { - /** - * Creates ValidationController instances. - */ - ValidationControllerFactory = /** @class */ (function () { - function ValidationControllerFactory(container) { - this.container = container; - } - ValidationControllerFactory.get = function (container) { - return new ValidationControllerFactory(container); - }; - /** - * Creates a new controller instance. - */ - ValidationControllerFactory.prototype.create = function (validator) { - if (!validator) { - validator = this.container.get(validator_1.Validator); - } - var propertyParser = this.container.get(property_accessor_parser_1.PropertyAccessorParser); - return new validation_controller_1.ValidationController(validator, propertyParser); - }; - /** - * Creates a new controller and registers it in the current element's container so that it's - * available to the validate binding behavior and renderers. - */ - ValidationControllerFactory.prototype.createForCurrentScope = function (validator) { - var controller = this.create(validator); - this.container.registerInstance(validation_controller_1.ValidationController, controller); - return controller; - }; - return ValidationControllerFactory; - }()); - exports_1("ValidationControllerFactory", ValidationControllerFactory); - ValidationControllerFactory['protocol:aurelia:resolver'] = true; - } - }; -}); diff --git a/dist/system/validation-controller.d.ts b/dist/system/validation-controller.d.ts deleted file mode 100644 index 7f208d49..00000000 --- a/dist/system/validation-controller.d.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { Binding } from 'aurelia-binding'; -import { Validator } from './validator'; -import { validateTrigger } from './validate-trigger'; -import { ValidationRenderer } from './validation-renderer'; -import { ValidateResult } from './validate-result'; -import { ValidateInstruction } from './validate-instruction'; -import { ControllerValidateResult } from './controller-validate-result'; -import { PropertyAccessorParser, PropertyAccessor } from './property-accessor-parser'; -import { ValidateEvent } from './validate-event'; -/** - * Orchestrates validation. - * Manages a set of bindings, renderers and objects. - * Exposes the current list of validation results for binding purposes. - */ -export declare class ValidationController { - private validator; - private propertyParser; - static inject: (typeof PropertyAccessorParser | typeof Validator)[]; - private bindings; - private renderers; - /** - * Validation results that have been rendered by the controller. - */ - private results; - /** - * Validation errors that have been rendered by the controller. - */ - errors: ValidateResult[]; - /** - * Whether the controller is currently validating. - */ - validating: boolean; - private elements; - private objects; - /** - * The trigger that will invoke automatic validation of a property used in a binding. - */ - validateTrigger: validateTrigger; - private finishValidating; - private eventCallbacks; - constructor(validator: Validator, propertyParser: PropertyAccessorParser); - /** - * Subscribe to controller validate and reset events. These events occur when the - * controller's "validate"" and "reset" methods are called. - * @param callback The callback to be invoked when the controller validates or resets. - */ - subscribe(callback: (event: ValidateEvent) => void): { - dispose: () => void; - }; - /** - * Adds an object to the set of objects that should be validated when validate is called. - * @param object The object. - * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. - */ - addObject(object: any, rules?: any): void; - /** - * Removes an object from the set of objects that should be validated when validate is called. - * @param object The object. - */ - removeObject(object: any): void; - /** - * Adds and renders an error. - */ - addError(message: string, object: TObject, propertyName?: string | PropertyAccessor | null): ValidateResult; - /** - * Removes and unrenders an error. - */ - removeError(result: ValidateResult): void; - /** - * Adds a renderer. - * @param renderer The renderer. - */ - addRenderer(renderer: ValidationRenderer): void; - /** - * Removes a renderer. - * @param renderer The renderer. - */ - removeRenderer(renderer: ValidationRenderer): void; - /** - * Registers a binding with the controller. - * @param binding The binding instance. - * @param target The DOM element. - * @param rules (optional) rules associated with the binding. Validator implementation specific. - */ - registerBinding(binding: Binding, target: Element, rules?: any): void; - /** - * Unregisters a binding with the controller. - * @param binding The binding instance. - */ - unregisterBinding(binding: Binding): void; - /** - * Interprets the instruction and returns a predicate that will identify - * relevant results in the list of rendered validation results. - */ - private getInstructionPredicate(instruction?); - /** - * Validates and renders results. - * @param instruction Optional. Instructions on what to validate. If undefined, all - * objects and bindings will be validated. - */ - validate(instruction?: ValidateInstruction): Promise; - /** - * Resets any rendered validation results (unrenders). - * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results - * will be unrendered. - */ - reset(instruction?: ValidateInstruction): void; - /** - * Gets the elements associated with an object and propertyName (if any). - */ - private getAssociatedElements({object, propertyName}); - private processResultDelta(kind, oldResults, newResults); - /** - * Validates the property associated with a binding. - */ - validateBinding(binding: Binding): void; - /** - * Resets the results for a property associated with a binding. - */ - resetBinding(binding: Binding): void; - /** - * Changes the controller's validateTrigger. - * @param newTrigger The new validateTrigger - */ - changeTrigger(newTrigger: validateTrigger): void; - /** - * Revalidates the controller's current set of errors. - */ - revalidateErrors(): void; - private invokeCallbacks(instruction, result); -} diff --git a/dist/system/validation-controller.js b/dist/system/validation-controller.js deleted file mode 100644 index 50e30893..00000000 --- a/dist/system/validation-controller.js +++ /dev/null @@ -1,431 +0,0 @@ -System.register(["./validator", "./validate-trigger", "./property-info", "./validate-result", "./property-accessor-parser", "./validate-event"], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var validator_1, validate_trigger_1, property_info_1, validate_result_1, property_accessor_parser_1, validate_event_1, ValidationController; - return { - setters: [ - function (validator_1_1) { - validator_1 = validator_1_1; - }, - function (validate_trigger_1_1) { - validate_trigger_1 = validate_trigger_1_1; - }, - function (property_info_1_1) { - property_info_1 = property_info_1_1; - }, - function (validate_result_1_1) { - validate_result_1 = validate_result_1_1; - }, - function (property_accessor_parser_1_1) { - property_accessor_parser_1 = property_accessor_parser_1_1; - }, - function (validate_event_1_1) { - validate_event_1 = validate_event_1_1; - } - ], - execute: function () { - ValidationController = /** @class */ (function () { - function ValidationController(validator, propertyParser) { - this.validator = validator; - this.propertyParser = propertyParser; - // Registered bindings (via the validate binding behavior) - this.bindings = new Map(); - // Renderers that have been added to the controller instance. - this.renderers = []; - /** - * Validation results that have been rendered by the controller. - */ - this.results = []; - /** - * Validation errors that have been rendered by the controller. - */ - this.errors = []; - /** - * Whether the controller is currently validating. - */ - this.validating = false; - // Elements related to validation results that have been rendered. - this.elements = new Map(); - // Objects that have been added to the controller instance (entity-style validation). - this.objects = new Map(); - /** - * The trigger that will invoke automatic validation of a property used in a binding. - */ - this.validateTrigger = validate_trigger_1.validateTrigger.blur; - // Promise that resolves when validation has completed. - this.finishValidating = Promise.resolve(); - this.eventCallbacks = []; - } - /** - * Subscribe to controller validate and reset events. These events occur when the - * controller's "validate"" and "reset" methods are called. - * @param callback The callback to be invoked when the controller validates or resets. - */ - ValidationController.prototype.subscribe = function (callback) { - var _this = this; - this.eventCallbacks.push(callback); - return { - dispose: function () { - var index = _this.eventCallbacks.indexOf(callback); - if (index === -1) { - return; - } - _this.eventCallbacks.splice(index, 1); - } - }; - }; - /** - * Adds an object to the set of objects that should be validated when validate is called. - * @param object The object. - * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. - */ - ValidationController.prototype.addObject = function (object, rules) { - this.objects.set(object, rules); - }; - /** - * Removes an object from the set of objects that should be validated when validate is called. - * @param object The object. - */ - ValidationController.prototype.removeObject = function (object) { - this.objects.delete(object); - this.processResultDelta('reset', this.results.filter(function (result) { return result.object === object; }), []); - }; - /** - * Adds and renders an error. - */ - ValidationController.prototype.addError = function (message, object, propertyName) { - if (propertyName === void 0) { propertyName = null; } - var resolvedPropertyName; - if (propertyName === null) { - resolvedPropertyName = propertyName; - } - else { - resolvedPropertyName = this.propertyParser.parse(propertyName); - } - var result = new validate_result_1.ValidateResult({ __manuallyAdded__: true }, object, resolvedPropertyName, false, message); - this.processResultDelta('validate', [], [result]); - return result; - }; - /** - * Removes and unrenders an error. - */ - ValidationController.prototype.removeError = function (result) { - if (this.results.indexOf(result) !== -1) { - this.processResultDelta('reset', [result], []); - } - }; - /** - * Adds a renderer. - * @param renderer The renderer. - */ - ValidationController.prototype.addRenderer = function (renderer) { - var _this = this; - this.renderers.push(renderer); - renderer.render({ - kind: 'validate', - render: this.results.map(function (result) { return ({ result: result, elements: _this.elements.get(result) }); }), - unrender: [] - }); - }; - /** - * Removes a renderer. - * @param renderer The renderer. - */ - ValidationController.prototype.removeRenderer = function (renderer) { - var _this = this; - this.renderers.splice(this.renderers.indexOf(renderer), 1); - renderer.render({ - kind: 'reset', - render: [], - unrender: this.results.map(function (result) { return ({ result: result, elements: _this.elements.get(result) }); }) - }); - }; - /** - * Registers a binding with the controller. - * @param binding The binding instance. - * @param target The DOM element. - * @param rules (optional) rules associated with the binding. Validator implementation specific. - */ - ValidationController.prototype.registerBinding = function (binding, target, rules) { - this.bindings.set(binding, { target: target, rules: rules, propertyInfo: null }); - }; - /** - * Unregisters a binding with the controller. - * @param binding The binding instance. - */ - ValidationController.prototype.unregisterBinding = function (binding) { - this.resetBinding(binding); - this.bindings.delete(binding); - }; - /** - * Interprets the instruction and returns a predicate that will identify - * relevant results in the list of rendered validation results. - */ - ValidationController.prototype.getInstructionPredicate = function (instruction) { - var _this = this; - if (instruction) { - var object_1 = instruction.object, propertyName_1 = instruction.propertyName, rules_1 = instruction.rules; - var predicate_1; - if (instruction.propertyName) { - predicate_1 = function (x) { return x.object === object_1 && x.propertyName === propertyName_1; }; - } - else { - predicate_1 = function (x) { return x.object === object_1; }; - } - if (rules_1) { - return function (x) { return predicate_1(x) && _this.validator.ruleExists(rules_1, x.rule); }; - } - return predicate_1; - } - else { - return function () { return true; }; - } - }; - /** - * Validates and renders results. - * @param instruction Optional. Instructions on what to validate. If undefined, all - * objects and bindings will be validated. - */ - ValidationController.prototype.validate = function (instruction) { - var _this = this; - // Get a function that will process the validation instruction. - var execute; - if (instruction) { - // tslint:disable-next-line:prefer-const - var object_2 = instruction.object, propertyName_2 = instruction.propertyName, rules_2 = instruction.rules; - // if rules were not specified, check the object map. - rules_2 = rules_2 || this.objects.get(object_2); - // property specified? - if (instruction.propertyName === undefined) { - // validate the specified object. - execute = function () { return _this.validator.validateObject(object_2, rules_2); }; - } - else { - // validate the specified property. - execute = function () { return _this.validator.validateProperty(object_2, propertyName_2, rules_2); }; - } - } - else { - // validate all objects and bindings. - execute = function () { - var promises = []; - for (var _i = 0, _a = Array.from(_this.objects); _i < _a.length; _i++) { - var _b = _a[_i], object = _b[0], rules = _b[1]; - promises.push(_this.validator.validateObject(object, rules)); - } - for (var _c = 0, _d = Array.from(_this.bindings); _c < _d.length; _c++) { - var _e = _d[_c], binding = _e[0], rules = _e[1].rules; - var propertyInfo = property_info_1.getPropertyInfo(binding.sourceExpression, binding.source); - if (!propertyInfo || _this.objects.has(propertyInfo.object)) { - continue; - } - promises.push(_this.validator.validateProperty(propertyInfo.object, propertyInfo.propertyName, rules)); - } - return Promise.all(promises).then(function (resultSets) { return resultSets.reduce(function (a, b) { return a.concat(b); }, []); }); - }; - } - // Wait for any existing validation to finish, execute the instruction, render the results. - this.validating = true; - var returnPromise = this.finishValidating - .then(execute) - .then(function (newResults) { - var predicate = _this.getInstructionPredicate(instruction); - var oldResults = _this.results.filter(predicate); - _this.processResultDelta('validate', oldResults, newResults); - if (returnPromise === _this.finishValidating) { - _this.validating = false; - } - var result = { - instruction: instruction, - valid: newResults.find(function (x) { return !x.valid; }) === undefined, - results: newResults - }; - _this.invokeCallbacks(instruction, result); - return result; - }) - .catch(function (exception) { - // recover, to enable subsequent calls to validate() - _this.validating = false; - _this.finishValidating = Promise.resolve(); - return Promise.reject(exception); - }); - this.finishValidating = returnPromise; - return returnPromise; - }; - /** - * Resets any rendered validation results (unrenders). - * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results - * will be unrendered. - */ - ValidationController.prototype.reset = function (instruction) { - var predicate = this.getInstructionPredicate(instruction); - var oldResults = this.results.filter(predicate); - this.processResultDelta('reset', oldResults, []); - this.invokeCallbacks(instruction, null); - }; - /** - * Gets the elements associated with an object and propertyName (if any). - */ - ValidationController.prototype.getAssociatedElements = function (_a) { - var object = _a.object, propertyName = _a.propertyName; - var elements = []; - for (var _i = 0, _b = Array.from(this.bindings); _i < _b.length; _i++) { - var _c = _b[_i], binding = _c[0], target = _c[1].target; - var propertyInfo = property_info_1.getPropertyInfo(binding.sourceExpression, binding.source); - if (propertyInfo && propertyInfo.object === object && propertyInfo.propertyName === propertyName) { - elements.push(target); - } - } - return elements; - }; - ValidationController.prototype.processResultDelta = function (kind, oldResults, newResults) { - // prepare the instruction. - var instruction = { - kind: kind, - render: [], - unrender: [] - }; - // create a shallow copy of newResults so we can mutate it without causing side-effects. - newResults = newResults.slice(0); - var _loop_1 = function (oldResult) { - // get the elements associated with the old result. - var elements = this_1.elements.get(oldResult); - // remove the old result from the element map. - this_1.elements.delete(oldResult); - // create the unrender instruction. - instruction.unrender.push({ result: oldResult, elements: elements }); - // determine if there's a corresponding new result for the old result we are unrendering. - var newResultIndex = newResults.findIndex(function (x) { return x.rule === oldResult.rule && x.object === oldResult.object && x.propertyName === oldResult.propertyName; }); - if (newResultIndex === -1) { - // no corresponding new result... simple remove. - this_1.results.splice(this_1.results.indexOf(oldResult), 1); - if (!oldResult.valid) { - this_1.errors.splice(this_1.errors.indexOf(oldResult), 1); - } - } - else { - // there is a corresponding new result... - var newResult = newResults.splice(newResultIndex, 1)[0]; - // get the elements that are associated with the new result. - var elements_1 = this_1.getAssociatedElements(newResult); - this_1.elements.set(newResult, elements_1); - // create a render instruction for the new result. - instruction.render.push({ result: newResult, elements: elements_1 }); - // do an in-place replacement of the old result with the new result. - // this ensures any repeats bound to this.results will not thrash. - this_1.results.splice(this_1.results.indexOf(oldResult), 1, newResult); - if (!oldResult.valid && newResult.valid) { - this_1.errors.splice(this_1.errors.indexOf(oldResult), 1); - } - else if (!oldResult.valid && !newResult.valid) { - this_1.errors.splice(this_1.errors.indexOf(oldResult), 1, newResult); - } - else if (!newResult.valid) { - this_1.errors.push(newResult); - } - } - }; - var this_1 = this; - // create unrender instructions from the old results. - for (var _i = 0, oldResults_1 = oldResults; _i < oldResults_1.length; _i++) { - var oldResult = oldResults_1[_i]; - _loop_1(oldResult); - } - // create render instructions from the remaining new results. - for (var _a = 0, newResults_1 = newResults; _a < newResults_1.length; _a++) { - var result = newResults_1[_a]; - var elements = this.getAssociatedElements(result); - instruction.render.push({ result: result, elements: elements }); - this.elements.set(result, elements); - this.results.push(result); - if (!result.valid) { - this.errors.push(result); - } - } - // render. - for (var _b = 0, _c = this.renderers; _b < _c.length; _b++) { - var renderer = _c[_b]; - renderer.render(instruction); - } - }; - /** - * Validates the property associated with a binding. - */ - ValidationController.prototype.validateBinding = function (binding) { - if (!binding.isBound) { - return; - } - var propertyInfo = property_info_1.getPropertyInfo(binding.sourceExpression, binding.source); - var rules; - var registeredBinding = this.bindings.get(binding); - if (registeredBinding) { - rules = registeredBinding.rules; - registeredBinding.propertyInfo = propertyInfo; - } - if (!propertyInfo) { - return; - } - var object = propertyInfo.object, propertyName = propertyInfo.propertyName; - this.validate({ object: object, propertyName: propertyName, rules: rules }); - }; - /** - * Resets the results for a property associated with a binding. - */ - ValidationController.prototype.resetBinding = function (binding) { - var registeredBinding = this.bindings.get(binding); - var propertyInfo = property_info_1.getPropertyInfo(binding.sourceExpression, binding.source); - if (!propertyInfo && registeredBinding) { - propertyInfo = registeredBinding.propertyInfo; - } - if (registeredBinding) { - registeredBinding.propertyInfo = null; - } - if (!propertyInfo) { - return; - } - var object = propertyInfo.object, propertyName = propertyInfo.propertyName; - this.reset({ object: object, propertyName: propertyName }); - }; - /** - * Changes the controller's validateTrigger. - * @param newTrigger The new validateTrigger - */ - ValidationController.prototype.changeTrigger = function (newTrigger) { - this.validateTrigger = newTrigger; - var bindings = Array.from(this.bindings.keys()); - for (var _i = 0, bindings_1 = bindings; _i < bindings_1.length; _i++) { - var binding = bindings_1[_i]; - var source = binding.source; - binding.unbind(); - binding.bind(source); - } - }; - /** - * Revalidates the controller's current set of errors. - */ - ValidationController.prototype.revalidateErrors = function () { - for (var _i = 0, _a = this.errors; _i < _a.length; _i++) { - var _b = _a[_i], object = _b.object, propertyName = _b.propertyName, rule = _b.rule; - if (rule.__manuallyAdded__) { - continue; - } - var rules = [[rule]]; - this.validate({ object: object, propertyName: propertyName, rules: rules }); - } - }; - ValidationController.prototype.invokeCallbacks = function (instruction, result) { - if (this.eventCallbacks.length === 0) { - return; - } - var event = new validate_event_1.ValidateEvent(result ? 'validate' : 'reset', this.errors, this.results, instruction || null, result); - for (var i = 0; i < this.eventCallbacks.length; i++) { - this.eventCallbacks[i](event); - } - }; - ValidationController.inject = [validator_1.Validator, property_accessor_parser_1.PropertyAccessorParser]; - return ValidationController; - }()); - exports_1("ValidationController", ValidationController); - } - }; -}); diff --git a/dist/system/validation-errors-custom-attribute.d.ts b/dist/system/validation-errors-custom-attribute.d.ts deleted file mode 100644 index 056e08ea..00000000 --- a/dist/system/validation-errors-custom-attribute.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Lazy } from 'aurelia-dependency-injection'; -import { ValidationController } from './validation-controller'; -import { ValidateResult } from './validate-result'; -import { ValidationRenderer, RenderInstruction } from './validation-renderer'; -export interface RenderedError { - error: ValidateResult; - targets: Element[]; -} -export declare class ValidationErrorsCustomAttribute implements ValidationRenderer { - private boundaryElement; - private controllerAccessor; - static inject(): ({ - new (): Element; - prototype: Element; - } | Lazy)[]; - controller: ValidationController | null; - errors: RenderedError[]; - private errorsInternal; - constructor(boundaryElement: Element, controllerAccessor: () => ValidationController); - sort(): void; - interestingElements(elements: Element[]): Element[]; - render(instruction: RenderInstruction): void; - bind(): void; - unbind(): void; -} diff --git a/dist/system/validation-errors-custom-attribute.js b/dist/system/validation-errors-custom-attribute.js deleted file mode 100644 index 322398cc..00000000 --- a/dist/system/validation-errors-custom-attribute.js +++ /dev/null @@ -1,103 +0,0 @@ -System.register(["aurelia-binding", "aurelia-dependency-injection", "aurelia-templating", "./validation-controller", "aurelia-pal"], function (exports_1, context_1) { - "use strict"; - var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; - }; - var __moduleName = context_1 && context_1.id; - var aurelia_binding_1, aurelia_dependency_injection_1, aurelia_templating_1, validation_controller_1, aurelia_pal_1, ValidationErrorsCustomAttribute; - return { - setters: [ - function (aurelia_binding_1_1) { - aurelia_binding_1 = aurelia_binding_1_1; - }, - function (aurelia_dependency_injection_1_1) { - aurelia_dependency_injection_1 = aurelia_dependency_injection_1_1; - }, - function (aurelia_templating_1_1) { - aurelia_templating_1 = aurelia_templating_1_1; - }, - function (validation_controller_1_1) { - validation_controller_1 = validation_controller_1_1; - }, - function (aurelia_pal_1_1) { - aurelia_pal_1 = aurelia_pal_1_1; - } - ], - execute: function () { - ValidationErrorsCustomAttribute = /** @class */ (function () { - function ValidationErrorsCustomAttribute(boundaryElement, controllerAccessor) { - this.boundaryElement = boundaryElement; - this.controllerAccessor = controllerAccessor; - this.controller = null; - this.errors = []; - this.errorsInternal = []; - } - ValidationErrorsCustomAttribute.inject = function () { return [aurelia_pal_1.DOM.Element, aurelia_dependency_injection_1.Lazy.of(validation_controller_1.ValidationController)]; }; - ValidationErrorsCustomAttribute.prototype.sort = function () { - this.errorsInternal.sort(function (a, b) { - if (a.targets[0] === b.targets[0]) { - return 0; - } - // tslint:disable-next-line:no-bitwise - return a.targets[0].compareDocumentPosition(b.targets[0]) & 2 ? 1 : -1; - }); - }; - ValidationErrorsCustomAttribute.prototype.interestingElements = function (elements) { - var _this = this; - return elements.filter(function (e) { return _this.boundaryElement.contains(e); }); - }; - ValidationErrorsCustomAttribute.prototype.render = function (instruction) { - var _loop_1 = function (result) { - var index = this_1.errorsInternal.findIndex(function (x) { return x.error === result; }); - if (index !== -1) { - this_1.errorsInternal.splice(index, 1); - } - }; - var this_1 = this; - for (var _i = 0, _a = instruction.unrender; _i < _a.length; _i++) { - var result = _a[_i].result; - _loop_1(result); - } - for (var _b = 0, _c = instruction.render; _b < _c.length; _b++) { - var _d = _c[_b], result = _d.result, elements = _d.elements; - if (result.valid) { - continue; - } - var targets = this.interestingElements(elements); - if (targets.length) { - this.errorsInternal.push({ error: result, targets: targets }); - } - } - this.sort(); - this.errors = this.errorsInternal; - }; - ValidationErrorsCustomAttribute.prototype.bind = function () { - if (!this.controller) { - this.controller = this.controllerAccessor(); - } - // this will call render() with the side-effect of updating this.errors - this.controller.addRenderer(this); - }; - ValidationErrorsCustomAttribute.prototype.unbind = function () { - if (this.controller) { - this.controller.removeRenderer(this); - } - }; - __decorate([ - aurelia_templating_1.bindable({ defaultBindingMode: aurelia_binding_1.bindingMode.oneWay }) - ], ValidationErrorsCustomAttribute.prototype, "controller", void 0); - __decorate([ - aurelia_templating_1.bindable({ primaryProperty: true, defaultBindingMode: aurelia_binding_1.bindingMode.twoWay }) - ], ValidationErrorsCustomAttribute.prototype, "errors", void 0); - ValidationErrorsCustomAttribute = __decorate([ - aurelia_templating_1.customAttribute('validation-errors') - ], ValidationErrorsCustomAttribute); - return ValidationErrorsCustomAttribute; - }()); - exports_1("ValidationErrorsCustomAttribute", ValidationErrorsCustomAttribute); - } - }; -}); diff --git a/dist/system/validation-renderer-custom-attribute.d.ts b/dist/system/validation-renderer-custom-attribute.d.ts deleted file mode 100644 index 9f48614e..00000000 --- a/dist/system/validation-renderer-custom-attribute.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export declare class ValidationRendererCustomAttribute { - private container; - private controller; - private value; - private renderer; - created(view: any): void; - bind(): void; - unbind(): void; -} diff --git a/dist/system/validation-renderer-custom-attribute.js b/dist/system/validation-renderer-custom-attribute.js deleted file mode 100644 index 7eba5664..00000000 --- a/dist/system/validation-renderer-custom-attribute.js +++ /dev/null @@ -1,33 +0,0 @@ -System.register(["./validation-controller"], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var validation_controller_1, ValidationRendererCustomAttribute; - return { - setters: [ - function (validation_controller_1_1) { - validation_controller_1 = validation_controller_1_1; - } - ], - execute: function () { - ValidationRendererCustomAttribute = /** @class */ (function () { - function ValidationRendererCustomAttribute() { - } - ValidationRendererCustomAttribute.prototype.created = function (view) { - this.container = view.container; - }; - ValidationRendererCustomAttribute.prototype.bind = function () { - this.controller = this.container.get(validation_controller_1.ValidationController); - this.renderer = this.container.get(this.value); - this.controller.addRenderer(this.renderer); - }; - ValidationRendererCustomAttribute.prototype.unbind = function () { - this.controller.removeRenderer(this.renderer); - this.controller = null; - this.renderer = null; - }; - return ValidationRendererCustomAttribute; - }()); - exports_1("ValidationRendererCustomAttribute", ValidationRendererCustomAttribute); - } - }; -}); diff --git a/dist/system/validation-renderer.d.ts b/dist/system/validation-renderer.d.ts deleted file mode 100644 index eb430d9d..00000000 --- a/dist/system/validation-renderer.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { ValidateResult } from './validate-result'; -/** - * A result to render (or unrender) and the associated elements (if any) - */ -export interface ResultInstruction { - /** - * The validation result. - */ - result: ValidateResult; - /** - * The associated elements (if any). - */ - elements: Element[]; -} -/** - * Defines which validation results to render and which validation results to unrender. - */ -export interface RenderInstruction { - /** - * The "kind" of render instruction. Either 'validate' or 'reset'. - */ - kind: 'validate' | 'reset'; - /** - * The results to render. - */ - render: ResultInstruction[]; - /** - * The results to unrender. - */ - unrender: ResultInstruction[]; -} -/** - * Renders validation results. - */ -export interface ValidationRenderer { - /** - * Render the validation results. - * @param instruction The render instruction. Defines which results to render and which - * results to unrender. - */ - render(instruction: RenderInstruction): void; -} diff --git a/dist/system/validation-renderer.js b/dist/system/validation-renderer.js deleted file mode 100644 index 083dc444..00000000 --- a/dist/system/validation-renderer.js +++ /dev/null @@ -1,9 +0,0 @@ -System.register([], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - return { - setters: [], - execute: function () { - } - }; -}); diff --git a/dist/system/validator.d.ts b/dist/system/validator.d.ts deleted file mode 100644 index 82c045e8..00000000 --- a/dist/system/validator.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ValidateResult } from './validate-result'; -/** - * Validates objects and properties. - */ -export declare abstract class Validator { - /** - * Validates the specified property. - * @param object The object to validate. - * @param propertyName The name of the property to validate. - * @param rules Optional. If unspecified, the implementation should lookup the rules for the - * specified object. This may not be possible for all implementations of this interface. - */ - abstract validateProperty(object: any, propertyName: string, rules?: any): Promise; - /** - * Validates all rules for specified object and it's properties. - * @param object The object to validate. - * @param rules Optional. If unspecified, the implementation should lookup the rules for the - * specified object. This may not be possible for all implementations of this interface. - */ - abstract validateObject(object: any, rules?: any): Promise; - /** - * Determines whether a rule exists in a set of rules. - * @param rules The rules to search. - * @parem rule The rule to find. - */ - abstract ruleExists(rules: any, rule: any): boolean; -} diff --git a/dist/system/validator.js b/dist/system/validator.js deleted file mode 100644 index 5945d52d..00000000 --- a/dist/system/validator.js +++ /dev/null @@ -1,19 +0,0 @@ -System.register([], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var Validator; - return { - setters: [], - execute: function () { - /** - * Validates objects and properties. - */ - Validator = /** @class */ (function () { - function Validator() { - } - return Validator; - }()); - exports_1("Validator", Validator); - } - }; -}); diff --git a/dist/amd/aurelia-validation.d.ts b/dist/types/aurelia-validation.d.ts similarity index 93% rename from dist/amd/aurelia-validation.d.ts rename to dist/types/aurelia-validation.d.ts index d744ccfb..4c8139dd 100644 --- a/dist/amd/aurelia-validation.d.ts +++ b/dist/types/aurelia-validation.d.ts @@ -1,46 +1,46 @@ -export * from './controller-validate-result'; -export * from './get-target-dom-element'; -export * from './property-info'; -export * from './property-accessor-parser'; -export * from './validate-binding-behavior'; -export * from './validate-event'; -export * from './validate-instruction'; -export * from './validate-result'; -export * from './validate-trigger'; -export * from './validation-controller'; -export * from './validation-controller-factory'; -export * from './validation-errors-custom-attribute'; -export * from './validation-renderer-custom-attribute'; -export * from './validation-renderer'; -export * from './validator'; -export * from './implementation/rule'; -export * from './implementation/rules'; -export * from './implementation/standard-validator'; -export * from './implementation/validation-messages'; -export * from './implementation/validation-message-parser'; -export * from './implementation/validation-rules'; -import { Container } from 'aurelia-dependency-injection'; -import { Validator } from './validator'; -/** - * Aurelia Validation Configuration API - */ -export declare class AureliaValidationConfiguration { - private validatorType; - /** - * Use a custom Validator implementation. - */ - customValidator(type: { - new (...args: any[]): Validator; - }): void; - /** - * Applies the configuration. - */ - apply(container: Container): void; -} -/** - * Configures the plugin. - */ -export declare function configure(frameworkConfig: { - container: Container; - globalResources?: (...resources: string[]) => any; -}, callback?: (config: AureliaValidationConfiguration) => void): void; +export * from './controller-validate-result'; +export * from './get-target-dom-element'; +export * from './property-info'; +export * from './property-accessor-parser'; +export * from './validate-binding-behavior'; +export * from './validate-event'; +export * from './validate-instruction'; +export * from './validate-result'; +export * from './validate-trigger'; +export * from './validation-controller'; +export * from './validation-controller-factory'; +export * from './validation-errors-custom-attribute'; +export * from './validation-renderer-custom-attribute'; +export * from './validation-renderer'; +export * from './validator'; +export * from './implementation/rule'; +export * from './implementation/rules'; +export * from './implementation/standard-validator'; +export * from './implementation/validation-messages'; +export * from './implementation/validation-message-parser'; +export * from './implementation/validation-rules'; +import { Container } from 'aurelia-dependency-injection'; +import { Validator } from './validator'; +/** + * Aurelia Validation Configuration API + */ +export declare class AureliaValidationConfiguration { + private validatorType; + /** + * Use a custom Validator implementation. + */ + customValidator(type: { + new (...args: any[]): Validator; + }): void; + /** + * Applies the configuration. + */ + apply(container: Container): void; +} +/** + * Configures the plugin. + */ +export declare function configure(frameworkConfig: { + container: Container; + globalResources?: (...resources: Function[]) => any; +}, callback?: (config: AureliaValidationConfiguration) => void): void; diff --git a/dist/es2015/controller-validate-result.d.ts b/dist/types/controller-validate-result.d.ts similarity index 96% rename from dist/es2015/controller-validate-result.d.ts rename to dist/types/controller-validate-result.d.ts index 5f814ed0..08049098 100644 --- a/dist/es2015/controller-validate-result.d.ts +++ b/dist/types/controller-validate-result.d.ts @@ -1,19 +1,19 @@ -import { ValidateResult } from './validate-result'; -import { ValidateInstruction } from './validate-instruction'; -/** - * The result of a call to the validation controller's validate method. - */ -export interface ControllerValidateResult { - /** - * Whether validation passed. - */ - valid: boolean; - /** - * The validation result of every rule that was evaluated. - */ - results: ValidateResult[]; - /** - * The instruction passed to the controller's validate method. - */ - instruction?: ValidateInstruction; -} +import { ValidateResult } from './validate-result'; +import { ValidateInstruction } from './validate-instruction'; +/** + * The result of a call to the validation controller's validate method. + */ +export interface ControllerValidateResult { + /** + * Whether validation passed. + */ + valid: boolean; + /** + * The validation result of every rule that was evaluated. + */ + results: ValidateResult[]; + /** + * The instruction passed to the controller's validate method. + */ + instruction?: ValidateInstruction; +} diff --git a/dist/es2015/get-target-dom-element.d.ts b/dist/types/get-target-dom-element.d.ts similarity index 98% rename from dist/es2015/get-target-dom-element.d.ts rename to dist/types/get-target-dom-element.d.ts index 314fc952..38409e45 100644 --- a/dist/es2015/get-target-dom-element.d.ts +++ b/dist/types/get-target-dom-element.d.ts @@ -1,7 +1,7 @@ -/** - * Gets the DOM element associated with the data-binding. Most of the time it's - * the binding.target but sometimes binding.target is an aurelia custom element, - * or custom attribute which is a javascript "class" instance, so we need to use - * the controller's container to retrieve the actual DOM element. - */ -export declare function getTargetDOMElement(binding: any, view: any): Element; +/** + * Gets the DOM element associated with the data-binding. Most of the time it's + * the binding.target but sometimes binding.target is an aurelia custom element, + * or custom attribute which is a javascript "class" instance, so we need to use + * the controller's container to retrieve the actual DOM element. + */ +export declare function getTargetDOMElement(binding: any, view: any): Element; diff --git a/dist/commonjs/implementation/expression-visitor.d.ts b/dist/types/implementation/expression-visitor.d.ts similarity index 96% rename from dist/commonjs/implementation/expression-visitor.d.ts rename to dist/types/implementation/expression-visitor.d.ts index 47769fae..9a6f3d98 100644 --- a/dist/commonjs/implementation/expression-visitor.d.ts +++ b/dist/types/implementation/expression-visitor.d.ts @@ -1,33 +1,33 @@ -import { ValueConverter, Conditional, AccessMember, AccessKeyed, CallMember, BindingBehavior, Binary } from 'aurelia-binding'; -export declare type Chain = any; -export declare type Assign = any; -export declare type AccessThis = any; -export declare type AccessScope = any; -export declare type CallScope = any; -export declare type CallFunction = any; -export declare type PrefixNot = any; -export declare type LiteralPrimitive = any; -export declare type LiteralArray = any; -export declare type LiteralObject = any; -export declare type LiteralString = any; -export declare class ExpressionVisitor { - visitChain(chain: Chain): void; - visitBindingBehavior(behavior: BindingBehavior): void; - visitValueConverter(converter: ValueConverter): void; - visitAssign(assign: Assign): void; - visitConditional(conditional: Conditional): void; - visitAccessThis(access: AccessThis): void; - visitAccessScope(access: AccessScope): void; - visitAccessMember(access: AccessMember): void; - visitAccessKeyed(access: AccessKeyed): void; - visitCallScope(call: CallScope): void; - visitCallFunction(call: CallFunction): void; - visitCallMember(call: CallMember): void; - visitPrefix(prefix: PrefixNot): void; - visitBinary(binary: Binary): void; - visitLiteralPrimitive(literal: LiteralPrimitive): void; - visitLiteralArray(literal: LiteralArray): void; - visitLiteralObject(literal: LiteralObject): void; - visitLiteralString(literal: LiteralString): void; - private visitArgs(args); -} +import { ValueConverter, Conditional, AccessMember, AccessKeyed, CallMember, BindingBehavior, Binary } from 'aurelia-binding'; +export declare type Chain = any; +export declare type Assign = any; +export declare type AccessThis = any; +export declare type AccessScope = any; +export declare type CallScope = any; +export declare type CallFunction = any; +export declare type PrefixNot = any; +export declare type LiteralPrimitive = any; +export declare type LiteralArray = any; +export declare type LiteralObject = any; +export declare type LiteralString = any; +export declare class ExpressionVisitor { + visitChain(chain: Chain): void; + visitBindingBehavior(behavior: BindingBehavior): void; + visitValueConverter(converter: ValueConverter): void; + visitAssign(assign: Assign): void; + visitConditional(conditional: Conditional): void; + visitAccessThis(access: AccessThis): void; + visitAccessScope(access: AccessScope): void; + visitAccessMember(access: AccessMember): void; + visitAccessKeyed(access: AccessKeyed): void; + visitCallScope(call: CallScope): void; + visitCallFunction(call: CallFunction): void; + visitCallMember(call: CallMember): void; + visitPrefix(prefix: PrefixNot): void; + visitBinary(binary: Binary): void; + visitLiteralPrimitive(literal: LiteralPrimitive): void; + visitLiteralArray(literal: LiteralArray): void; + visitLiteralObject(literal: LiteralObject): void; + visitLiteralString(literal: LiteralString): void; + private visitArgs; +} diff --git a/dist/es2015/implementation/rule.d.ts b/dist/types/implementation/rule.d.ts similarity index 96% rename from dist/es2015/implementation/rule.d.ts rename to dist/types/implementation/rule.d.ts index ffbb7b21..6812a750 100644 --- a/dist/es2015/implementation/rule.d.ts +++ b/dist/types/implementation/rule.d.ts @@ -1,28 +1,28 @@ -import { Expression } from 'aurelia-binding'; -export declare type ValidationDisplayNameAccessor = () => string; -/** - * Information related to a property that is the subject of validation. - */ -export interface RuleProperty { - /** - * The property name. null indicates the rule targets the object itself. - */ - name: string | number | null; - /** - * The displayName of the property (or object). - */ - displayName: string | ValidationDisplayNameAccessor | null; -} -/** - * A rule definition. Associations a rule with a property or object. - */ -export interface Rule { - property: RuleProperty; - condition: (value: TValue, object?: TObject) => boolean | Promise; - config: object; - when: ((object: TObject) => boolean) | null; - messageKey: string; - message: Expression | null; - sequence: number; - tag?: string; -} +import { Expression } from 'aurelia-binding'; +export declare type ValidationDisplayNameAccessor = () => string; +/** + * Information related to a property that is the subject of validation. + */ +export interface RuleProperty { + /** + * The property name. null indicates the rule targets the object itself. + */ + name: string | number | null; + /** + * The displayName of the property (or object). + */ + displayName: string | ValidationDisplayNameAccessor | null; +} +/** + * A rule definition. Associations a rule with a property or object. + */ +export interface Rule { + property: RuleProperty; + condition: (value: TValue, object?: TObject) => boolean | Promise; + config: object; + when: ((object: TObject) => boolean) | null; + messageKey: string; + message: Expression | null; + sequence: number; + tag?: string; +} diff --git a/dist/es2015/implementation/rules.d.ts b/dist/types/implementation/rules.d.ts similarity index 96% rename from dist/es2015/implementation/rules.d.ts rename to dist/types/implementation/rules.d.ts index 30947f6f..6a87738d 100644 --- a/dist/es2015/implementation/rules.d.ts +++ b/dist/types/implementation/rules.d.ts @@ -1,22 +1,22 @@ -import { Rule } from './rule'; -/** - * Sets, unsets and retrieves rules on an object or constructor function. - */ -export declare class Rules { - /** - * The name of the property that stores the rules. - */ - private static key; - /** - * Applies the rules to a target. - */ - static set(target: any, rules: Rule[][]): void; - /** - * Removes rules from a target. - */ - static unset(target: any): void; - /** - * Retrieves the target's rules. - */ - static get(target: any): Rule[][] | null; -} +import { Rule } from './rule'; +/** + * Sets, unsets and retrieves rules on an object or constructor function. + */ +export declare class Rules { + /** + * The name of the property that stores the rules. + */ + private static key; + /** + * Applies the rules to a target. + */ + static set(target: any, rules: Rule[][]): void; + /** + * Removes rules from a target. + */ + static unset(target: any): void; + /** + * Retrieves the target's rules. + */ + static get(target: any): Rule[][] | null; +} diff --git a/dist/es2015/implementation/standard-validator.d.ts b/dist/types/implementation/standard-validator.d.ts similarity index 85% rename from dist/es2015/implementation/standard-validator.d.ts rename to dist/types/implementation/standard-validator.d.ts index c47a7d2e..04ce047a 100644 --- a/dist/es2015/implementation/standard-validator.d.ts +++ b/dist/types/implementation/standard-validator.d.ts @@ -1,40 +1,40 @@ -import { ViewResources } from 'aurelia-templating'; -import { Validator } from '../validator'; -import { ValidateResult } from '../validate-result'; -import { Rule } from './rule'; -import { ValidationMessageProvider } from './validation-messages'; -/** - * Validates. - * Responsible for validating objects and properties. - */ -export declare class StandardValidator extends Validator { - static inject: (typeof ViewResources | typeof ValidationMessageProvider)[]; - private messageProvider; - private lookupFunctions; - private getDisplayName; - constructor(messageProvider: ValidationMessageProvider, resources: ViewResources); - /** - * Validates the specified property. - * @param object The object to validate. - * @param propertyName The name of the property to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - validateProperty(object: any, propertyName: string | number, rules?: any): Promise; - /** - * Validates all rules for specified object and it's properties. - * @param object The object to validate. - * @param rules Optional. If unspecified, the rules will be looked up using the metadata - * for the object created by ValidationRules....on(class/object) - */ - validateObject(object: any, rules?: any): Promise; - /** - * Determines whether a rule exists in a set of rules. - * @param rules The rules to search. - * @parem rule The rule to find. - */ - ruleExists(rules: Rule[][], rule: Rule): boolean; - private getMessage(rule, object, value); - private validateRuleSequence(object, propertyName, ruleSequence, sequence, results); - private validate(object, propertyName, rules); -} +import { ViewResources } from 'aurelia-templating'; +import { Validator } from '../validator'; +import { ValidateResult } from '../validate-result'; +import { Rule } from './rule'; +import { ValidationMessageProvider } from './validation-messages'; +/** + * Validates. + * Responsible for validating objects and properties. + */ +export declare class StandardValidator extends Validator { + static inject: (typeof ValidationMessageProvider | typeof ViewResources)[]; + private messageProvider; + private lookupFunctions; + private getDisplayName; + constructor(messageProvider: ValidationMessageProvider, resources: ViewResources); + /** + * Validates the specified property. + * @param object The object to validate. + * @param propertyName The name of the property to validate. + * @param rules Optional. If unspecified, the rules will be looked up using the metadata + * for the object created by ValidationRules....on(class/object) + */ + validateProperty(object: any, propertyName: string | number, rules?: any): Promise; + /** + * Validates all rules for specified object and it's properties. + * @param object The object to validate. + * @param rules Optional. If unspecified, the rules will be looked up using the metadata + * for the object created by ValidationRules....on(class/object) + */ + validateObject(object: any, rules?: any): Promise; + /** + * Determines whether a rule exists in a set of rules. + * @param rules The rules to search. + * @parem rule The rule to find. + */ + ruleExists(rules: Rule[][], rule: Rule): boolean; + private getMessage; + private validateRuleSequence; + private validate; +} diff --git a/dist/amd/implementation/validation-message-parser.d.ts b/dist/types/implementation/validation-message-parser.d.ts similarity index 94% rename from dist/amd/implementation/validation-message-parser.d.ts rename to dist/types/implementation/validation-message-parser.d.ts index 39d288c0..35b9fe66 100644 --- a/dist/amd/implementation/validation-message-parser.d.ts +++ b/dist/types/implementation/validation-message-parser.d.ts @@ -1,20 +1,20 @@ -import { Expression, AccessScope } from 'aurelia-binding'; -import { BindingLanguage } from 'aurelia-templating'; -import { ExpressionVisitor } from './expression-visitor'; -export declare class ValidationMessageParser { - private bindinqLanguage; - static inject: (typeof BindingLanguage)[]; - private emptyStringExpression; - private nullExpression; - private undefinedExpression; - private cache; - constructor(bindinqLanguage: BindingLanguage); - parse(message: string): Expression; - private coalesce(part); -} -export declare class MessageExpressionValidator extends ExpressionVisitor { - private originalMessage; - static validate(expression: Expression, originalMessage: string): void; - constructor(originalMessage: string); - visitAccessScope(access: AccessScope): void; -} +import { Expression, AccessScope } from 'aurelia-binding'; +import { BindingLanguage } from 'aurelia-templating'; +import { ExpressionVisitor } from './expression-visitor'; +export declare class ValidationMessageParser { + private bindinqLanguage; + static inject: (typeof BindingLanguage)[]; + private emptyStringExpression; + private nullExpression; + private undefinedExpression; + private cache; + constructor(bindinqLanguage: BindingLanguage); + parse(message: string): Expression; + private coalesce; +} +export declare class MessageExpressionValidator extends ExpressionVisitor { + private originalMessage; + static validate(expression: Expression, originalMessage: string): void; + constructor(originalMessage: string); + visitAccessScope(access: AccessScope): void; +} diff --git a/dist/commonjs/implementation/validation-messages.d.ts b/dist/types/implementation/validation-messages.d.ts similarity index 97% rename from dist/commonjs/implementation/validation-messages.d.ts rename to dist/types/implementation/validation-messages.d.ts index eb4cb9d4..1e3ae3b0 100644 --- a/dist/commonjs/implementation/validation-messages.d.ts +++ b/dist/types/implementation/validation-messages.d.ts @@ -1,29 +1,29 @@ -import { Expression } from 'aurelia-binding'; -import { ValidationMessageParser } from './validation-message-parser'; -export interface ValidationMessages { - [key: string]: string; -} -/** - * Dictionary of validation messages. [messageKey]: messageExpression - */ -export declare const validationMessages: ValidationMessages; -/** - * Retrieves validation messages and property display names. - */ -export declare class ValidationMessageProvider { - parser: ValidationMessageParser; - static inject: (typeof ValidationMessageParser)[]; - constructor(parser: ValidationMessageParser); - /** - * Returns a message binding expression that corresponds to the key. - * @param key The message key. - */ - getMessage(key: string): Expression; - /** - * Formulates a property display name using the property name and the configured - * displayName (if provided). - * Override this with your own custom logic. - * @param propertyName The property name. - */ - getDisplayName(propertyName: string | number, displayName?: string | null | (() => string)): string; -} +import { Expression } from 'aurelia-binding'; +import { ValidationMessageParser } from './validation-message-parser'; +export interface ValidationMessages { + [key: string]: string; +} +/** + * Dictionary of validation messages. [messageKey]: messageExpression + */ +export declare const validationMessages: ValidationMessages; +/** + * Retrieves validation messages and property display names. + */ +export declare class ValidationMessageProvider { + parser: ValidationMessageParser; + static inject: (typeof ValidationMessageParser)[]; + constructor(parser: ValidationMessageParser); + /** + * Returns a message binding expression that corresponds to the key. + * @param key The message key. + */ + getMessage(key: string): Expression; + /** + * Formulates a property display name using the property name and the configured + * displayName (if provided). + * Override this with your own custom logic. + * @param propertyName The property name. + */ + getDisplayName(propertyName: string | number, displayName?: string | null | (() => string)): string; +} diff --git a/dist/commonjs/implementation/validation-rules.d.ts b/dist/types/implementation/validation-rules.d.ts similarity index 97% rename from dist/commonjs/implementation/validation-rules.d.ts rename to dist/types/implementation/validation-rules.d.ts index 995b2a8a..63926a78 100644 --- a/dist/commonjs/implementation/validation-rules.d.ts +++ b/dist/types/implementation/validation-rules.d.ts @@ -1,262 +1,262 @@ -import { Rule, RuleProperty, ValidationDisplayNameAccessor } from './rule'; -import { ValidationMessageParser } from './validation-message-parser'; -import { PropertyAccessorParser, PropertyAccessor } from '../property-accessor-parser'; -/** - * Part of the fluent rule API. Enables customizing property rules. - */ -export declare class FluentRuleCustomizer { - private fluentEnsure; - private fluentRules; - private parsers; - private rule; - constructor(property: RuleProperty, condition: (value: TValue, object?: TObject) => boolean | Promise, config: object | undefined, fluentEnsure: FluentEnsure, fluentRules: FluentRules, parsers: Parsers); - /** - * Validate subsequent rules after previously declared rules have - * been validated successfully. Use to postpone validation of costly - * rules until less expensive rules pass validation. - */ - then(): this; - /** - * Specifies the key to use when looking up the rule's validation message. - */ - withMessageKey(key: string): this; - /** - * Specifies rule's validation message. - */ - withMessage(message: string): this; - /** - * Specifies a condition that must be met before attempting to validate the rule. - * @param condition A function that accepts the object as a parameter and returns true - * or false whether the rule should be evaluated. - */ - when(condition: (object: TObject) => boolean): this; - /** - * Tags the rule instance, enabling the rule to be found easily - * using ValidationRules.taggedRules(rules, tag) - */ - tag(tag: string): this; - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - ensure(subject: string | ((model: TObject) => TValue2)): FluentRules; - /** - * Targets an object with validation rules. - */ - ensureObject(): FluentRules; - /** - * Rules that have been defined using the fluent API. - */ - readonly rules: Rule[][]; - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - on(target: any): FluentEnsure; - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - satisfies(condition: (value: TValue, object: TObject) => boolean | Promise, config?: object): FluentRuleCustomizer; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - satisfiesRule(name: string, ...args: any[]): FluentRuleCustomizer; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - required(): FluentRuleCustomizer; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - matches(regex: RegExp): FluentRuleCustomizer; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - email(): FluentRuleCustomizer; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - minLength(length: number): FluentRuleCustomizer; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - maxLength(length: number): FluentRuleCustomizer; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - minItems(count: number): FluentRuleCustomizer; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - maxItems(count: number): FluentRuleCustomizer; - /** - * Applies the "equals" validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - equals(expectedValue: TValue): FluentRuleCustomizer; -} -/** - * Part of the fluent rule API. Enables applying rules to properties and objects. - */ -export declare class FluentRules { - private fluentEnsure; - private parsers; - private property; - static customRules: { - [name: string]: { - condition: (value: any, object?: any, ...fluentArgs: any[]) => boolean | Promise; - argsToConfig?: (...args: any[]) => any; - }; - }; - /** - * Current rule sequence number. Used to postpone evaluation of rules until rules - * with lower sequence number have successfully validated. The "then" fluent API method - * manages this property, there's usually no need to set it directly. - */ - sequence: number; - constructor(fluentEnsure: FluentEnsure, parsers: Parsers, property: RuleProperty); - /** - * Sets the display name of the ensured property. - */ - displayName(name: string | ValidationDisplayNameAccessor | null): this; - /** - * Applies an ad-hoc rule function to the ensured property or object. - * @param condition The function to validate the rule. - * Will be called with two arguments, the property value and the object. - * Should return a boolean or a Promise that resolves to a boolean. - */ - satisfies(condition: (value: TValue, object?: TObject) => boolean | Promise, config?: object): FluentRuleCustomizer; - /** - * Applies a rule by name. - * @param name The name of the custom or standard rule. - * @param args The rule's arguments. - */ - satisfiesRule(name: string, ...args: any[]): FluentRuleCustomizer; - /** - * Applies the "required" rule to the property. - * The value cannot be null, undefined or whitespace. - */ - required(): FluentRuleCustomizer; - /** - * Applies the "matches" rule to the property. - * Value must match the specified regular expression. - * null, undefined and empty-string values are considered valid. - */ - matches(regex: RegExp): FluentRuleCustomizer; - /** - * Applies the "email" rule to the property. - * null, undefined and empty-string values are considered valid. - */ - email(): FluentRuleCustomizer; - /** - * Applies the "minLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - minLength(length: number): FluentRuleCustomizer; - /** - * Applies the "maxLength" STRING validation rule to the property. - * null, undefined and empty-string values are considered valid. - */ - maxLength(length: number): FluentRuleCustomizer; - /** - * Applies the "minItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - minItems(count: number): FluentRuleCustomizer; - /** - * Applies the "maxItems" ARRAY validation rule to the property. - * null and undefined values are considered valid. - */ - maxItems(count: number): FluentRuleCustomizer; - /** - * Applies the "equals" validation rule to the property. - * null and undefined values are considered valid. - */ - equals(expectedValue: TValue): FluentRuleCustomizer; -} -/** - * Part of the fluent rule API. Enables targeting properties and objects with rules. - */ -export declare class FluentEnsure { - private parsers; - /** - * Rules that have been defined using the fluent API. - */ - rules: Rule[][]; - constructor(parsers: Parsers); - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor - * function. - */ - ensure(property: string | number | PropertyAccessor): FluentRules; - /** - * Targets an object with validation rules. - */ - ensureObject(): FluentRules; - /** - * Applies the rules to a class or object, making them discoverable by the StandardValidator. - * @param target A class or object. - */ - on(target: any): this; - private assertInitialized(); - private mergeRules(fluentRules, propertyName); -} -/** - * Fluent rule definition API. - */ -export declare class ValidationRules { - private static parsers; - static initialize(messageParser: ValidationMessageParser, propertyParser: PropertyAccessorParser): void; - /** - * Target a property with validation rules. - * @param property The property to target. Can be the property name or a property accessor function. - */ - static ensure(property: string | number | PropertyAccessor): FluentRules; - /** - * Targets an object with validation rules. - */ - static ensureObject(): FluentRules; - /** - * Defines a custom rule. - * @param name The name of the custom rule. Also serves as the message key. - * @param condition The rule function. - * @param message The message expression - * @param argsToConfig A function that maps the rule's arguments to a "config" - * object that can be used when evaluating the message expression. - */ - static customRule(name: string, condition: (value: any, object?: any, ...args: any[]) => boolean | Promise, message: string, argsToConfig?: (...args: any[]) => any): void; - /** - * Returns rules with the matching tag. - * @param rules The rules to search. - * @param tag The tag to search for. - */ - static taggedRules(rules: Rule[][], tag: string): Rule[][]; - /** - * Returns rules that have no tag. - * @param rules The rules to search. - */ - static untaggedRules(rules: Rule[][]): Rule[][]; - /** - * Removes the rules from a class or object. - * @param target A class or object. - */ - static off(target: any): void; -} -export interface Parsers { - message: ValidationMessageParser; - property: PropertyAccessorParser; -} +import { Rule, RuleProperty, ValidationDisplayNameAccessor } from './rule'; +import { ValidationMessageParser } from './validation-message-parser'; +import { PropertyAccessorParser, PropertyAccessor } from '../property-accessor-parser'; +/** + * Part of the fluent rule API. Enables customizing property rules. + */ +export declare class FluentRuleCustomizer { + private fluentEnsure; + private fluentRules; + private parsers; + private rule; + constructor(property: RuleProperty, condition: (value: TValue, object?: TObject) => boolean | Promise, config: object | undefined, fluentEnsure: FluentEnsure, fluentRules: FluentRules, parsers: Parsers); + /** + * Validate subsequent rules after previously declared rules have + * been validated successfully. Use to postpone validation of costly + * rules until less expensive rules pass validation. + */ + then(): this; + /** + * Specifies the key to use when looking up the rule's validation message. + */ + withMessageKey(key: string): this; + /** + * Specifies rule's validation message. + */ + withMessage(message: string): this; + /** + * Specifies a condition that must be met before attempting to validate the rule. + * @param condition A function that accepts the object as a parameter and returns true + * or false whether the rule should be evaluated. + */ + when(condition: (object: TObject) => boolean): this; + /** + * Tags the rule instance, enabling the rule to be found easily + * using ValidationRules.taggedRules(rules, tag) + */ + tag(tag: string): this; + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor function. + */ + ensure(subject: string | ((model: TObject) => TValue2)): FluentRules; + /** + * Targets an object with validation rules. + */ + ensureObject(): FluentRules; + /** + * Rules that have been defined using the fluent API. + */ + readonly rules: Rule[][]; + /** + * Applies the rules to a class or object, making them discoverable by the StandardValidator. + * @param target A class or object. + */ + on(target: any): FluentEnsure; + /** + * Applies an ad-hoc rule function to the ensured property or object. + * @param condition The function to validate the rule. + * Will be called with two arguments, the property value and the object. + * Should return a boolean or a Promise that resolves to a boolean. + */ + satisfies(condition: (value: TValue, object: TObject) => boolean | Promise, config?: object): FluentRuleCustomizer; + /** + * Applies a rule by name. + * @param name The name of the custom or standard rule. + * @param args The rule's arguments. + */ + satisfiesRule(name: string, ...args: any[]): FluentRuleCustomizer; + /** + * Applies the "required" rule to the property. + * The value cannot be null, undefined or whitespace. + */ + required(): FluentRuleCustomizer; + /** + * Applies the "matches" rule to the property. + * Value must match the specified regular expression. + * null, undefined and empty-string values are considered valid. + */ + matches(regex: RegExp): FluentRuleCustomizer; + /** + * Applies the "email" rule to the property. + * null, undefined and empty-string values are considered valid. + */ + email(): FluentRuleCustomizer; + /** + * Applies the "minLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + minLength(length: number): FluentRuleCustomizer; + /** + * Applies the "maxLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + maxLength(length: number): FluentRuleCustomizer; + /** + * Applies the "minItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + minItems(count: number): FluentRuleCustomizer; + /** + * Applies the "maxItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + maxItems(count: number): FluentRuleCustomizer; + /** + * Applies the "equals" validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + equals(expectedValue: TValue): FluentRuleCustomizer; +} +/** + * Part of the fluent rule API. Enables applying rules to properties and objects. + */ +export declare class FluentRules { + private fluentEnsure; + private parsers; + private property; + static customRules: { + [name: string]: { + condition: (value: any, object?: any, ...fluentArgs: any[]) => boolean | Promise; + argsToConfig?: (...args: any[]) => any; + }; + }; + /** + * Current rule sequence number. Used to postpone evaluation of rules until rules + * with lower sequence number have successfully validated. The "then" fluent API method + * manages this property, there's usually no need to set it directly. + */ + sequence: number; + constructor(fluentEnsure: FluentEnsure, parsers: Parsers, property: RuleProperty); + /** + * Sets the display name of the ensured property. + */ + displayName(name: string | ValidationDisplayNameAccessor | null): this; + /** + * Applies an ad-hoc rule function to the ensured property or object. + * @param condition The function to validate the rule. + * Will be called with two arguments, the property value and the object. + * Should return a boolean or a Promise that resolves to a boolean. + */ + satisfies(condition: (value: TValue, object?: TObject) => boolean | Promise, config?: object): FluentRuleCustomizer; + /** + * Applies a rule by name. + * @param name The name of the custom or standard rule. + * @param args The rule's arguments. + */ + satisfiesRule(name: string, ...args: any[]): FluentRuleCustomizer; + /** + * Applies the "required" rule to the property. + * The value cannot be null, undefined or whitespace. + */ + required(): FluentRuleCustomizer; + /** + * Applies the "matches" rule to the property. + * Value must match the specified regular expression. + * null, undefined and empty-string values are considered valid. + */ + matches(regex: RegExp): FluentRuleCustomizer; + /** + * Applies the "email" rule to the property. + * null, undefined and empty-string values are considered valid. + */ + email(): FluentRuleCustomizer; + /** + * Applies the "minLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + minLength(length: number): FluentRuleCustomizer; + /** + * Applies the "maxLength" STRING validation rule to the property. + * null, undefined and empty-string values are considered valid. + */ + maxLength(length: number): FluentRuleCustomizer; + /** + * Applies the "minItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + minItems(count: number): FluentRuleCustomizer; + /** + * Applies the "maxItems" ARRAY validation rule to the property. + * null and undefined values are considered valid. + */ + maxItems(count: number): FluentRuleCustomizer; + /** + * Applies the "equals" validation rule to the property. + * null and undefined values are considered valid. + */ + equals(expectedValue: TValue): FluentRuleCustomizer; +} +/** + * Part of the fluent rule API. Enables targeting properties and objects with rules. + */ +export declare class FluentEnsure { + private parsers; + /** + * Rules that have been defined using the fluent API. + */ + rules: Rule[][]; + constructor(parsers: Parsers); + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor + * function. + */ + ensure(property: string | number | PropertyAccessor): FluentRules; + /** + * Targets an object with validation rules. + */ + ensureObject(): FluentRules; + /** + * Applies the rules to a class or object, making them discoverable by the StandardValidator. + * @param target A class or object. + */ + on(target: any): this; + private assertInitialized; + private mergeRules; +} +/** + * Fluent rule definition API. + */ +export declare class ValidationRules { + private static parsers; + static initialize(messageParser: ValidationMessageParser, propertyParser: PropertyAccessorParser): void; + /** + * Target a property with validation rules. + * @param property The property to target. Can be the property name or a property accessor function. + */ + static ensure(property: string | number | PropertyAccessor): FluentRules; + /** + * Targets an object with validation rules. + */ + static ensureObject(): FluentRules; + /** + * Defines a custom rule. + * @param name The name of the custom rule. Also serves as the message key. + * @param condition The rule function. + * @param message The message expression + * @param argsToConfig A function that maps the rule's arguments to a "config" + * object that can be used when evaluating the message expression. + */ + static customRule(name: string, condition: (value: any, object?: any, ...args: any[]) => boolean | Promise, message: string, argsToConfig?: (...args: any[]) => any): void; + /** + * Returns rules with the matching tag. + * @param rules The rules to search. + * @param tag The tag to search for. + */ + static taggedRules(rules: Rule[][], tag: string): Rule[][]; + /** + * Returns rules that have no tag. + * @param rules The rules to search. + */ + static untaggedRules(rules: Rule[][]): Rule[][]; + /** + * Removes the rules from a class or object. + * @param target A class or object. + */ + static off(target: any): void; +} +export interface Parsers { + message: ValidationMessageParser; + property: PropertyAccessorParser; +} diff --git a/dist/amd/property-accessor-parser.d.ts b/dist/types/property-accessor-parser.d.ts similarity index 98% rename from dist/amd/property-accessor-parser.d.ts rename to dist/types/property-accessor-parser.d.ts index ba64614b..e5a4ee49 100644 --- a/dist/amd/property-accessor-parser.d.ts +++ b/dist/types/property-accessor-parser.d.ts @@ -1,9 +1,9 @@ -import { Parser } from 'aurelia-binding'; -export declare type PropertyAccessor = (object: TObject) => TValue; -export declare class PropertyAccessorParser { - private parser; - static inject: (typeof Parser)[]; - constructor(parser: Parser); - parse(property: string | number | PropertyAccessor): string | number; -} -export declare function getAccessorExpression(fn: string): string; +import { Parser } from 'aurelia-binding'; +export declare type PropertyAccessor = (object: TObject) => TValue; +export declare class PropertyAccessorParser { + private parser; + static inject: (typeof Parser)[]; + constructor(parser: Parser); + parse(property: string | number | PropertyAccessor): string | number; +} +export declare function getAccessorExpression(fn: string): string; diff --git a/dist/es2015/property-info.d.ts b/dist/types/property-info.d.ts similarity index 97% rename from dist/es2015/property-info.d.ts rename to dist/types/property-info.d.ts index 35fef1d5..3e3e5661 100644 --- a/dist/es2015/property-info.d.ts +++ b/dist/types/property-info.d.ts @@ -1,10 +1,10 @@ -import { Expression, Scope } from 'aurelia-binding'; -/** - * Retrieves the object and property name for the specified expression. - * @param expression The expression - * @param source The scope - */ -export declare function getPropertyInfo(expression: Expression, source: Scope): { - object: object; - propertyName: string; -} | null; +import { Expression, Scope } from 'aurelia-binding'; +/** + * Retrieves the object and property name for the specified expression. + * @param expression The expression + * @param source The scope + */ +export declare function getPropertyInfo(expression: Expression, source: Scope): { + object: object; + propertyName: string; +} | null; diff --git a/dist/amd/util.d.ts b/dist/types/util.d.ts similarity index 98% rename from dist/amd/util.d.ts rename to dist/types/util.d.ts index f6873f03..0fb2c86c 100644 --- a/dist/amd/util.d.ts +++ b/dist/types/util.d.ts @@ -1,2 +1,2 @@ -export declare function isString(value: any): boolean; -export declare function isNumber(value: any): boolean; +export declare function isString(value: any): boolean; +export declare function isNumber(value: any): boolean; diff --git a/dist/amd/validate-binding-behavior-base.d.ts b/dist/types/validate-binding-behavior-base.d.ts similarity index 97% rename from dist/amd/validate-binding-behavior-base.d.ts rename to dist/types/validate-binding-behavior-base.d.ts index 971c8e83..0248159c 100644 --- a/dist/amd/validate-binding-behavior-base.d.ts +++ b/dist/types/validate-binding-behavior-base.d.ts @@ -1,13 +1,13 @@ -import { TaskQueue } from 'aurelia-task-queue'; -import { ValidationController } from './validation-controller'; -import { validateTrigger } from './validate-trigger'; -/** - * Binding behavior. Indicates the bound property should be validated. - */ -export declare abstract class ValidateBindingBehaviorBase { - private taskQueue; - constructor(taskQueue: TaskQueue); - protected abstract getValidateTrigger(controller: ValidationController): validateTrigger; - bind(binding: any, source: any, rulesOrController?: ValidationController | any, rules?: any): void; - unbind(binding: any): void; -} +import { TaskQueue } from 'aurelia-task-queue'; +import { ValidationController } from './validation-controller'; +import { validateTrigger } from './validate-trigger'; +/** + * Binding behavior. Indicates the bound property should be validated. + */ +export declare abstract class ValidateBindingBehaviorBase { + private taskQueue; + constructor(taskQueue: TaskQueue); + protected abstract getValidateTrigger(controller: ValidationController): validateTrigger; + bind(binding: any, source: any, rulesOrController?: ValidationController | any, rules?: any): void; + unbind(binding: any): void; +} diff --git a/dist/es2015/validate-binding-behavior.d.ts b/dist/types/validate-binding-behavior.d.ts similarity index 97% rename from dist/es2015/validate-binding-behavior.d.ts rename to dist/types/validate-binding-behavior.d.ts index 08b5d9e0..90f40d9d 100644 --- a/dist/es2015/validate-binding-behavior.d.ts +++ b/dist/types/validate-binding-behavior.d.ts @@ -1,48 +1,48 @@ -import { TaskQueue } from 'aurelia-task-queue'; -import { ValidationController } from './validation-controller'; -import { validateTrigger } from './validate-trigger'; -import { ValidateBindingBehaviorBase } from './validate-binding-behavior-base'; -/** - * Binding behavior. Indicates the bound property should be validated - * when the validate trigger specified by the associated controller's - * validateTrigger property occurs. - */ -export declare class ValidateBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(controller: ValidationController): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property will be validated - * manually, by calling controller.validate(). No automatic validation - * triggered by data-entry or blur will occur. - */ -export declare class ValidateManuallyBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs. - */ -export declare class ValidateOnBlurBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element is changed by the user, causing a change - * to the model. - */ -export declare class ValidateOnChangeBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} -/** - * Binding behavior. Indicates the bound property should be validated - * when the associated element blurs or is changed by the user, causing - * a change to the model. - */ -export declare class ValidateOnChangeOrBlurBindingBehavior extends ValidateBindingBehaviorBase { - static inject: (typeof TaskQueue)[]; - getValidateTrigger(): validateTrigger; -} +import { TaskQueue } from 'aurelia-task-queue'; +import { ValidationController } from './validation-controller'; +import { validateTrigger } from './validate-trigger'; +import { ValidateBindingBehaviorBase } from './validate-binding-behavior-base'; +/** + * Binding behavior. Indicates the bound property should be validated + * when the validate trigger specified by the associated controller's + * validateTrigger property occurs. + */ +export declare class ValidateBindingBehavior extends ValidateBindingBehaviorBase { + static inject: (typeof TaskQueue)[]; + getValidateTrigger(controller: ValidationController): validateTrigger; +} +/** + * Binding behavior. Indicates the bound property will be validated + * manually, by calling controller.validate(). No automatic validation + * triggered by data-entry or blur will occur. + */ +export declare class ValidateManuallyBindingBehavior extends ValidateBindingBehaviorBase { + static inject: (typeof TaskQueue)[]; + getValidateTrigger(): validateTrigger; +} +/** + * Binding behavior. Indicates the bound property should be validated + * when the associated element blurs. + */ +export declare class ValidateOnBlurBindingBehavior extends ValidateBindingBehaviorBase { + static inject: (typeof TaskQueue)[]; + getValidateTrigger(): validateTrigger; +} +/** + * Binding behavior. Indicates the bound property should be validated + * when the associated element is changed by the user, causing a change + * to the model. + */ +export declare class ValidateOnChangeBindingBehavior extends ValidateBindingBehaviorBase { + static inject: (typeof TaskQueue)[]; + getValidateTrigger(): validateTrigger; +} +/** + * Binding behavior. Indicates the bound property should be validated + * when the associated element blurs or is changed by the user, causing + * a change to the model. + */ +export declare class ValidateOnChangeOrBlurBindingBehavior extends ValidateBindingBehaviorBase { + static inject: (typeof TaskQueue)[]; + getValidateTrigger(): validateTrigger; +} diff --git a/dist/es2015/validate-event.d.ts b/dist/types/validate-event.d.ts similarity index 52% rename from dist/es2015/validate-event.d.ts rename to dist/types/validate-event.d.ts index 0fbacbb7..c32fb2fe 100644 --- a/dist/es2015/validate-event.d.ts +++ b/dist/types/validate-event.d.ts @@ -1,62 +1,62 @@ -import { ValidateResult } from './validate-result'; -import { ValidateInstruction } from './validate-instruction'; -import { ControllerValidateResult } from './controller-validate-result'; -export declare class ValidateEvent { - /** - * The type of validate event. Either "validate" or "reset". - */ - readonly type: 'validate' | 'reset'; - /** - * The controller's current array of errors. For an array containing both - * failed rules and passed rules, use the "results" property. - */ - readonly errors: ValidateResult[]; - /** - * The controller's current array of validate results. This - * includes both passed rules and failed rules. For an array of only failed rules, - * use the "errors" property. - */ - readonly results: ValidateResult[]; - /** - * The instruction passed to the "validate" or "reset" event. Will be null when - * the controller's validate/reset method was called with no instruction argument. - */ - readonly instruction: ValidateInstruction | null; - /** - * In events with type === "validate", this property will contain the result - * of validating the instruction (see "instruction" property). Use the controllerValidateResult - * to access the validate results specific to the call to "validate" - * (as opposed to using the "results" and "errors" properties to access the controller's entire - * set of results/errors). - */ - readonly controllerValidateResult: ControllerValidateResult | null; - constructor( - /** - * The type of validate event. Either "validate" or "reset". - */ - type: 'validate' | 'reset', - /** - * The controller's current array of errors. For an array containing both - * failed rules and passed rules, use the "results" property. - */ - errors: ValidateResult[], - /** - * The controller's current array of validate results. This - * includes both passed rules and failed rules. For an array of only failed rules, - * use the "errors" property. - */ - results: ValidateResult[], - /** - * The instruction passed to the "validate" or "reset" event. Will be null when - * the controller's validate/reset method was called with no instruction argument. - */ - instruction: ValidateInstruction | null, - /** - * In events with type === "validate", this property will contain the result - * of validating the instruction (see "instruction" property). Use the controllerValidateResult - * to access the validate results specific to the call to "validate" - * (as opposed to using the "results" and "errors" properties to access the controller's entire - * set of results/errors). - */ - controllerValidateResult: ControllerValidateResult | null); -} +import { ValidateResult } from './validate-result'; +import { ValidateInstruction } from './validate-instruction'; +import { ControllerValidateResult } from './controller-validate-result'; +export declare class ValidateEvent { + /** + * The type of validate event. Either "validate" or "reset". + */ + readonly type: 'validate' | 'reset'; + /** + * The controller's current array of errors. For an array containing both + * failed rules and passed rules, use the "results" property. + */ + readonly errors: ValidateResult[]; + /** + * The controller's current array of validate results. This + * includes both passed rules and failed rules. For an array of only failed rules, + * use the "errors" property. + */ + readonly results: ValidateResult[]; + /** + * The instruction passed to the "validate" or "reset" event. Will be null when + * the controller's validate/reset method was called with no instruction argument. + */ + readonly instruction: ValidateInstruction | null; + /** + * In events with type === "validate", this property will contain the result + * of validating the instruction (see "instruction" property). Use the controllerValidateResult + * to access the validate results specific to the call to "validate" + * (as opposed to using the "results" and "errors" properties to access the controller's entire + * set of results/errors). + */ + readonly controllerValidateResult: ControllerValidateResult | null; + constructor( + /** + * The type of validate event. Either "validate" or "reset". + */ + type: 'validate' | 'reset', + /** + * The controller's current array of errors. For an array containing both + * failed rules and passed rules, use the "results" property. + */ + errors: ValidateResult[], + /** + * The controller's current array of validate results. This + * includes both passed rules and failed rules. For an array of only failed rules, + * use the "errors" property. + */ + results: ValidateResult[], + /** + * The instruction passed to the "validate" or "reset" event. Will be null when + * the controller's validate/reset method was called with no instruction argument. + */ + instruction: ValidateInstruction | null, + /** + * In events with type === "validate", this property will contain the result + * of validating the instruction (see "instruction" property). Use the controllerValidateResult + * to access the validate results specific to the call to "validate" + * (as opposed to using the "results" and "errors" properties to access the controller's entire + * set of results/errors). + */ + controllerValidateResult: ControllerValidateResult | null); +} diff --git a/dist/commonjs/validate-instruction.d.ts b/dist/types/validate-instruction.d.ts similarity index 95% rename from dist/commonjs/validate-instruction.d.ts rename to dist/types/validate-instruction.d.ts index 2f792a70..114c2d24 100644 --- a/dist/commonjs/validate-instruction.d.ts +++ b/dist/types/validate-instruction.d.ts @@ -1,17 +1,17 @@ -/** - * Instructions for the validation controller's validate method. - */ -export interface ValidateInstruction { - /** - * The object to validate. - */ - object: any; - /** - * The property to validate. Optional. - */ - propertyName?: any; - /** - * The rules to validate. Optional. - */ - rules?: any; -} +/** + * Instructions for the validation controller's validate method. + */ +export interface ValidateInstruction { + /** + * The object to validate. + */ + object: any; + /** + * The property to validate. Optional. + */ + propertyName?: any; + /** + * The rules to validate. Optional. + */ + rules?: any; +} diff --git a/dist/amd/validate-result.d.ts b/dist/types/validate-result.d.ts similarity index 97% rename from dist/amd/validate-result.d.ts rename to dist/types/validate-result.d.ts index 91d79995..5e9fdf9d 100644 --- a/dist/amd/validate-result.d.ts +++ b/dist/types/validate-result.d.ts @@ -1,23 +1,23 @@ -/** - * The result of validating an individual validation rule. - */ -export declare class ValidateResult { - rule: any; - object: any; - propertyName: string | number | null; - valid: boolean; - message: string | null; - private static nextId; - /** - * A number that uniquely identifies the result instance. - */ - id: number; - /** - * @param rule The rule associated with the result. Validator implementation specific. - * @param object The object that was validated. - * @param propertyName The name of the property that was validated. - * @param error The error, if the result is a validation error. - */ - constructor(rule: any, object: any, propertyName: string | number | null, valid: boolean, message?: string | null); - toString(): string | null; -} +/** + * The result of validating an individual validation rule. + */ +export declare class ValidateResult { + rule: any; + object: any; + propertyName: string | number | null; + valid: boolean; + message: string | null; + private static nextId; + /** + * A number that uniquely identifies the result instance. + */ + id: number; + /** + * @param rule The rule associated with the result. Validator implementation specific. + * @param object The object that was validated. + * @param propertyName The name of the property that was validated. + * @param error The error, if the result is a validation error. + */ + constructor(rule: any, object: any, propertyName: string | number | null, valid: boolean, message?: string | null); + toString(): string | null; +} diff --git a/dist/amd/validate-trigger.d.ts b/dist/types/validate-trigger.d.ts similarity index 93% rename from dist/amd/validate-trigger.d.ts rename to dist/types/validate-trigger.d.ts index 43e76851..f8f4a450 100644 --- a/dist/amd/validate-trigger.d.ts +++ b/dist/types/validate-trigger.d.ts @@ -1,23 +1,23 @@ -/** - * Validation triggers. - */ -export declare enum validateTrigger { - /** - * Manual validation. Use the controller's `validate()` and `reset()` methods - * to validate all bindings. - */ - manual = 0, - /** - * Validate the binding when the binding's target element fires a DOM "blur" event. - */ - blur = 1, - /** - * Validate the binding when it updates the model due to a change in the view. - */ - change = 2, - /** - * Validate the binding when the binding's target element fires a DOM "blur" event and - * when it updates the model due to a change in the view. - */ - changeOrBlur = 3, -} +/** + * Validation triggers. + */ +export declare enum validateTrigger { + /** + * Manual validation. Use the controller's `validate()` and `reset()` methods + * to validate all bindings. + */ + manual = 0, + /** + * Validate the binding when the binding's target element fires a DOM "blur" event. + */ + blur = 1, + /** + * Validate the binding when it updates the model due to a change in the view. + */ + change = 2, + /** + * Validate the binding when the binding's target element fires a DOM "blur" event and + * when it updates the model due to a change in the view. + */ + changeOrBlur = 3 +} diff --git a/dist/es2015/validation-controller-factory.d.ts b/dist/types/validation-controller-factory.d.ts similarity index 97% rename from dist/es2015/validation-controller-factory.d.ts rename to dist/types/validation-controller-factory.d.ts index 2c51999e..b1589666 100644 --- a/dist/es2015/validation-controller-factory.d.ts +++ b/dist/types/validation-controller-factory.d.ts @@ -1,20 +1,20 @@ -import { Container } from 'aurelia-dependency-injection'; -import { ValidationController } from './validation-controller'; -import { Validator } from './validator'; -/** - * Creates ValidationController instances. - */ -export declare class ValidationControllerFactory { - private container; - static get(container: Container): ValidationControllerFactory; - constructor(container: Container); - /** - * Creates a new controller instance. - */ - create(validator?: Validator): ValidationController; - /** - * Creates a new controller and registers it in the current element's container so that it's - * available to the validate binding behavior and renderers. - */ - createForCurrentScope(validator?: Validator): ValidationController; -} +import { Container } from 'aurelia-dependency-injection'; +import { ValidationController } from './validation-controller'; +import { Validator } from './validator'; +/** + * Creates ValidationController instances. + */ +export declare class ValidationControllerFactory { + private container; + static get(container: Container): ValidationControllerFactory; + constructor(container: Container); + /** + * Creates a new controller instance. + */ + create(validator?: Validator): ValidationController; + /** + * Creates a new controller and registers it in the current element's container so that it's + * available to the validate binding behavior and renderers. + */ + createForCurrentScope(validator?: Validator): ValidationController; +} diff --git a/dist/amd/validation-controller.d.ts b/dist/types/validation-controller.d.ts similarity index 93% rename from dist/amd/validation-controller.d.ts rename to dist/types/validation-controller.d.ts index 7f208d49..17433d5c 100644 --- a/dist/amd/validation-controller.d.ts +++ b/dist/types/validation-controller.d.ts @@ -1,131 +1,131 @@ -import { Binding } from 'aurelia-binding'; -import { Validator } from './validator'; -import { validateTrigger } from './validate-trigger'; -import { ValidationRenderer } from './validation-renderer'; -import { ValidateResult } from './validate-result'; -import { ValidateInstruction } from './validate-instruction'; -import { ControllerValidateResult } from './controller-validate-result'; -import { PropertyAccessorParser, PropertyAccessor } from './property-accessor-parser'; -import { ValidateEvent } from './validate-event'; -/** - * Orchestrates validation. - * Manages a set of bindings, renderers and objects. - * Exposes the current list of validation results for binding purposes. - */ -export declare class ValidationController { - private validator; - private propertyParser; - static inject: (typeof PropertyAccessorParser | typeof Validator)[]; - private bindings; - private renderers; - /** - * Validation results that have been rendered by the controller. - */ - private results; - /** - * Validation errors that have been rendered by the controller. - */ - errors: ValidateResult[]; - /** - * Whether the controller is currently validating. - */ - validating: boolean; - private elements; - private objects; - /** - * The trigger that will invoke automatic validation of a property used in a binding. - */ - validateTrigger: validateTrigger; - private finishValidating; - private eventCallbacks; - constructor(validator: Validator, propertyParser: PropertyAccessorParser); - /** - * Subscribe to controller validate and reset events. These events occur when the - * controller's "validate"" and "reset" methods are called. - * @param callback The callback to be invoked when the controller validates or resets. - */ - subscribe(callback: (event: ValidateEvent) => void): { - dispose: () => void; - }; - /** - * Adds an object to the set of objects that should be validated when validate is called. - * @param object The object. - * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. - */ - addObject(object: any, rules?: any): void; - /** - * Removes an object from the set of objects that should be validated when validate is called. - * @param object The object. - */ - removeObject(object: any): void; - /** - * Adds and renders an error. - */ - addError(message: string, object: TObject, propertyName?: string | PropertyAccessor | null): ValidateResult; - /** - * Removes and unrenders an error. - */ - removeError(result: ValidateResult): void; - /** - * Adds a renderer. - * @param renderer The renderer. - */ - addRenderer(renderer: ValidationRenderer): void; - /** - * Removes a renderer. - * @param renderer The renderer. - */ - removeRenderer(renderer: ValidationRenderer): void; - /** - * Registers a binding with the controller. - * @param binding The binding instance. - * @param target The DOM element. - * @param rules (optional) rules associated with the binding. Validator implementation specific. - */ - registerBinding(binding: Binding, target: Element, rules?: any): void; - /** - * Unregisters a binding with the controller. - * @param binding The binding instance. - */ - unregisterBinding(binding: Binding): void; - /** - * Interprets the instruction and returns a predicate that will identify - * relevant results in the list of rendered validation results. - */ - private getInstructionPredicate(instruction?); - /** - * Validates and renders results. - * @param instruction Optional. Instructions on what to validate. If undefined, all - * objects and bindings will be validated. - */ - validate(instruction?: ValidateInstruction): Promise; - /** - * Resets any rendered validation results (unrenders). - * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results - * will be unrendered. - */ - reset(instruction?: ValidateInstruction): void; - /** - * Gets the elements associated with an object and propertyName (if any). - */ - private getAssociatedElements({object, propertyName}); - private processResultDelta(kind, oldResults, newResults); - /** - * Validates the property associated with a binding. - */ - validateBinding(binding: Binding): void; - /** - * Resets the results for a property associated with a binding. - */ - resetBinding(binding: Binding): void; - /** - * Changes the controller's validateTrigger. - * @param newTrigger The new validateTrigger - */ - changeTrigger(newTrigger: validateTrigger): void; - /** - * Revalidates the controller's current set of errors. - */ - revalidateErrors(): void; - private invokeCallbacks(instruction, result); -} +import { Binding } from 'aurelia-binding'; +import { Validator } from './validator'; +import { validateTrigger } from './validate-trigger'; +import { ValidationRenderer } from './validation-renderer'; +import { ValidateResult } from './validate-result'; +import { ValidateInstruction } from './validate-instruction'; +import { ControllerValidateResult } from './controller-validate-result'; +import { PropertyAccessorParser, PropertyAccessor } from './property-accessor-parser'; +import { ValidateEvent } from './validate-event'; +/** + * Orchestrates validation. + * Manages a set of bindings, renderers and objects. + * Exposes the current list of validation results for binding purposes. + */ +export declare class ValidationController { + private validator; + private propertyParser; + static inject: (typeof Validator | typeof PropertyAccessorParser)[]; + private bindings; + private renderers; + /** + * Validation results that have been rendered by the controller. + */ + private results; + /** + * Validation errors that have been rendered by the controller. + */ + errors: ValidateResult[]; + /** + * Whether the controller is currently validating. + */ + validating: boolean; + private elements; + private objects; + /** + * The trigger that will invoke automatic validation of a property used in a binding. + */ + validateTrigger: validateTrigger; + private finishValidating; + private eventCallbacks; + constructor(validator: Validator, propertyParser: PropertyAccessorParser); + /** + * Subscribe to controller validate and reset events. These events occur when the + * controller's "validate"" and "reset" methods are called. + * @param callback The callback to be invoked when the controller validates or resets. + */ + subscribe(callback: (event: ValidateEvent) => void): { + dispose: () => void; + }; + /** + * Adds an object to the set of objects that should be validated when validate is called. + * @param object The object. + * @param rules Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules. + */ + addObject(object: any, rules?: any): void; + /** + * Removes an object from the set of objects that should be validated when validate is called. + * @param object The object. + */ + removeObject(object: any): void; + /** + * Adds and renders an error. + */ + addError(message: string, object: TObject, propertyName?: string | PropertyAccessor | null): ValidateResult; + /** + * Removes and unrenders an error. + */ + removeError(result: ValidateResult): void; + /** + * Adds a renderer. + * @param renderer The renderer. + */ + addRenderer(renderer: ValidationRenderer): void; + /** + * Removes a renderer. + * @param renderer The renderer. + */ + removeRenderer(renderer: ValidationRenderer): void; + /** + * Registers a binding with the controller. + * @param binding The binding instance. + * @param target The DOM element. + * @param rules (optional) rules associated with the binding. Validator implementation specific. + */ + registerBinding(binding: Binding, target: Element, rules?: any): void; + /** + * Unregisters a binding with the controller. + * @param binding The binding instance. + */ + unregisterBinding(binding: Binding): void; + /** + * Interprets the instruction and returns a predicate that will identify + * relevant results in the list of rendered validation results. + */ + private getInstructionPredicate; + /** + * Validates and renders results. + * @param instruction Optional. Instructions on what to validate. If undefined, all + * objects and bindings will be validated. + */ + validate(instruction?: ValidateInstruction): Promise; + /** + * Resets any rendered validation results (unrenders). + * @param instruction Optional. Instructions on what to reset. If unspecified all rendered results + * will be unrendered. + */ + reset(instruction?: ValidateInstruction): void; + /** + * Gets the elements associated with an object and propertyName (if any). + */ + private getAssociatedElements; + private processResultDelta; + /** + * Validates the property associated with a binding. + */ + validateBinding(binding: Binding): void; + /** + * Resets the results for a property associated with a binding. + */ + resetBinding(binding: Binding): void; + /** + * Changes the controller's validateTrigger. + * @param newTrigger The new validateTrigger + */ + changeTrigger(newTrigger: validateTrigger): void; + /** + * Revalidates the controller's current set of errors. + */ + revalidateErrors(): void; + private invokeCallbacks; +} diff --git a/dist/commonjs/validation-errors-custom-attribute.d.ts b/dist/types/validation-errors-custom-attribute.d.ts similarity index 97% rename from dist/commonjs/validation-errors-custom-attribute.d.ts rename to dist/types/validation-errors-custom-attribute.d.ts index 056e08ea..bebb1a51 100644 --- a/dist/commonjs/validation-errors-custom-attribute.d.ts +++ b/dist/types/validation-errors-custom-attribute.d.ts @@ -1,25 +1,25 @@ -import { Lazy } from 'aurelia-dependency-injection'; -import { ValidationController } from './validation-controller'; -import { ValidateResult } from './validate-result'; -import { ValidationRenderer, RenderInstruction } from './validation-renderer'; -export interface RenderedError { - error: ValidateResult; - targets: Element[]; -} -export declare class ValidationErrorsCustomAttribute implements ValidationRenderer { - private boundaryElement; - private controllerAccessor; - static inject(): ({ - new (): Element; - prototype: Element; - } | Lazy)[]; - controller: ValidationController | null; - errors: RenderedError[]; - private errorsInternal; - constructor(boundaryElement: Element, controllerAccessor: () => ValidationController); - sort(): void; - interestingElements(elements: Element[]): Element[]; - render(instruction: RenderInstruction): void; - bind(): void; - unbind(): void; -} +import { Lazy } from 'aurelia-dependency-injection'; +import { ValidationController } from './validation-controller'; +import { ValidateResult } from './validate-result'; +import { ValidationRenderer, RenderInstruction } from './validation-renderer'; +export interface RenderedError { + error: ValidateResult; + targets: Element[]; +} +export declare class ValidationErrorsCustomAttribute implements ValidationRenderer { + private boundaryElement; + private controllerAccessor; + static inject(): ({ + new (): Element; + prototype: Element; + } | Lazy)[]; + controller: ValidationController | null; + errors: RenderedError[]; + private errorsInternal; + constructor(boundaryElement: Element, controllerAccessor: () => ValidationController); + sort(): void; + interestingElements(elements: Element[]): Element[]; + render(instruction: RenderInstruction): void; + bind(): void; + unbind(): void; +} diff --git a/dist/commonjs/validation-renderer-custom-attribute.d.ts b/dist/types/validation-renderer-custom-attribute.d.ts similarity index 95% rename from dist/commonjs/validation-renderer-custom-attribute.d.ts rename to dist/types/validation-renderer-custom-attribute.d.ts index 9f48614e..2fc48aa8 100644 --- a/dist/commonjs/validation-renderer-custom-attribute.d.ts +++ b/dist/types/validation-renderer-custom-attribute.d.ts @@ -1,9 +1,9 @@ -export declare class ValidationRendererCustomAttribute { - private container; - private controller; - private value; - private renderer; - created(view: any): void; - bind(): void; - unbind(): void; -} +export declare class ValidationRendererCustomAttribute { + private container; + private controller; + private value; + private renderer; + created(view: any): void; + bind(): void; + unbind(): void; +} diff --git a/dist/es2015/validation-renderer.d.ts b/dist/types/validation-renderer.d.ts similarity index 96% rename from dist/es2015/validation-renderer.d.ts rename to dist/types/validation-renderer.d.ts index eb430d9d..71c62752 100644 --- a/dist/es2015/validation-renderer.d.ts +++ b/dist/types/validation-renderer.d.ts @@ -1,42 +1,42 @@ -import { ValidateResult } from './validate-result'; -/** - * A result to render (or unrender) and the associated elements (if any) - */ -export interface ResultInstruction { - /** - * The validation result. - */ - result: ValidateResult; - /** - * The associated elements (if any). - */ - elements: Element[]; -} -/** - * Defines which validation results to render and which validation results to unrender. - */ -export interface RenderInstruction { - /** - * The "kind" of render instruction. Either 'validate' or 'reset'. - */ - kind: 'validate' | 'reset'; - /** - * The results to render. - */ - render: ResultInstruction[]; - /** - * The results to unrender. - */ - unrender: ResultInstruction[]; -} -/** - * Renders validation results. - */ -export interface ValidationRenderer { - /** - * Render the validation results. - * @param instruction The render instruction. Defines which results to render and which - * results to unrender. - */ - render(instruction: RenderInstruction): void; -} +import { ValidateResult } from './validate-result'; +/** + * A result to render (or unrender) and the associated elements (if any) + */ +export interface ResultInstruction { + /** + * The validation result. + */ + result: ValidateResult; + /** + * The associated elements (if any). + */ + elements: Element[]; +} +/** + * Defines which validation results to render and which validation results to unrender. + */ +export interface RenderInstruction { + /** + * The "kind" of render instruction. Either 'validate' or 'reset'. + */ + kind: 'validate' | 'reset'; + /** + * The results to render. + */ + render: ResultInstruction[]; + /** + * The results to unrender. + */ + unrender: ResultInstruction[]; +} +/** + * Renders validation results. + */ +export interface ValidationRenderer { + /** + * Render the validation results. + * @param instruction The render instruction. Defines which results to render and which + * results to unrender. + */ + render(instruction: RenderInstruction): void; +} diff --git a/dist/es2015/validator.d.ts b/dist/types/validator.d.ts similarity index 97% rename from dist/es2015/validator.d.ts rename to dist/types/validator.d.ts index 82c045e8..a9f49985 100644 --- a/dist/es2015/validator.d.ts +++ b/dist/types/validator.d.ts @@ -1,27 +1,27 @@ -import { ValidateResult } from './validate-result'; -/** - * Validates objects and properties. - */ -export declare abstract class Validator { - /** - * Validates the specified property. - * @param object The object to validate. - * @param propertyName The name of the property to validate. - * @param rules Optional. If unspecified, the implementation should lookup the rules for the - * specified object. This may not be possible for all implementations of this interface. - */ - abstract validateProperty(object: any, propertyName: string, rules?: any): Promise; - /** - * Validates all rules for specified object and it's properties. - * @param object The object to validate. - * @param rules Optional. If unspecified, the implementation should lookup the rules for the - * specified object. This may not be possible for all implementations of this interface. - */ - abstract validateObject(object: any, rules?: any): Promise; - /** - * Determines whether a rule exists in a set of rules. - * @param rules The rules to search. - * @parem rule The rule to find. - */ - abstract ruleExists(rules: any, rule: any): boolean; -} +import { ValidateResult } from './validate-result'; +/** + * Validates objects and properties. + */ +export declare abstract class Validator { + /** + * Validates the specified property. + * @param object The object to validate. + * @param propertyName The name of the property to validate. + * @param rules Optional. If unspecified, the implementation should lookup the rules for the + * specified object. This may not be possible for all implementations of this interface. + */ + abstract validateProperty(object: any, propertyName: string, rules?: any): Promise; + /** + * Validates all rules for specified object and it's properties. + * @param object The object to validate. + * @param rules Optional. If unspecified, the implementation should lookup the rules for the + * specified object. This may not be possible for all implementations of this interface. + */ + abstract validateObject(object: any, rules?: any): Promise; + /** + * Determines whether a rule exists in a set of rules. + * @param rules The rules to search. + * @parem rule The rule to find. + */ + abstract ruleExists(rules: any, rule: any): boolean; +} diff --git a/doc/api.json b/doc/api.json index bdecf3b4..7ce93456 100644 --- a/doc/api.json +++ b/doc/api.json @@ -1 +1 @@ -{"name":"aurelia-validation","children":[{"id":52,"name":"validateTrigger","kind":4,"kindString":"Enumeration","flags":{"isExported":true},"comment":{"shortText":"Validation triggers."},"children":[{"id":54,"name":"blur","kind":16,"kindString":"Enumeration member","flags":{"isExported":true},"comment":{"shortText":"Validate the binding when the binding's target element fires a DOM \"blur\" event."},"sources":[{"fileName":"aurelia-validation.d.ts","line":136,"character":12}],"defaultValue":"1"},{"id":55,"name":"change","kind":16,"kindString":"Enumeration member","flags":{"isExported":true},"comment":{"shortText":"Validate the binding when it updates the model due to a change in the view."},"sources":[{"fileName":"aurelia-validation.d.ts","line":140,"character":14}],"defaultValue":"2"},{"id":56,"name":"changeOrBlur","kind":16,"kindString":"Enumeration member","flags":{"isExported":true},"comment":{"shortText":"Validate the binding when the binding's target element fires a DOM \"blur\" event and\nwhen it updates the model due to a change in the view."},"sources":[{"fileName":"aurelia-validation.d.ts","line":145,"character":20}],"defaultValue":"3"},{"id":53,"name":"manual","kind":16,"kindString":"Enumeration member","flags":{"isExported":true},"comment":{"shortText":"Manual validation. Use the controller's `validate()` and `reset()` methods\nto validate all bindings."},"sources":[{"fileName":"aurelia-validation.d.ts","line":132,"character":14}],"defaultValue":"0"}],"groups":[{"title":"Enumeration members","kind":16,"children":[54,55,56,53]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":127,"character":31}]},{"id":768,"name":"AureliaValidationConfiguration","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Aurelia Validation Configuration API"},"children":[{"id":769,"name":"validatorType","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":959,"character":29}],"type":{"type":"intrinsic","name":"any"}},{"id":777,"name":"apply","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":778,"name":"apply","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the configuration."},"parameters":[{"id":779,"name":"container","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Container"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":969,"character":13}]},{"id":770,"name":"customValidator","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":771,"name":"customValidator","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Use a custom Validator implementation."},"parameters":[{"id":772,"name":"type","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reflection","declaration":{"id":773,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"children":[{"id":774,"name":"constructor","kind":512,"kindString":"Constructor","flags":{},"signatures":[{"id":775,"name":"new __type","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":776,"name":"args","kind":32768,"kindString":"Parameter","flags":{"isRest":true},"type":{"type":"array","elementType":{"type":"intrinsic","name":"any"}}}],"type":{"type":"reference","name":"Validator","id":38}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":963,"character":31}]}],"groups":[{"title":"Constructors","kind":512,"children":[774]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":963,"character":29}]}}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":963,"character":23}]}],"groups":[{"title":"Properties","kind":1024,"children":[769]},{"title":"Methods","kind":2048,"children":[777,770]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":958,"character":47}]},{"id":364,"name":"ExpressionVisitor","kind":128,"kindString":"Class","flags":{"isExported":true},"children":[{"id":389,"name":"visitAccessKeyed","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":390,"name":"visitAccessKeyed","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":391,"name":"access","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"AccessKeyed"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":569,"character":24}]},{"id":386,"name":"visitAccessMember","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":387,"name":"visitAccessMember","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":388,"name":"access","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"AccessMember"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":568,"character":25}]},{"id":383,"name":"visitAccessScope","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":384,"name":"visitAccessScope","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":385,"name":"access","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"AccessScope"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":567,"character":24}]},{"id":380,"name":"visitAccessThis","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":381,"name":"visitAccessThis","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":382,"name":"access","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"AccessThis","id":811}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":566,"character":23}]},{"id":419,"name":"visitArgs","kind":2048,"kindString":"Method","flags":{"isPrivate":true,"isExported":true},"signatures":[{"id":420,"name":"visitArgs","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":421,"name":"args","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"any"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":579,"character":25}]},{"id":374,"name":"visitAssign","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":375,"name":"visitAssign","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":376,"name":"assign","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Assign","id":810}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":564,"character":19}]},{"id":404,"name":"visitBinary","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":405,"name":"visitBinary","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":406,"name":"binary","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Binary"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":574,"character":19}]},{"id":368,"name":"visitBindingBehavior","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":369,"name":"visitBindingBehavior","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":370,"name":"behavior","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"BindingBehavior"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":562,"character":28}]},{"id":395,"name":"visitCallFunction","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":396,"name":"visitCallFunction","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":397,"name":"call","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"CallFunction","id":814}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":571,"character":25}]},{"id":398,"name":"visitCallMember","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":399,"name":"visitCallMember","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":400,"name":"call","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"CallMember"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":572,"character":23}]},{"id":392,"name":"visitCallScope","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":393,"name":"visitCallScope","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":394,"name":"call","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"CallScope","id":813}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":570,"character":22}]},{"id":365,"name":"visitChain","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":366,"name":"visitChain","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":367,"name":"chain","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Chain","id":809}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":561,"character":18}]},{"id":377,"name":"visitConditional","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":378,"name":"visitConditional","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":379,"name":"conditional","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Conditional"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":565,"character":24}]},{"id":410,"name":"visitLiteralArray","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":411,"name":"visitLiteralArray","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":412,"name":"literal","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"LiteralArray","id":817}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":576,"character":25}]},{"id":413,"name":"visitLiteralObject","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":414,"name":"visitLiteralObject","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":415,"name":"literal","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"LiteralObject","id":818}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":577,"character":26}]},{"id":407,"name":"visitLiteralPrimitive","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":408,"name":"visitLiteralPrimitive","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":409,"name":"literal","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"LiteralPrimitive","id":816}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":575,"character":29}]},{"id":416,"name":"visitLiteralString","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":417,"name":"visitLiteralString","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":418,"name":"literal","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"LiteralString","id":819}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":578,"character":26}]},{"id":401,"name":"visitPrefix","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":402,"name":"visitPrefix","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":403,"name":"prefix","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"PrefixNot","id":815}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":573,"character":19}]},{"id":371,"name":"visitValueConverter","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":372,"name":"visitValueConverter","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":373,"name":"converter","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ValueConverter"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":563,"character":27}]}],"groups":[{"title":"Methods","kind":2048,"children":[389,386,383,380,419,374,404,368,395,398,392,365,377,410,413,407,416,401,371]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":560,"character":34}],"extendedBy":[{"type":"reference","name":"MessageExpressionValidator","id":438}]},{"id":705,"name":"FluentEnsure","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Part of the fluent rule API. Enables targeting properties and objects with rules."},"typeParameter":[{"id":706,"name":"TObject","kind":131072,"kindString":"Type parameter","flags":{}}],"children":[{"id":709,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":710,"name":"new FluentEnsure","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":711,"name":"parsers","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Parsers","id":765}}],"type":{"type":"reference","name":"FluentEnsure","id":705}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":867,"character":38}]},{"id":707,"name":"parsers","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":863,"character":23}],"type":{"type":"intrinsic","name":"any"}},{"id":708,"name":"rules","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"Rules that have been defined using the fluent API."},"sources":[{"fileName":"aurelia-validation.d.ts","line":867,"character":13}],"type":{"type":"array","elementType":{"type":"array","elementType":{"type":"reference","name":"Rule","id":334,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"intrinsic","name":"any"}]}}}},{"id":721,"name":"assertInitialized","kind":2048,"kindString":"Method","flags":{"isPrivate":true,"isExported":true},"signatures":[{"id":722,"name":"assertInitialized","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"any"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":884,"character":33}]},{"id":712,"name":"ensure","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":713,"name":"ensure","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Target a property with validation rules."},"typeParameter":[{"id":714,"name":"TValue","kind":131072,"kindString":"Type parameter","flags":{}}],"parameters":[{"id":715,"name":"property","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The property to target. Can be the property name or a property accessor\nfunction.\n"},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"number"},{"type":"reference","name":"PropertyAccessor","id":797,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}]}}],"type":{"type":"reference","name":"FluentRules","id":641,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"intrinsic","name":"any"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":874,"character":14}]},{"id":716,"name":"ensureObject","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":717,"name":"ensureObject","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Targets an object with validation rules."},"type":{"type":"reference","name":"FluentRules","id":641,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"intrinsic","name":"any"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":878,"character":20}]},{"id":723,"name":"mergeRules","kind":2048,"kindString":"Method","flags":{"isPrivate":true,"isExported":true},"signatures":[{"id":724,"name":"mergeRules","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":725,"name":"fluentRules","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":726,"name":"propertyName","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"any"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":885,"character":26}]},{"id":718,"name":"on","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":719,"name":"on","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the rules to a class or object, making them discoverable by the StandardValidator."},"parameters":[{"id":720,"name":"target","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"A class or object.\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"this"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":883,"character":10}]}],"groups":[{"title":"Constructors","kind":512,"children":[709]},{"title":"Properties","kind":1024,"children":[707,708]},{"title":"Methods","kind":2048,"children":[721,712,716,723,718]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":862,"character":29}]},{"id":558,"name":"FluentRuleCustomizer","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Part of the fluent rule API. Enables customizing property rules."},"typeParameter":[{"id":559,"name":"TObject","kind":131072,"kindString":"Type parameter","flags":{}},{"id":560,"name":"TValue","kind":131072,"kindString":"Type parameter","flags":{}}],"children":[{"id":565,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":566,"name":"new FluentRuleCustomizer","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":567,"name":"property","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"RuleProperty","id":331}},{"id":568,"name":"condition","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reflection","declaration":{"id":569,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":570,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":571,"name":"value","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TValue"}},{"id":572,"name":"object","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"reference","name":"TObject","id":559}}],"type":{"type":"union","types":[{"type":"intrinsic","name":"boolean"},{"type":"reference","name":"Promise","typeArguments":[{"type":"intrinsic","name":"boolean"}]}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":681,"character":54}]}}},{"id":573,"name":"config","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"union","types":[{"type":"intrinsic","name":"any"},{"type":"intrinsic","name":"undefined"}]}},{"id":574,"name":"fluentEnsure","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"FluentEnsure","id":705,"typeArguments":[{"type":"typeParameter","name":"TObject"}]}},{"id":575,"name":"fluentRules","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"FluentRules","id":641,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}},{"id":576,"name":"parsers","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Parsers","id":765}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":558}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":680,"character":21}]},{"id":561,"name":"fluentEnsure","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":677,"character":28}],"type":{"type":"intrinsic","name":"any"}},{"id":562,"name":"fluentRules","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":678,"character":27}],"type":{"type":"intrinsic","name":"any"}},{"id":563,"name":"parsers","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":679,"character":23}],"type":{"type":"intrinsic","name":"any"}},{"id":564,"name":"rule","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":680,"character":20}],"type":{"type":"intrinsic","name":"any"}},{"id":603,"name":"rules","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"Rules that have been defined using the fluent API."},"sources":[{"fileName":"aurelia-validation.d.ts","line":719,"character":22}],"type":{"type":"array","elementType":{"type":"array","elementType":{"type":"reference","name":"Rule","id":334,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"intrinsic","name":"any"}]}}}},{"id":624,"name":"email","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":625,"name":"email","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"email\" rule to the property.\nnull, undefined and empty-string values are considered valid."},"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":753,"character":13}]},{"id":594,"name":"ensure","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":595,"name":"ensure","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Target a property with validation rules."},"typeParameter":[{"id":596,"name":"TValue2","kind":131072,"kindString":"Type parameter","flags":{}}],"parameters":[{"id":597,"name":"subject","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"reflection","declaration":{"id":598,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":599,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":600,"name":"model","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TObject"}}],"type":{"type":"typeParameter","name":"TValue2"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":711,"character":41}]}}]}}],"type":{"type":"reference","name":"FluentRules","id":641,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"intrinsic","name":"any"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":711,"character":14}]},{"id":601,"name":"ensureObject","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":602,"name":"ensureObject","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Targets an object with validation rules."},"type":{"type":"reference","name":"FluentRules","id":641,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"intrinsic","name":"any"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":715,"character":20}]},{"id":638,"name":"equals","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":639,"name":"equals","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"equals\" validation rule to the property.\nnull, undefined and empty-string values are considered valid."},"parameters":[{"id":640,"name":"expectedValue","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TValue"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":778,"character":14}]},{"id":621,"name":"matches","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":622,"name":"matches","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"matches\" rule to the property.\nValue must match the specified regular expression.\nnull, undefined and empty-string values are considered valid."},"parameters":[{"id":623,"name":"regex","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"RegExp"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":748,"character":15}]},{"id":635,"name":"maxItems","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":636,"name":"maxItems","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"maxItems\" ARRAY validation rule to the property.\nnull and undefined values are considered valid."},"parameters":[{"id":637,"name":"count","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":773,"character":16}]},{"id":629,"name":"maxLength","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":630,"name":"maxLength","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"maxLength\" STRING validation rule to the property.\nnull, undefined and empty-string values are considered valid."},"parameters":[{"id":631,"name":"length","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":763,"character":17}]},{"id":632,"name":"minItems","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":633,"name":"minItems","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"minItems\" ARRAY validation rule to the property.\nnull and undefined values are considered valid."},"parameters":[{"id":634,"name":"count","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":768,"character":16}]},{"id":626,"name":"minLength","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":627,"name":"minLength","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"minLength\" STRING validation rule to the property.\nnull, undefined and empty-string values are considered valid."},"parameters":[{"id":628,"name":"length","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":758,"character":17}]},{"id":604,"name":"on","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":605,"name":"on","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the rules to a class or object, making them discoverable by the StandardValidator."},"parameters":[{"id":606,"name":"target","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"A class or object.\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"reference","name":"FluentEnsure","id":705,"typeArguments":[{"type":"typeParameter","name":"TObject"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":724,"character":10}]},{"id":619,"name":"required","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":620,"name":"required","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"required\" rule to the property.\nThe value cannot be null, undefined or whitespace."},"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":742,"character":16}]},{"id":607,"name":"satisfies","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":608,"name":"satisfies","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies an ad-hoc rule function to the ensured property or object."},"parameters":[{"id":609,"name":"condition","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The function to validate the rule.\nWill be called with two arguments, the property value and the object.\nShould return a boolean or a Promise that resolves to a boolean.\n"},"type":{"type":"reflection","declaration":{"id":610,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":611,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":612,"name":"value","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TValue"}},{"id":613,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TObject"}}],"type":{"type":"union","types":[{"type":"intrinsic","name":"boolean"},{"type":"reference","name":"Promise","typeArguments":[{"type":"intrinsic","name":"boolean"}]}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":731,"character":28}]}}},{"id":614,"name":"config","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"intrinsic","name":"undefined"},{"type":"intrinsic","name":"object"}]}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":731,"character":17}]},{"id":615,"name":"satisfiesRule","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":616,"name":"satisfiesRule","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies a rule by name."},"parameters":[{"id":617,"name":"name","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The name of the custom or standard rule."},"type":{"type":"intrinsic","name":"string"}},{"id":618,"name":"args","kind":32768,"kindString":"Parameter","flags":{"isRest":true},"comment":{"text":"The rule's arguments.\n"},"type":{"type":"array","elementType":{"type":"intrinsic","name":"any"}}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":737,"character":21}]},{"id":591,"name":"tag","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":592,"name":"tag","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Tags the rule instance, enabling the rule to be found easily\nusing ValidationRules.taggedRules(rules, tag)"},"parameters":[{"id":593,"name":"tag","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"intrinsic","name":"this"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":706,"character":11}]},{"id":577,"name":"then","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":578,"name":"then","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Validate subsequent rules after previously declared rules have\nbeen validated successfully. Use to postpone validation of costly\nrules until less expensive rules pass validation."},"type":{"type":"intrinsic","name":"this"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":687,"character":12}]},{"id":585,"name":"when","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":586,"name":"when","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Specifies a condition that must be met before attempting to validate the rule."},"parameters":[{"id":587,"name":"condition","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"A function that accepts the object as a parameter and returns true\nor false whether the rule should be evaluated.\n"},"type":{"type":"reflection","declaration":{"id":588,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":589,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":590,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TObject"}}],"type":{"type":"intrinsic","name":"boolean"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":701,"character":23}]}}}],"type":{"type":"intrinsic","name":"this"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":701,"character":12}]},{"id":582,"name":"withMessage","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":583,"name":"withMessage","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Specifies rule's validation message."},"parameters":[{"id":584,"name":"message","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"intrinsic","name":"this"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":695,"character":19}]},{"id":579,"name":"withMessageKey","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":580,"name":"withMessageKey","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Specifies the key to use when looking up the rule's validation message."},"parameters":[{"id":581,"name":"key","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"intrinsic","name":"this"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":691,"character":22}]}],"groups":[{"title":"Constructors","kind":512,"children":[565]},{"title":"Properties","kind":1024,"children":[561,562,563,564,603]},{"title":"Methods","kind":2048,"children":[624,594,601,638,621,635,629,632,626,604,619,607,615,591,577,585,582,579]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":676,"character":37}]},{"id":641,"name":"FluentRules","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Part of the fluent rule API. Enables applying rules to properties and objects."},"typeParameter":[{"id":642,"name":"TObject","kind":131072,"kindString":"Type parameter","flags":{}},{"id":643,"name":"TValue","kind":131072,"kindString":"Type parameter","flags":{}}],"children":[{"id":663,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":664,"name":"new FluentRules","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":665,"name":"fluentEnsure","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"FluentEnsure","id":705,"typeArguments":[{"type":"typeParameter","name":"TObject"}]}},{"id":666,"name":"parsers","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Parsers","id":765}},{"id":667,"name":"property","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"RuleProperty","id":331}}],"type":{"type":"reference","name":"FluentRules","id":641}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":798,"character":25}]},{"id":644,"name":"fluentEnsure","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":784,"character":28}],"type":{"type":"intrinsic","name":"any"}},{"id":645,"name":"parsers","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":785,"character":23}],"type":{"type":"intrinsic","name":"any"}},{"id":646,"name":"property","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":786,"character":24}],"type":{"type":"intrinsic","name":"any"}},{"id":662,"name":"sequence","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"Current rule sequence number. Used to postpone evaluation of rules until rules\nwith lower sequence number have successfully validated. The \"then\" fluent API method\nmanages this property, there's usually no need to set it directly."},"sources":[{"fileName":"aurelia-validation.d.ts","line":798,"character":16}],"type":{"type":"intrinsic","name":"number"}},{"id":647,"name":"customRules","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":787,"character":26}],"type":{"type":"reflection","declaration":{"id":648,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"indexSignature":{"id":649,"name":"__index","kind":8192,"kindString":"Index signature","flags":{},"parameters":[{"id":650,"name":"name","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"reflection","declaration":{"id":651,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"children":[{"id":658,"name":"argsToConfig","kind":32,"kindString":"Variable","flags":{"isOptional":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":790,"character":28}],"type":{"type":"union","types":[{"type":"intrinsic","name":"undefined"},{"type":"reflection","declaration":{"id":659,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":660,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":661,"name":"args","kind":32768,"kindString":"Parameter","flags":{"isRest":true},"type":{"type":"array","elementType":{"type":"intrinsic","name":"any"}}}],"type":{"type":"intrinsic","name":"any"}}]}}]}},{"id":652,"name":"condition","kind":32,"kindString":"Variable","flags":{},"sources":[{"fileName":"aurelia-validation.d.ts","line":789,"character":25}],"type":{"type":"reflection","declaration":{"id":653,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":654,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":655,"name":"value","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":656,"name":"object","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"any"}},{"id":657,"name":"fluentArgs","kind":32768,"kindString":"Parameter","flags":{"isRest":true},"type":{"type":"array","elementType":{"type":"intrinsic","name":"any"}}}],"type":{"type":"union","types":[{"type":"intrinsic","name":"boolean"},{"type":"reference","name":"Promise","typeArguments":[{"type":"intrinsic","name":"boolean"}]}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":789,"character":26}]}}}],"groups":[{"title":"Variables","kind":32,"children":[658,652]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":788,"character":27}]}}},"sources":[{"fileName":"aurelia-validation.d.ts","line":787,"character":27}]}}},{"id":668,"name":"displayName","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":669,"name":"displayName","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Sets the display name of the ensured property."},"parameters":[{"id":670,"name":"name","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"reference","name":"ValidationDisplayNameAccessor","id":806},{"type":"intrinsic","name":"null"}]}}],"type":{"type":"intrinsic","name":"this"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":803,"character":19}]},{"id":688,"name":"email","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":689,"name":"email","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"email\" rule to the property.\nnull, undefined and empty-string values are considered valid."},"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":832,"character":13}]},{"id":702,"name":"equals","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":703,"name":"equals","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"equals\" validation rule to the property.\nnull and undefined values are considered valid."},"parameters":[{"id":704,"name":"expectedValue","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TValue"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":857,"character":14}]},{"id":685,"name":"matches","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":686,"name":"matches","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"matches\" rule to the property.\nValue must match the specified regular expression.\nnull, undefined and empty-string values are considered valid."},"parameters":[{"id":687,"name":"regex","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"RegExp"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":827,"character":15}]},{"id":699,"name":"maxItems","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":700,"name":"maxItems","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"maxItems\" ARRAY validation rule to the property.\nnull and undefined values are considered valid."},"parameters":[{"id":701,"name":"count","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":852,"character":16}]},{"id":693,"name":"maxLength","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":694,"name":"maxLength","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"maxLength\" STRING validation rule to the property.\nnull, undefined and empty-string values are considered valid."},"parameters":[{"id":695,"name":"length","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":842,"character":17}]},{"id":696,"name":"minItems","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":697,"name":"minItems","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"minItems\" ARRAY validation rule to the property.\nnull and undefined values are considered valid."},"parameters":[{"id":698,"name":"count","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":847,"character":16}]},{"id":690,"name":"minLength","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":691,"name":"minLength","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"minLength\" STRING validation rule to the property.\nnull, undefined and empty-string values are considered valid."},"parameters":[{"id":692,"name":"length","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":837,"character":17}]},{"id":683,"name":"required","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":684,"name":"required","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"required\" rule to the property.\nThe value cannot be null, undefined or whitespace."},"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":821,"character":16}]},{"id":671,"name":"satisfies","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":672,"name":"satisfies","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies an ad-hoc rule function to the ensured property or object."},"parameters":[{"id":673,"name":"condition","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The function to validate the rule.\nWill be called with two arguments, the property value and the object.\nShould return a boolean or a Promise that resolves to a boolean.\n"},"type":{"type":"reflection","declaration":{"id":674,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":675,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":676,"name":"value","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TValue"}},{"id":677,"name":"object","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"reference","name":"TObject","id":642}}],"type":{"type":"union","types":[{"type":"intrinsic","name":"boolean"},{"type":"reference","name":"Promise","typeArguments":[{"type":"intrinsic","name":"boolean"}]}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":810,"character":28}]}}},{"id":678,"name":"config","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"intrinsic","name":"undefined"},{"type":"intrinsic","name":"object"}]}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":810,"character":17}]},{"id":679,"name":"satisfiesRule","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":680,"name":"satisfiesRule","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies a rule by name."},"parameters":[{"id":681,"name":"name","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The name of the custom or standard rule."},"type":{"type":"intrinsic","name":"string"}},{"id":682,"name":"args","kind":32768,"kindString":"Parameter","flags":{"isRest":true},"comment":{"text":"The rule's arguments.\n"},"type":{"type":"array","elementType":{"type":"intrinsic","name":"any"}}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":558,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":816,"character":21}]}],"groups":[{"title":"Constructors","kind":512,"children":[663]},{"title":"Properties","kind":1024,"children":[644,645,646,662,647]},{"title":"Methods","kind":2048,"children":[668,688,702,685,699,693,696,690,683,671,679]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":783,"character":28}]},{"id":438,"name":"MessageExpressionValidator","kind":128,"kindString":"Class","flags":{"isExported":true},"children":[{"id":444,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":445,"name":"new MessageExpressionValidator","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":446,"name":"originalMessage","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"reference","name":"MessageExpressionValidator","id":438}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":597,"character":79}]},{"id":439,"name":"originalMessage","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":596,"character":31}],"type":{"type":"intrinsic","name":"any"}},{"id":471,"name":"visitAccessKeyed","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":472,"name":"visitAccessKeyed","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":473,"name":"access","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"AccessKeyed"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitAccessKeyed","id":389}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":569,"character":24}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitAccessKeyed","id":389}},{"id":468,"name":"visitAccessMember","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":469,"name":"visitAccessMember","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":470,"name":"access","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"AccessMember"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitAccessMember","id":386}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":568,"character":25}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitAccessMember","id":386}},{"id":447,"name":"visitAccessScope","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":448,"name":"visitAccessScope","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":449,"name":"access","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"AccessScope"}}],"type":{"type":"intrinsic","name":"void"},"overwrites":{"type":"reference","name":"ExpressionVisitor.visitAccessScope","id":383}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":599,"character":24}],"overwrites":{"type":"reference","name":"ExpressionVisitor.visitAccessScope","id":383}},{"id":465,"name":"visitAccessThis","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":466,"name":"visitAccessThis","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":467,"name":"access","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"AccessThis","id":811}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitAccessThis","id":380}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":566,"character":23}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitAccessThis","id":380}},{"id":459,"name":"visitAssign","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":460,"name":"visitAssign","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":461,"name":"assign","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Assign","id":810}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitAssign","id":374}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":564,"character":19}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitAssign","id":374}},{"id":486,"name":"visitBinary","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":487,"name":"visitBinary","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":488,"name":"binary","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Binary"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitBinary","id":404}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":574,"character":19}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitBinary","id":404}},{"id":453,"name":"visitBindingBehavior","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":454,"name":"visitBindingBehavior","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":455,"name":"behavior","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"BindingBehavior"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitBindingBehavior","id":368}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":562,"character":28}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitBindingBehavior","id":368}},{"id":477,"name":"visitCallFunction","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":478,"name":"visitCallFunction","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":479,"name":"call","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"CallFunction","id":814}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitCallFunction","id":395}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":571,"character":25}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitCallFunction","id":395}},{"id":480,"name":"visitCallMember","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":481,"name":"visitCallMember","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":482,"name":"call","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"CallMember"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitCallMember","id":398}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":572,"character":23}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitCallMember","id":398}},{"id":474,"name":"visitCallScope","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":475,"name":"visitCallScope","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":476,"name":"call","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"CallScope","id":813}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitCallScope","id":392}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":570,"character":22}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitCallScope","id":392}},{"id":450,"name":"visitChain","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":451,"name":"visitChain","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":452,"name":"chain","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Chain","id":809}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitChain","id":365}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":561,"character":18}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitChain","id":365}},{"id":462,"name":"visitConditional","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":463,"name":"visitConditional","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":464,"name":"conditional","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Conditional"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitConditional","id":377}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":565,"character":24}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitConditional","id":377}},{"id":492,"name":"visitLiteralArray","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":493,"name":"visitLiteralArray","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":494,"name":"literal","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"LiteralArray","id":817}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitLiteralArray","id":410}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":576,"character":25}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitLiteralArray","id":410}},{"id":495,"name":"visitLiteralObject","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":496,"name":"visitLiteralObject","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":497,"name":"literal","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"LiteralObject","id":818}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitLiteralObject","id":413}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":577,"character":26}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitLiteralObject","id":413}},{"id":489,"name":"visitLiteralPrimitive","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":490,"name":"visitLiteralPrimitive","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":491,"name":"literal","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"LiteralPrimitive","id":816}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitLiteralPrimitive","id":407}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":575,"character":29}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitLiteralPrimitive","id":407}},{"id":498,"name":"visitLiteralString","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":499,"name":"visitLiteralString","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":500,"name":"literal","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"LiteralString","id":819}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitLiteralString","id":416}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":578,"character":26}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitLiteralString","id":416}},{"id":483,"name":"visitPrefix","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":484,"name":"visitPrefix","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":485,"name":"prefix","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"PrefixNot","id":815}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitPrefix","id":401}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":573,"character":19}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitPrefix","id":401}},{"id":456,"name":"visitValueConverter","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":457,"name":"visitValueConverter","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":458,"name":"converter","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ValueConverter"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitValueConverter","id":371}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":563,"character":27}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitValueConverter","id":371}},{"id":440,"name":"validate","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":441,"name":"validate","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":442,"name":"expression","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Expression"}},{"id":443,"name":"originalMessage","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":597,"character":23}]}],"groups":[{"title":"Constructors","kind":512,"children":[444]},{"title":"Properties","kind":1024,"children":[439]},{"title":"Methods","kind":2048,"children":[471,468,447,465,459,486,453,477,480,474,450,462,492,495,489,498,483,456,440]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":595,"character":43}],"extendedTypes":[{"type":"reference","name":"ExpressionVisitor","id":364}]},{"id":27,"name":"PropertyAccessorParser","kind":128,"kindString":"Class","flags":{"isExported":true},"children":[{"id":30,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":31,"name":"new PropertyAccessorParser","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":32,"name":"parser","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Parser"}}],"type":{"type":"reference","name":"PropertyAccessorParser","id":27}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":91,"character":41}]},{"id":28,"name":"parser","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":90,"character":22}],"type":{"type":"intrinsic","name":"any"}},{"id":29,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":91,"character":21}],"type":{"type":"array","elementType":{"type":"reference","name":"Parser"}}},{"id":33,"name":"parse","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":34,"name":"parse","kind":4096,"kindString":"Call signature","flags":{},"typeParameter":[{"id":35,"name":"TObject","kind":131072,"kindString":"Type parameter","flags":{}},{"id":36,"name":"TValue","kind":131072,"kindString":"Type parameter","flags":{}}],"parameters":[{"id":37,"name":"property","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"number"},{"type":"reference","name":"PropertyAccessor","id":797,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}]}}],"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"number"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":93,"character":13}]}],"groups":[{"title":"Constructors","kind":512,"children":[30]},{"title":"Properties","kind":1024,"children":[28,29]},{"title":"Methods","kind":2048,"children":[33]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":89,"character":39}]},{"id":352,"name":"Rules","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Sets, unsets and retrieves rules on an object or constructor function."},"children":[{"id":353,"name":"key","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isPrivate":true,"isExported":true},"comment":{"shortText":"The name of the property that stores the rules."},"sources":[{"fileName":"aurelia-validation.d.ts","line":534,"character":26}],"type":{"type":"intrinsic","name":"any"}},{"id":361,"name":"get","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":362,"name":"get","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Retrieves the target's rules."},"parameters":[{"id":363,"name":"target","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"union","types":[{"type":"array","elementType":{"type":"array","elementType":{"type":"reference","name":"Rule","id":334,"typeArguments":[{"type":"intrinsic","name":"any"},{"type":"intrinsic","name":"any"}]}}},{"type":"intrinsic","name":"null"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":546,"character":18}]},{"id":354,"name":"set","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":355,"name":"set","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the rules to a target."},"parameters":[{"id":356,"name":"target","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":357,"name":"rules","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"array","elementType":{"type":"array","elementType":{"type":"reference","name":"Rule","id":334,"typeArguments":[{"type":"intrinsic","name":"any"},{"type":"intrinsic","name":"any"}]}}}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":538,"character":18}]},{"id":358,"name":"unset","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":359,"name":"unset","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Removes rules from a target."},"parameters":[{"id":360,"name":"target","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":542,"character":20}]}],"groups":[{"title":"Properties","kind":1024,"children":[353]},{"title":"Methods","kind":2048,"children":[361,354,358]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":530,"character":22}]},{"id":519,"name":"StandardValidator","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Validates.\nResponsible for validating objects and properties."},"children":[{"id":524,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":525,"name":"new StandardValidator","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":526,"name":"messageProvider","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ValidationMessageProvider","id":504}},{"id":527,"name":"resources","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ViewResources"}}],"type":{"type":"reference","name":"StandardValidator","id":519}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":643,"character":31}]},{"id":523,"name":"getDisplayName","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":643,"character":30}],"type":{"type":"intrinsic","name":"any"}},{"id":522,"name":"lookupFunctions","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":642,"character":31}],"type":{"type":"intrinsic","name":"any"}},{"id":521,"name":"messageProvider","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":641,"character":31}],"type":{"type":"intrinsic","name":"any"}},{"id":520,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":640,"character":21}],"type":{"type":"array","elementType":{"type":"union","types":[{"type":"reference","name":"ViewResources"},{"type":"reference","name":"ValidationMessageProvider","id":504}]}}},{"id":541,"name":"getMessage","kind":2048,"kindString":"Method","flags":{"isPrivate":true,"isExported":true},"signatures":[{"id":542,"name":"getMessage","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":543,"name":"rule","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":544,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":545,"name":"value","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"any"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":666,"character":26}]},{"id":537,"name":"ruleExists","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":538,"name":"ruleExists","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Determines whether a rule exists in a set of rules.","tags":[{"tag":"parem","text":"rule The rule to find.\n"}]},"parameters":[{"id":539,"name":"rules","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The rules to search."},"type":{"type":"array","elementType":{"type":"array","elementType":{"type":"reference","name":"Rule","id":334,"typeArguments":[{"type":"intrinsic","name":"any"},{"type":"intrinsic","name":"any"}]}}}},{"id":540,"name":"rule","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Rule","id":334,"typeArguments":[{"type":"intrinsic","name":"any"},{"type":"intrinsic","name":"any"}]}}],"type":{"type":"intrinsic","name":"boolean"},"overwrites":{"type":"reference","name":"Validator.ruleExists","id":48}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":665,"character":18}],"overwrites":{"type":"reference","name":"Validator.ruleExists","id":48}},{"id":553,"name":"validate","kind":2048,"kindString":"Method","flags":{"isPrivate":true,"isExported":true},"signatures":[{"id":554,"name":"validate","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":555,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":556,"name":"propertyName","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":557,"name":"rules","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"any"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":668,"character":24}]},{"id":533,"name":"validateObject","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":534,"name":"validateObject","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Validates all rules for specified object and it's properties."},"parameters":[{"id":535,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The object to validate."},"type":{"type":"intrinsic","name":"any"}},{"id":536,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"comment":{"text":"Optional. If unspecified, the rules will be looked up using the metadata\nfor the object created by ValidationRules....on(class/object)\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"reference","name":"Promise","typeArguments":[{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}]},"overwrites":{"type":"reference","name":"Validator.validateObject","id":44}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":659,"character":22}],"overwrites":{"type":"reference","name":"Validator.validateObject","id":44}},{"id":528,"name":"validateProperty","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":529,"name":"validateProperty","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Validates the specified property."},"parameters":[{"id":530,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The object to validate."},"type":{"type":"intrinsic","name":"any"}},{"id":531,"name":"propertyName","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The name of the property to validate."},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"number"}]}},{"id":532,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"comment":{"text":"Optional. If unspecified, the rules will be looked up using the metadata\nfor the object created by ValidationRules....on(class/object)\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"reference","name":"Promise","typeArguments":[{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}]},"overwrites":{"type":"reference","name":"Validator.validateProperty","id":39}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":652,"character":24}],"overwrites":{"type":"reference","name":"Validator.validateProperty","id":39}},{"id":546,"name":"validateRuleSequence","kind":2048,"kindString":"Method","flags":{"isPrivate":true,"isExported":true},"signatures":[{"id":547,"name":"validateRuleSequence","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":548,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":549,"name":"propertyName","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":550,"name":"ruleSequence","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":551,"name":"sequence","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":552,"name":"results","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"any"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":667,"character":36}]}],"groups":[{"title":"Constructors","kind":512,"children":[524]},{"title":"Properties","kind":1024,"children":[523,522,521,520]},{"title":"Methods","kind":2048,"children":[541,537,553,533,528,546]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":639,"character":34}],"extendedTypes":[{"type":"reference","name":"Validator","id":38}]},{"id":191,"name":"ValidateBindingBehavior","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Binding behavior. Indicates the bound property should be validated\nwhen the validate trigger specified by the associated controller's\nvalidateTrigger property occurs."},"children":[{"id":196,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":197,"name":"new ValidateBindingBehavior","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":198,"name":"taskQueue","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"TaskQueue"}}],"type":{"type":"reference","name":"ValidateBindingBehavior","id":191},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":176}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":389,"character":26}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":176}},{"id":192,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":405,"character":21}],"type":{"type":"array","elementType":{"type":"reference","name":"TaskQueue"}}},{"id":199,"name":"bind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":200,"name":"bind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":201,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":202,"name":"source","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":203,"name":"rulesOrController","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"reference","name":"ValidationController","id":81},{"type":"intrinsic","name":"any"}]}},{"id":204,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":182}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":392,"character":12}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":182}},{"id":193,"name":"getValidateTrigger","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":194,"name":"getValidateTrigger","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":195,"name":"controller","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ValidationController","id":81}}],"type":{"type":"reference","name":"validateTrigger","id":52},"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":179}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":406,"character":26}],"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":179}},{"id":205,"name":"unbind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":206,"name":"unbind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":207,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":188}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":393,"character":14}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":188}}],"groups":[{"title":"Constructors","kind":512,"children":[196]},{"title":"Properties","kind":1024,"children":[192]},{"title":"Methods","kind":2048,"children":[199,193,205]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":404,"character":40}],"extendedTypes":[{"type":"reference","name":"ValidateBindingBehaviorBase","id":174}]},{"id":174,"name":"ValidateBindingBehaviorBase","kind":128,"kindString":"Class","flags":{"isExported":true,"isAbstract":true},"comment":{"shortText":"Binding behavior. Indicates the bound property should be validated."},"children":[{"id":176,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":177,"name":"new ValidateBindingBehaviorBase","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":178,"name":"taskQueue","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"TaskQueue"}}],"type":{"type":"reference","name":"ValidateBindingBehaviorBase","id":174}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":389,"character":26}]},{"id":175,"name":"taskQueue","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":389,"character":25}],"type":{"type":"intrinsic","name":"any"}},{"id":182,"name":"bind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":183,"name":"bind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":184,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":185,"name":"source","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":186,"name":"rulesOrController","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"reference","name":"ValidationController","id":81},{"type":"intrinsic","name":"any"}]}},{"id":187,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":392,"character":12}]},{"id":179,"name":"getValidateTrigger","kind":2048,"kindString":"Method","flags":{"isExported":true,"isProtected":true,"isAbstract":true},"signatures":[{"id":180,"name":"getValidateTrigger","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":181,"name":"controller","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ValidationController","id":81}}],"type":{"type":"reference","name":"validateTrigger","id":52}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":391,"character":45}]},{"id":188,"name":"unbind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":189,"name":"unbind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":190,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":393,"character":14}]}],"groups":[{"title":"Constructors","kind":512,"children":[176]},{"title":"Properties","kind":1024,"children":[175]},{"title":"Methods","kind":2048,"children":[182,179,188]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":388,"character":53}],"extendedBy":[{"type":"reference","name":"ValidateBindingBehavior","id":191},{"type":"reference","name":"ValidateManuallyBindingBehavior","id":208},{"type":"reference","name":"ValidateOnBlurBindingBehavior","id":224},{"type":"reference","name":"ValidateOnChangeBindingBehavior","id":240},{"type":"reference","name":"ValidateOnChangeOrBlurBindingBehavior","id":256}]},{"id":68,"name":"ValidateEvent","kind":128,"kindString":"Class","flags":{"isExported":true},"children":[{"id":74,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":75,"name":"new ValidateEvent","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":76,"name":"type","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"union","types":[{"type":"stringLiteral","value":"validate"},{"type":"stringLiteral","value":"reset"}]}},{"id":77,"name":"errors","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}},{"id":78,"name":"results","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}},{"id":79,"name":"instruction","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"union","types":[{"type":"reference","name":"ValidateInstruction","id":19},{"type":"intrinsic","name":"null"}]}},{"id":80,"name":"controllerValidateResult","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"union","types":[{"type":"reference","name":"ControllerValidateResult","id":23},{"type":"intrinsic","name":"null"}]}}],"type":{"type":"reference","name":"ValidateEvent","id":68}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":220,"character":75}]},{"id":73,"name":"controllerValidateResult","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"In events with type === \"validate\", this property will contain the result\nof validating the instruction (see \"instruction\" property). Use the controllerValidateResult\nto access the validate results specific to the call to \"validate\"\n(as opposed to using the \"results\" and \"errors\" properties to access the controller's entire\nset of results/errors)."},"sources":[{"fileName":"aurelia-validation.d.ts","line":220,"character":41}],"type":{"type":"union","types":[{"type":"reference","name":"ControllerValidateResult","id":23},{"type":"intrinsic","name":"null"}]}},{"id":70,"name":"errors","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The controller's current array of errors. For an array containing both\nfailed rules and passed rules, use the \"results\" property."},"sources":[{"fileName":"aurelia-validation.d.ts","line":201,"character":23}],"type":{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}},{"id":72,"name":"instruction","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The instruction passed to the \"validate\" or \"reset\" event. Will be null when\nthe controller's validate/reset method was called with no instruction argument."},"sources":[{"fileName":"aurelia-validation.d.ts","line":212,"character":28}],"type":{"type":"union","types":[{"type":"reference","name":"ValidateInstruction","id":19},{"type":"intrinsic","name":"null"}]}},{"id":71,"name":"results","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The controller's current array of validate results. This\nincludes both passed rules and failed rules. For an array of only failed rules,\nuse the \"errors\" property."},"sources":[{"fileName":"aurelia-validation.d.ts","line":207,"character":24}],"type":{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}},{"id":69,"name":"type","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The type of validate event. Either \"validate\" or \"reset\"."},"sources":[{"fileName":"aurelia-validation.d.ts","line":196,"character":21}],"type":{"type":"union","types":[{"type":"stringLiteral","value":"validate"},{"type":"stringLiteral","value":"reset"}]}}],"groups":[{"title":"Constructors","kind":512,"children":[74]},{"title":"Properties","kind":1024,"children":[73,70,72,71,69]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":192,"character":30}]},{"id":208,"name":"ValidateManuallyBindingBehavior","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Binding behavior. Indicates the bound property will be validated\nmanually, by calling controller.validate(). No automatic validation\ntriggered by data-entry or blur will occur."},"children":[{"id":212,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":213,"name":"new ValidateManuallyBindingBehavior","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":214,"name":"taskQueue","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"TaskQueue"}}],"type":{"type":"reference","name":"ValidateManuallyBindingBehavior","id":208},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":176}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":389,"character":26}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":176}},{"id":209,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":414,"character":21}],"type":{"type":"array","elementType":{"type":"reference","name":"TaskQueue"}}},{"id":215,"name":"bind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":216,"name":"bind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":217,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":218,"name":"source","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":219,"name":"rulesOrController","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"reference","name":"ValidationController","id":81},{"type":"intrinsic","name":"any"}]}},{"id":220,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":182}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":392,"character":12}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":182}},{"id":210,"name":"getValidateTrigger","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":211,"name":"getValidateTrigger","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"reference","name":"validateTrigger","id":52},"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":179}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":415,"character":26}],"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":179}},{"id":221,"name":"unbind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":222,"name":"unbind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":223,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":188}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":393,"character":14}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":188}}],"groups":[{"title":"Constructors","kind":512,"children":[212]},{"title":"Properties","kind":1024,"children":[209]},{"title":"Methods","kind":2048,"children":[215,210,221]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":413,"character":48}],"extendedTypes":[{"type":"reference","name":"ValidateBindingBehaviorBase","id":174}]},{"id":224,"name":"ValidateOnBlurBindingBehavior","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Binding behavior. Indicates the bound property should be validated\nwhen the associated element blurs."},"children":[{"id":228,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":229,"name":"new ValidateOnBlurBindingBehavior","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":230,"name":"taskQueue","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"TaskQueue"}}],"type":{"type":"reference","name":"ValidateOnBlurBindingBehavior","id":224},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":176}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":389,"character":26}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":176}},{"id":225,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":422,"character":21}],"type":{"type":"array","elementType":{"type":"reference","name":"TaskQueue"}}},{"id":231,"name":"bind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":232,"name":"bind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":233,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":234,"name":"source","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":235,"name":"rulesOrController","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"reference","name":"ValidationController","id":81},{"type":"intrinsic","name":"any"}]}},{"id":236,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":182}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":392,"character":12}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":182}},{"id":226,"name":"getValidateTrigger","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":227,"name":"getValidateTrigger","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"reference","name":"validateTrigger","id":52},"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":179}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":423,"character":26}],"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":179}},{"id":237,"name":"unbind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":238,"name":"unbind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":239,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":188}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":393,"character":14}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":188}}],"groups":[{"title":"Constructors","kind":512,"children":[228]},{"title":"Properties","kind":1024,"children":[225]},{"title":"Methods","kind":2048,"children":[231,226,237]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":421,"character":46}],"extendedTypes":[{"type":"reference","name":"ValidateBindingBehaviorBase","id":174}]},{"id":240,"name":"ValidateOnChangeBindingBehavior","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Binding behavior. Indicates the bound property should be validated\nwhen the associated element is changed by the user, causing a change\nto the model."},"children":[{"id":244,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":245,"name":"new ValidateOnChangeBindingBehavior","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":246,"name":"taskQueue","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"TaskQueue"}}],"type":{"type":"reference","name":"ValidateOnChangeBindingBehavior","id":240},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":176}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":389,"character":26}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":176}},{"id":241,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":431,"character":21}],"type":{"type":"array","elementType":{"type":"reference","name":"TaskQueue"}}},{"id":247,"name":"bind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":248,"name":"bind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":249,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":250,"name":"source","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":251,"name":"rulesOrController","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"reference","name":"ValidationController","id":81},{"type":"intrinsic","name":"any"}]}},{"id":252,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":182}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":392,"character":12}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":182}},{"id":242,"name":"getValidateTrigger","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":243,"name":"getValidateTrigger","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"reference","name":"validateTrigger","id":52},"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":179}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":432,"character":26}],"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":179}},{"id":253,"name":"unbind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":254,"name":"unbind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":255,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":188}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":393,"character":14}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":188}}],"groups":[{"title":"Constructors","kind":512,"children":[244]},{"title":"Properties","kind":1024,"children":[241]},{"title":"Methods","kind":2048,"children":[247,242,253]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":430,"character":48}],"extendedTypes":[{"type":"reference","name":"ValidateBindingBehaviorBase","id":174}]},{"id":256,"name":"ValidateOnChangeOrBlurBindingBehavior","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Binding behavior. Indicates the bound property should be validated\nwhen the associated element blurs or is changed by the user, causing\na change to the model."},"children":[{"id":260,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":261,"name":"new ValidateOnChangeOrBlurBindingBehavior","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":262,"name":"taskQueue","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"TaskQueue"}}],"type":{"type":"reference","name":"ValidateOnChangeOrBlurBindingBehavior","id":256},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":176}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":389,"character":26}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":176}},{"id":257,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":440,"character":21}],"type":{"type":"array","elementType":{"type":"reference","name":"TaskQueue"}}},{"id":263,"name":"bind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":264,"name":"bind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":265,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":266,"name":"source","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":267,"name":"rulesOrController","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"reference","name":"ValidationController","id":81},{"type":"intrinsic","name":"any"}]}},{"id":268,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":182}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":392,"character":12}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":182}},{"id":258,"name":"getValidateTrigger","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":259,"name":"getValidateTrigger","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"reference","name":"validateTrigger","id":52},"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":179}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":441,"character":26}],"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":179}},{"id":269,"name":"unbind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":270,"name":"unbind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":271,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":188}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":393,"character":14}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":188}}],"groups":[{"title":"Constructors","kind":512,"children":[260]},{"title":"Properties","kind":1024,"children":[257]},{"title":"Methods","kind":2048,"children":[263,258,269]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":439,"character":54}],"extendedTypes":[{"type":"reference","name":"ValidateBindingBehaviorBase","id":174}]},{"id":2,"name":"ValidateResult","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"The result of validating an individual validation rule."},"children":[{"id":10,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"comment":{},"signatures":[{"id":11,"name":"new ValidateResult","kind":16384,"kindString":"Constructor signature","flags":{},"comment":{},"parameters":[{"id":12,"name":"rule","kind":32768,"kindString":"Parameter","flags":{},"comment":{"shortText":"The rule associated with the result. Validator implementation specific."},"type":{"type":"intrinsic","name":"any"}},{"id":13,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"comment":{"shortText":"The object that was validated."},"type":{"type":"intrinsic","name":"any"}},{"id":14,"name":"propertyName","kind":32768,"kindString":"Parameter","flags":{},"comment":{"shortText":"The name of the property that was validated."},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"number"},{"type":"intrinsic","name":"null"}]}},{"id":15,"name":"valid","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"boolean"}},{"id":16,"name":"message","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"null"}]}}],"type":{"type":"reference","name":"ValidateResult","id":2}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":19,"character":19}]},{"id":9,"name":"id","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"A number that uniquely identifies the result instance."},"sources":[{"fileName":"aurelia-validation.d.ts","line":19,"character":10}],"type":{"type":"intrinsic","name":"number"}},{"id":7,"name":"message","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":14,"character":15}],"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"null"}]}},{"id":4,"name":"object","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":11,"character":14}],"type":{"type":"intrinsic","name":"any"}},{"id":5,"name":"propertyName","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":12,"character":20}],"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"number"},{"type":"intrinsic","name":"null"}]}},{"id":3,"name":"rule","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":10,"character":12}],"type":{"type":"intrinsic","name":"any"}},{"id":6,"name":"valid","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":13,"character":13}],"type":{"type":"intrinsic","name":"boolean"}},{"id":8,"name":"nextId","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":15,"character":29}],"type":{"type":"intrinsic","name":"any"}},{"id":17,"name":"toString","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":18,"name":"toString","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"null"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":27,"character":16}]}],"groups":[{"title":"Constructors","kind":512,"children":[10]},{"title":"Properties","kind":1024,"children":[9,7,4,5,3,6,8]},{"title":"Methods","kind":2048,"children":[17]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":9,"character":31}]},{"id":81,"name":"ValidationController","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Orchestrates validation.\nManages a set of bindings, renderers and objects.\nExposes the current list of validation results for binding purposes."},"children":[{"id":95,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":96,"name":"new ValidationController","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":97,"name":"validator","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Validator","id":38}},{"id":98,"name":"propertyParser","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"PropertyAccessorParser","id":27}}],"type":{"type":"reference","name":"ValidationController","id":81}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":290,"character":31}]},{"id":85,"name":"bindings","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":269,"character":24}],"type":{"type":"intrinsic","name":"any"}},{"id":90,"name":"elements","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":283,"character":24}],"type":{"type":"intrinsic","name":"any"}},{"id":88,"name":"errors","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"Validation errors that have been rendered by the controller."},"sources":[{"fileName":"aurelia-validation.d.ts","line":278,"character":14}],"type":{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}},{"id":94,"name":"eventCallbacks","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":290,"character":30}],"type":{"type":"intrinsic","name":"any"}},{"id":93,"name":"finishValidating","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":289,"character":32}],"type":{"type":"intrinsic","name":"any"}},{"id":91,"name":"objects","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":284,"character":23}],"type":{"type":"intrinsic","name":"any"}},{"id":83,"name":"propertyParser","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":267,"character":30}],"type":{"type":"intrinsic","name":"any"}},{"id":86,"name":"renderers","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":270,"character":25}],"type":{"type":"intrinsic","name":"any"}},{"id":87,"name":"results","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"comment":{"shortText":"Validation results that have been rendered by the controller."},"sources":[{"fileName":"aurelia-validation.d.ts","line":274,"character":23}],"type":{"type":"intrinsic","name":"any"}},{"id":92,"name":"validateTrigger","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The trigger that will invoke automatic validation of a property used in a binding."},"sources":[{"fileName":"aurelia-validation.d.ts","line":288,"character":23}],"type":{"type":"reference","name":"validateTrigger","id":52}},{"id":89,"name":"validating","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":" Whether the controller is currently validating."},"sources":[{"fileName":"aurelia-validation.d.ts","line":282,"character":18}],"type":{"type":"intrinsic","name":"boolean"}},{"id":82,"name":"validator","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":266,"character":25}],"type":{"type":"intrinsic","name":"any"}},{"id":84,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":268,"character":21}],"type":{"type":"array","elementType":{"type":"union","types":[{"type":"reference","name":"PropertyAccessorParser","id":27},{"type":"reference","name":"Validator","id":38}]}}},{"id":116,"name":"addError","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":117,"name":"addError","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Adds and renders an error."},"typeParameter":[{"id":118,"name":"TObject","kind":131072,"kindString":"Type parameter","flags":{}}],"parameters":[{"id":119,"name":"message","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}},{"id":120,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TObject"}},{"id":121,"name":"propertyName","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"reference","name":"PropertyAccessor","id":797,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"intrinsic","name":"string"}]},{"type":"intrinsic","name":"null"}]}}],"type":{"type":"reference","name":"ValidateResult","id":2}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":314,"character":16}]},{"id":109,"name":"addObject","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":110,"name":"addObject","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Adds an object to the set of objects that should be validated when validate is called."},"parameters":[{"id":111,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The object."},"type":{"type":"intrinsic","name":"any"}},{"id":112,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"comment":{"text":"Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules.\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":305,"character":17}]},{"id":125,"name":"addRenderer","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":126,"name":"addRenderer","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Adds a renderer."},"parameters":[{"id":127,"name":"renderer","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The renderer.\n"},"type":{"type":"reference","name":"ValidationRenderer","id":64}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":323,"character":19}]},{"id":165,"name":"changeTrigger","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":166,"name":"changeTrigger","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Changes the controller's validateTrigger."},"parameters":[{"id":167,"name":"newTrigger","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The new validateTrigger\n"},"type":{"type":"reference","name":"validateTrigger","id":52}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":375,"character":21}]},{"id":148,"name":"getAssociatedElements","kind":2048,"kindString":"Method","flags":{"isPrivate":true,"isExported":true},"signatures":[{"id":149,"name":"getAssociatedElements","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Gets the elements associated with an object and propertyName (if any)."},"parameters":[{"id":150,"name":"__namedParameters","kind":32768,"kindString":"Parameter","flags":{},"originalName":"__0","type":{"type":"reflection","declaration":{"id":151,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"children":[{"id":152,"name":"object","kind":32,"kindString":"Variable","flags":{},"sources":[{"fileName":"aurelia-validation.d.ts","line":361,"character":45}],"type":{"type":"intrinsic","name":"any"}},{"id":153,"name":"propertyName","kind":32,"kindString":"Variable","flags":{},"sources":[{"fileName":"aurelia-validation.d.ts","line":361,"character":59}],"type":{"type":"intrinsic","name":"any"}}],"groups":[{"title":"Variables","kind":32,"children":[152,153]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":361,"character":38}]}}}],"type":{"type":"intrinsic","name":"any"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":361,"character":37}]},{"id":139,"name":"getInstructionPredicate","kind":2048,"kindString":"Method","flags":{"isPrivate":true,"isExported":true},"signatures":[{"id":140,"name":"getInstructionPredicate","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Interprets the instruction and returns a predicate that will identify\nrelevant results in the list of rendered validation results."},"parameters":[{"id":141,"name":"instruction","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"any"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":345,"character":39}]},{"id":170,"name":"invokeCallbacks","kind":2048,"kindString":"Method","flags":{"isPrivate":true,"isExported":true},"signatures":[{"id":171,"name":"invokeCallbacks","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":172,"name":"instruction","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":173,"name":"result","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"any"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":380,"character":31}]},{"id":154,"name":"processResultDelta","kind":2048,"kindString":"Method","flags":{"isPrivate":true,"isExported":true},"signatures":[{"id":155,"name":"processResultDelta","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":156,"name":"kind","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":157,"name":"oldResults","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":158,"name":"newResults","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"any"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":362,"character":34}]},{"id":131,"name":"registerBinding","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":132,"name":"registerBinding","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Registers a binding with the controller."},"parameters":[{"id":133,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The binding instance."},"type":{"type":"reference","name":"Binding"}},{"id":134,"name":"target","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The DOM element."},"type":{"type":"reference","name":"Element"}},{"id":135,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"comment":{"text":"(optional) rules associated with the binding. Validator implementation specific.\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":335,"character":23}]},{"id":122,"name":"removeError","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":123,"name":"removeError","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Removes and unrenders an error."},"parameters":[{"id":124,"name":"result","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ValidateResult","id":2}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":318,"character":19}]},{"id":113,"name":"removeObject","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":114,"name":"removeObject","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Removes an object from the set of objects that should be validated when validate is called."},"parameters":[{"id":115,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The object.\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":310,"character":20}]},{"id":128,"name":"removeRenderer","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":129,"name":"removeRenderer","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Removes a renderer."},"parameters":[{"id":130,"name":"renderer","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The renderer.\n"},"type":{"type":"reference","name":"ValidationRenderer","id":64}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":328,"character":22}]},{"id":145,"name":"reset","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":146,"name":"reset","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Resets any rendered validation results (unrenders)."},"parameters":[{"id":147,"name":"instruction","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"comment":{"text":"Optional. Instructions on what to reset. If unspecified all rendered results\nwill be unrendered.\n"},"type":{"type":"reference","name":"ValidateInstruction","id":19}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":357,"character":13}]},{"id":162,"name":"resetBinding","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":163,"name":"resetBinding","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Resets the results for a property associated with a binding."},"parameters":[{"id":164,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Binding"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":370,"character":20}]},{"id":168,"name":"revalidateErrors","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":169,"name":"revalidateErrors","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Revalidates the controller's current set of errors."},"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":379,"character":24}]},{"id":99,"name":"subscribe","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":100,"name":"subscribe","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Subscribe to controller validate and reset events. These events occur when the\ncontroller's \"validate\"\" and \"reset\" methods are called."},"parameters":[{"id":101,"name":"callback","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The callback to be invoked when the controller validates or resets.\n"},"type":{"type":"reflection","declaration":{"id":102,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":103,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":104,"name":"event","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ValidateEvent","id":68}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":297,"character":27}]}}}],"type":{"type":"reflection","declaration":{"id":105,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"children":[{"id":106,"name":"dispose","kind":32,"kindString":"Variable","flags":{},"sources":[{"fileName":"aurelia-validation.d.ts","line":298,"character":19}],"type":{"type":"reflection","declaration":{"id":107,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":108,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":298,"character":20}]}}}],"groups":[{"title":"Variables","kind":32,"children":[106]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":297,"character":60}]}}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":297,"character":17}]},{"id":136,"name":"unregisterBinding","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":137,"name":"unregisterBinding","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Unregisters a binding with the controller."},"parameters":[{"id":138,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The binding instance.\n"},"type":{"type":"reference","name":"Binding"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":340,"character":25}]},{"id":142,"name":"validate","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":143,"name":"validate","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Validates and renders results."},"parameters":[{"id":144,"name":"instruction","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"comment":{"text":"Optional. Instructions on what to validate. If undefined, all\nobjects and bindings will be validated.\n"},"type":{"type":"reference","name":"ValidateInstruction","id":19}}],"type":{"type":"reference","name":"Promise","typeArguments":[{"type":"reference","name":"ControllerValidateResult","id":23}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":351,"character":16}]},{"id":159,"name":"validateBinding","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":160,"name":"validateBinding","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Validates the property associated with a binding."},"parameters":[{"id":161,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Binding"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":366,"character":23}]}],"groups":[{"title":"Constructors","kind":512,"children":[95]},{"title":"Properties","kind":1024,"children":[85,90,88,94,93,91,83,86,87,92,89,82,84]},{"title":"Methods","kind":2048,"children":[116,109,125,165,148,139,170,154,131,122,113,128,145,162,168,99,136,142,159]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":265,"character":37}]},{"id":272,"name":"ValidationControllerFactory","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Creates ValidationController instances."},"children":[{"id":277,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":278,"name":"new ValidationControllerFactory","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":279,"name":"container","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Container"}}],"type":{"type":"reference","name":"ValidationControllerFactory","id":272}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":451,"character":70}]},{"id":273,"name":"container","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":450,"character":25}],"type":{"type":"intrinsic","name":"any"}},{"id":280,"name":"create","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":281,"name":"create","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Creates a new controller instance."},"parameters":[{"id":282,"name":"validator","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"reference","name":"Validator","id":38}}],"type":{"type":"reference","name":"ValidationController","id":81}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":456,"character":14}]},{"id":283,"name":"createForCurrentScope","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":284,"name":"createForCurrentScope","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Creates a new controller and registers it in the current element's container so that it's\navailable to the validate binding behavior and renderers."},"parameters":[{"id":285,"name":"validator","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"reference","name":"Validator","id":38}}],"type":{"type":"reference","name":"ValidationController","id":81}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":461,"character":29}]},{"id":274,"name":"get","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":275,"name":"get","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":276,"name":"container","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Container"}}],"type":{"type":"reference","name":"ValidationControllerFactory","id":272}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":451,"character":18}]}],"groups":[{"title":"Constructors","kind":512,"children":[277]},{"title":"Properties","kind":1024,"children":[273]},{"title":"Methods","kind":2048,"children":[280,283,274]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":449,"character":44}]},{"id":289,"name":"ValidationErrorsCustomAttribute","kind":128,"kindString":"Class","flags":{"isExported":true},"children":[{"id":301,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":302,"name":"new ValidationErrorsCustomAttribute","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":303,"name":"boundaryElement","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Element"}},{"id":304,"name":"controllerAccessor","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reflection","declaration":{"id":305,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":306,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"reference","name":"ValidationController","id":81}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":481,"character":65}]}}}],"type":{"type":"reference","name":"ValidationErrorsCustomAttribute","id":289}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":480,"character":31}]},{"id":290,"name":"boundaryElement","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":472,"character":31}],"type":{"type":"intrinsic","name":"any"}},{"id":298,"name":"controller","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":478,"character":18}],"type":{"type":"union","types":[{"type":"reference","name":"ValidationController","id":81},{"type":"intrinsic","name":"null"}]}},{"id":291,"name":"controllerAccessor","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":473,"character":34}],"type":{"type":"intrinsic","name":"any"}},{"id":299,"name":"errors","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":479,"character":14}],"type":{"type":"array","elementType":{"type":"reference","name":"RenderedError","id":286}}},{"id":300,"name":"errorsInternal","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":480,"character":30}],"type":{"type":"intrinsic","name":"any"}},{"id":315,"name":"bind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":316,"name":"bind","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":485,"character":12}]},{"id":309,"name":"interestingElements","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":310,"name":"interestingElements","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":311,"name":"elements","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"array","elementType":{"type":"reference","name":"Element"}}}],"type":{"type":"array","elementType":{"type":"reference","name":"Element"}}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":483,"character":27}]},{"id":312,"name":"render","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":313,"name":"render","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":314,"name":"instruction","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"RenderInstruction","id":60}}],"type":{"type":"intrinsic","name":"void"},"implementationOf":{"type":"reference","name":"ValidationRenderer.render","id":66}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":484,"character":14}],"implementationOf":{"type":"reference","name":"ValidationRenderer.render","id":65}},{"id":307,"name":"sort","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":308,"name":"sort","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":482,"character":12}]},{"id":317,"name":"unbind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":318,"name":"unbind","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":486,"character":14}]},{"id":292,"name":"inject","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":293,"name":"inject","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"array","elementType":{"type":"union","types":[{"type":"reflection","declaration":{"id":294,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"children":[{"id":295,"name":"constructor","kind":512,"kindString":"Constructor","flags":{},"signatures":[{"id":296,"name":"new __type","kind":16384,"kindString":"Constructor signature","flags":{},"type":{"type":"reference","name":"Element"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":474,"character":27}]},{"id":297,"name":"prototype","kind":32,"kindString":"Variable","flags":{},"sources":[{"fileName":"aurelia-validation.d.ts","line":476,"character":21}],"type":{"type":"reference","name":"Element"}}],"groups":[{"title":"Constructors","kind":512,"children":[295]},{"title":"Variables","kind":32,"children":[297]}]}},{"type":"reference","name":"Lazy"}]}}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":474,"character":21}]}],"groups":[{"title":"Constructors","kind":512,"children":[301]},{"title":"Properties","kind":1024,"children":[290,298,291,299,300]},{"title":"Methods","kind":2048,"children":[315,309,312,307,317,292]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":471,"character":48}],"implementedTypes":[{"type":"reference","name":"ValidationRenderer","id":64}]},{"id":422,"name":"ValidationMessageParser","kind":128,"kindString":"Class","flags":{"isExported":true},"children":[{"id":429,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":430,"name":"new ValidationMessageParser","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":431,"name":"bindinqLanguage","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"BindingLanguage"}}],"type":{"type":"reference","name":"ValidationMessageParser","id":422}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":590,"character":22}]},{"id":423,"name":"bindinqLanguage","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":585,"character":31}],"type":{"type":"intrinsic","name":"any"}},{"id":428,"name":"cache","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":590,"character":21}],"type":{"type":"intrinsic","name":"any"}},{"id":425,"name":"emptyStringExpression","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":587,"character":37}],"type":{"type":"intrinsic","name":"any"}},{"id":426,"name":"nullExpression","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":588,"character":30}],"type":{"type":"intrinsic","name":"any"}},{"id":427,"name":"undefinedExpression","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":589,"character":35}],"type":{"type":"intrinsic","name":"any"}},{"id":424,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":586,"character":21}],"type":{"type":"array","elementType":{"type":"reference","name":"BindingLanguage"}}},{"id":435,"name":"coalesce","kind":2048,"kindString":"Method","flags":{"isPrivate":true,"isExported":true},"signatures":[{"id":436,"name":"coalesce","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":437,"name":"part","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"any"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":593,"character":24}]},{"id":432,"name":"parse","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":433,"name":"parse","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":434,"name":"message","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"reference","name":"Expression"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":592,"character":13}]}],"groups":[{"title":"Constructors","kind":512,"children":[429]},{"title":"Properties","kind":1024,"children":[423,428,425,426,427,424]},{"title":"Methods","kind":2048,"children":[435,432]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":584,"character":40}]},{"id":504,"name":"ValidationMessageProvider","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Retrieves validation messages and property display names."},"children":[{"id":507,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":508,"name":"new ValidationMessageProvider","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":509,"name":"parser","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ValidationMessageParser","id":422}}],"type":{"type":"reference","name":"ValidationMessageProvider","id":504}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":615,"character":58}]},{"id":505,"name":"parser","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":614,"character":14}],"type":{"type":"reference","name":"ValidationMessageParser","id":422}},{"id":506,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":615,"character":21}],"type":{"type":"array","elementType":{"type":"reference","name":"ValidationMessageParser","id":422}}},{"id":513,"name":"getDisplayName","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":514,"name":"getDisplayName","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Formulates a property display name using the property name and the configured\ndisplayName (if provided).\nOverride this with your own custom logic."},"parameters":[{"id":515,"name":"propertyName","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The property name.\n"},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"number"}]}},{"id":516,"name":"displayName","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"null"},{"type":"reflection","declaration":{"id":517,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":518,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"string"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":628,"character":83}]}}]}}],"type":{"type":"intrinsic","name":"string"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":628,"character":22}]},{"id":510,"name":"getMessage","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":511,"name":"getMessage","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Returns a message binding expression that corresponds to the key."},"parameters":[{"id":512,"name":"key","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The message key.\n"},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"reference","name":"Expression"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":621,"character":18}]}],"groups":[{"title":"Constructors","kind":512,"children":[507]},{"title":"Properties","kind":1024,"children":[505,506]},{"title":"Methods","kind":2048,"children":[513,510]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":613,"character":42}]},{"id":319,"name":"ValidationRendererCustomAttribute","kind":128,"kindString":"Class","flags":{"isExported":true},"children":[{"id":320,"name":"container","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":490,"character":25}],"type":{"type":"intrinsic","name":"any"}},{"id":321,"name":"controller","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":491,"character":26}],"type":{"type":"intrinsic","name":"any"}},{"id":323,"name":"renderer","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":493,"character":24}],"type":{"type":"intrinsic","name":"any"}},{"id":322,"name":"value","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":492,"character":21}],"type":{"type":"intrinsic","name":"any"}},{"id":327,"name":"bind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":328,"name":"bind","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":495,"character":12}]},{"id":324,"name":"created","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":325,"name":"created","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":326,"name":"view","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":494,"character":15}]},{"id":329,"name":"unbind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":330,"name":"unbind","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":496,"character":14}]}],"groups":[{"title":"Properties","kind":1024,"children":[320,321,323,322]},{"title":"Methods","kind":2048,"children":[327,324,329]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":489,"character":50}]},{"id":727,"name":"ValidationRules","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Fluent rule definition API."},"children":[{"id":728,"name":"parsers","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":891,"character":30}],"type":{"type":"intrinsic","name":"any"}},{"id":741,"name":"customRule","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":742,"name":"customRule","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Defines a custom rule."},"parameters":[{"id":743,"name":"name","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The name of the custom rule. Also serves as the message key."},"type":{"type":"intrinsic","name":"string"}},{"id":744,"name":"condition","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The rule function."},"type":{"type":"reflection","declaration":{"id":745,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":746,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":747,"name":"value","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":748,"name":"object","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"any"}},{"id":749,"name":"args","kind":32768,"kindString":"Parameter","flags":{"isRest":true},"type":{"type":"array","elementType":{"type":"intrinsic","name":"any"}}}],"type":{"type":"union","types":[{"type":"intrinsic","name":"boolean"},{"type":"reference","name":"Promise","typeArguments":[{"type":"intrinsic","name":"boolean"}]}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":910,"character":50}]}}},{"id":750,"name":"message","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The message expression"},"type":{"type":"intrinsic","name":"string"}},{"id":751,"name":"argsToConfig","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"comment":{"text":"A function that maps the rule's arguments to a \"config\"\nobject that can be used when evaluating the message expression.\n"},"type":{"type":"union","types":[{"type":"intrinsic","name":"undefined"},{"type":"reflection","declaration":{"id":752,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":753,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":754,"name":"args","kind":32768,"kindString":"Parameter","flags":{"isRest":true},"type":{"type":"array","elementType":{"type":"intrinsic","name":"any"}}}],"type":{"type":"intrinsic","name":"any"}}]}}]}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":910,"character":25}]},{"id":733,"name":"ensure","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":734,"name":"ensure","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Target a property with validation rules."},"typeParameter":[{"id":735,"name":"TObject","kind":131072,"kindString":"Type parameter","flags":{}},{"id":736,"name":"TValue","kind":131072,"kindString":"Type parameter","flags":{}}],"parameters":[{"id":737,"name":"property","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The property to target. Can be the property name or a property accessor function.\n"},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"number"},{"type":"reference","name":"PropertyAccessor","id":797,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}]}}],"type":{"type":"reference","name":"FluentRules","id":641,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"intrinsic","name":"any"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":897,"character":21}]},{"id":738,"name":"ensureObject","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":739,"name":"ensureObject","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Targets an object with validation rules."},"typeParameter":[{"id":740,"name":"TObject","kind":131072,"kindString":"Type parameter","flags":{}}],"type":{"type":"reference","name":"FluentRules","id":641,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"intrinsic","name":"any"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":901,"character":27}]},{"id":729,"name":"initialize","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":730,"name":"initialize","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":731,"name":"messageParser","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ValidationMessageParser","id":422}},{"id":732,"name":"propertyParser","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"PropertyAccessorParser","id":27}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":892,"character":25}]},{"id":762,"name":"off","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":763,"name":"off","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Removes the rules from a class or object."},"parameters":[{"id":764,"name":"target","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"A class or object.\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":926,"character":18}]},{"id":755,"name":"taggedRules","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":756,"name":"taggedRules","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Returns rules with the matching tag."},"parameters":[{"id":757,"name":"rules","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The rules to search."},"type":{"type":"array","elementType":{"type":"array","elementType":{"type":"reference","name":"Rule","id":334,"typeArguments":[{"type":"intrinsic","name":"any"},{"type":"intrinsic","name":"any"}]}}}},{"id":758,"name":"tag","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The tag to search for.\n"},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"array","elementType":{"type":"array","elementType":{"type":"reference","name":"Rule","id":334,"typeArguments":[{"type":"intrinsic","name":"any"},{"type":"intrinsic","name":"any"}]}}}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":916,"character":26}]},{"id":759,"name":"untaggedRules","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":760,"name":"untaggedRules","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Returns rules that have no tag."},"parameters":[{"id":761,"name":"rules","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The rules to search.\n"},"type":{"type":"array","elementType":{"type":"array","elementType":{"type":"reference","name":"Rule","id":334,"typeArguments":[{"type":"intrinsic","name":"any"},{"type":"intrinsic","name":"any"}]}}}}],"type":{"type":"array","elementType":{"type":"array","elementType":{"type":"reference","name":"Rule","id":334,"typeArguments":[{"type":"intrinsic","name":"any"},{"type":"intrinsic","name":"any"}]}}}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":921,"character":28}]}],"groups":[{"title":"Properties","kind":1024,"children":[728]},{"title":"Methods","kind":2048,"children":[741,733,738,729,762,755,759]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":890,"character":32}]},{"id":38,"name":"Validator","kind":128,"kindString":"Class","flags":{"isExported":true,"isAbstract":true},"comment":{"shortText":"Validates objects and properties."},"children":[{"id":48,"name":"ruleExists","kind":2048,"kindString":"Method","flags":{"isExported":true,"isAbstract":true},"signatures":[{"id":49,"name":"ruleExists","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Determines whether a rule exists in a set of rules.","tags":[{"tag":"parem","text":"rule The rule to find.\n"}]},"parameters":[{"id":50,"name":"rules","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The rules to search."},"type":{"type":"intrinsic","name":"any"}},{"id":51,"name":"rule","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"boolean"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":121,"character":27}]},{"id":44,"name":"validateObject","kind":2048,"kindString":"Method","flags":{"isExported":true,"isAbstract":true},"signatures":[{"id":45,"name":"validateObject","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Validates all rules for specified object and it's properties."},"parameters":[{"id":46,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The object to validate."},"type":{"type":"intrinsic","name":"any"}},{"id":47,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"comment":{"text":"Optional. If unspecified, the implementation should lookup the rules for the\nspecified object. This may not be possible for all implementations of this interface.\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"reference","name":"Promise","typeArguments":[{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":115,"character":31}]},{"id":39,"name":"validateProperty","kind":2048,"kindString":"Method","flags":{"isExported":true,"isAbstract":true},"signatures":[{"id":40,"name":"validateProperty","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Validates the specified property."},"parameters":[{"id":41,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The object to validate."},"type":{"type":"intrinsic","name":"any"}},{"id":42,"name":"propertyName","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The name of the property to validate."},"type":{"type":"intrinsic","name":"string"}},{"id":43,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"comment":{"text":"Optional. If unspecified, the implementation should lookup the rules for the\nspecified object. This may not be possible for all implementations of this interface.\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"reference","name":"Promise","typeArguments":[{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":108,"character":33}]}],"groups":[{"title":"Methods","kind":2048,"children":[48,44,39]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":100,"character":35}],"extendedBy":[{"type":"reference","name":"StandardValidator","id":519}]},{"id":23,"name":"ControllerValidateResult","kind":256,"kindString":"Interface","flags":{"isExported":true},"comment":{"shortText":"The result of a call to the validation controller's validate method."},"children":[{"id":26,"name":"instruction","kind":1024,"kindString":"Property","flags":{"isExported":true,"isOptional":true},"comment":{"shortText":"The instruction passed to the controller's validate method."},"sources":[{"fileName":"aurelia-validation.d.ts","line":64,"character":19}],"type":{"type":"reference","name":"ValidateInstruction","id":19}},{"id":25,"name":"results","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The validation result of every rule that was evaluated."},"sources":[{"fileName":"aurelia-validation.d.ts","line":60,"character":15}],"type":{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}},{"id":24,"name":"valid","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"Whether validation passed."},"sources":[{"fileName":"aurelia-validation.d.ts","line":56,"character":13}],"type":{"type":"intrinsic","name":"boolean"}}],"groups":[{"title":"Properties","kind":1024,"children":[26,25,24]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":52,"character":45}]},{"id":765,"name":"Parsers","kind":256,"kindString":"Interface","flags":{"isExported":true},"children":[{"id":766,"name":"message","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":929,"character":15}],"type":{"type":"reference","name":"ValidationMessageParser","id":422}},{"id":767,"name":"property","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":930,"character":16}],"type":{"type":"reference","name":"PropertyAccessorParser","id":27}}],"groups":[{"title":"Properties","kind":1024,"children":[766,767]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":928,"character":28}]},{"id":60,"name":"RenderInstruction","kind":256,"kindString":"Interface","flags":{"isExported":true},"comment":{"shortText":"Defines which validation results to render and which validation results to unrender."},"children":[{"id":61,"name":"kind","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The \"kind\" of render instruction. Either 'validate' or 'reset'."},"sources":[{"fileName":"aurelia-validation.d.ts","line":168,"character":12}],"type":{"type":"union","types":[{"type":"stringLiteral","value":"validate"},{"type":"stringLiteral","value":"reset"}]}},{"id":62,"name":"render","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The results to render."},"sources":[{"fileName":"aurelia-validation.d.ts","line":172,"character":14}],"type":{"type":"array","elementType":{"type":"reference","name":"ResultInstruction","id":57}}},{"id":63,"name":"unrender","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The results to unrender."},"sources":[{"fileName":"aurelia-validation.d.ts","line":176,"character":16}],"type":{"type":"array","elementType":{"type":"reference","name":"ResultInstruction","id":57}}}],"groups":[{"title":"Properties","kind":1024,"children":[61,62,63]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":164,"character":38}]},{"id":286,"name":"RenderedError","kind":256,"kindString":"Interface","flags":{"isExported":true},"children":[{"id":287,"name":"error","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":468,"character":13}],"type":{"type":"reference","name":"ValidateResult","id":2}},{"id":288,"name":"targets","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":469,"character":15}],"type":{"type":"array","elementType":{"type":"reference","name":"Element"}}}],"groups":[{"title":"Properties","kind":1024,"children":[287,288]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":467,"character":34}]},{"id":57,"name":"ResultInstruction","kind":256,"kindString":"Interface","flags":{"isExported":true},"comment":{"shortText":"A result to render (or unrender) and the associated elements (if any)"},"children":[{"id":59,"name":"elements","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The associated elements (if any)."},"sources":[{"fileName":"aurelia-validation.d.ts","line":159,"character":16}],"type":{"type":"array","elementType":{"type":"reference","name":"Element"}}},{"id":58,"name":"result","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The validation result."},"sources":[{"fileName":"aurelia-validation.d.ts","line":155,"character":14}],"type":{"type":"reference","name":"ValidateResult","id":2}}],"groups":[{"title":"Properties","kind":1024,"children":[59,58]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":151,"character":38}]},{"id":334,"name":"Rule","kind":256,"kindString":"Interface","flags":{"isExported":true},"comment":{"shortText":"A rule definition. Associations a rule with a property or object."},"typeParameter":[{"id":335,"name":"TObject","kind":131072,"kindString":"Type parameter","flags":{}},{"id":336,"name":"TValue","kind":131072,"kindString":"Type parameter","flags":{}}],"children":[{"id":338,"name":"condition","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":518,"character":17}],"type":{"type":"reflection","declaration":{"id":339,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":340,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":341,"name":"value","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TValue"}},{"id":342,"name":"object","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"reference","name":"TObject","id":335}}],"type":{"type":"union","types":[{"type":"intrinsic","name":"boolean"},{"type":"reference","name":"Promise","typeArguments":[{"type":"intrinsic","name":"boolean"}]}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":518,"character":18}]}}},{"id":343,"name":"config","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":519,"character":14}],"type":{"type":"intrinsic","name":"object"}},{"id":349,"name":"message","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":522,"character":15}],"type":{"type":"union","types":[{"type":"reference","name":"Expression"},{"type":"intrinsic","name":"null"}]}},{"id":348,"name":"messageKey","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":521,"character":18}],"type":{"type":"intrinsic","name":"string"}},{"id":337,"name":"property","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":517,"character":16}],"type":{"type":"reference","name":"RuleProperty","id":331}},{"id":350,"name":"sequence","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":523,"character":16}],"type":{"type":"intrinsic","name":"number"}},{"id":351,"name":"tag","kind":1024,"kindString":"Property","flags":{"isExported":true,"isOptional":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":524,"character":11}],"type":{"type":"union","types":[{"type":"intrinsic","name":"undefined"},{"type":"intrinsic","name":"string"}]}},{"id":344,"name":"when","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":520,"character":12}],"type":{"type":"union","types":[{"type":"reflection","declaration":{"id":345,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":346,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":347,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TObject"}}],"type":{"type":"intrinsic","name":"boolean"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":520,"character":13}]}},{"type":"intrinsic","name":"null"}]}}],"groups":[{"title":"Properties","kind":1024,"children":[338,343,349,348,337,350,351,344]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":516,"character":25}]},{"id":331,"name":"RuleProperty","kind":256,"kindString":"Interface","flags":{"isExported":true},"comment":{"shortText":"Information related to a property that is the subject of validation."},"children":[{"id":333,"name":"displayName","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The displayName of the property (or object)."},"sources":[{"fileName":"aurelia-validation.d.ts","line":511,"character":19}],"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"reference","name":"ValidationDisplayNameAccessor","id":806},{"type":"intrinsic","name":"null"}]}},{"id":332,"name":"name","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The property name. null indicates the rule targets the object itself."},"sources":[{"fileName":"aurelia-validation.d.ts","line":507,"character":12}],"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"number"},{"type":"intrinsic","name":"null"}]}}],"groups":[{"title":"Properties","kind":1024,"children":[333,332]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":503,"character":33}]},{"id":19,"name":"ValidateInstruction","kind":256,"kindString":"Interface","flags":{"isExported":true},"comment":{"shortText":"Instructions for the validation controller's validate method."},"children":[{"id":20,"name":"object","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The object to validate."},"sources":[{"fileName":"aurelia-validation.d.ts","line":37,"character":14}],"type":{"type":"intrinsic","name":"any"}},{"id":21,"name":"propertyName","kind":1024,"kindString":"Property","flags":{"isExported":true,"isOptional":true},"comment":{"shortText":"The property to validate. Optional."},"sources":[{"fileName":"aurelia-validation.d.ts","line":41,"character":20}],"type":{"type":"intrinsic","name":"any"}},{"id":22,"name":"rules","kind":1024,"kindString":"Property","flags":{"isExported":true,"isOptional":true},"comment":{"shortText":"The rules to validate. Optional."},"sources":[{"fileName":"aurelia-validation.d.ts","line":45,"character":13}],"type":{"type":"intrinsic","name":"any"}}],"groups":[{"title":"Properties","kind":1024,"children":[20,21,22]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":33,"character":40}]},{"id":501,"name":"ValidationMessages","kind":256,"kindString":"Interface","flags":{"isExported":true},"indexSignature":{"id":502,"name":"__index","kind":8192,"kindString":"Index signature","flags":{},"parameters":[{"id":503,"name":"key","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"intrinsic","name":"string"}},"sources":[{"fileName":"aurelia-validation.d.ts","line":603,"character":39}]},{"id":64,"name":"ValidationRenderer","kind":256,"kindString":"Interface","flags":{"isExported":true},"comment":{"shortText":"Renders validation results."},"children":[{"id":65,"name":"render","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":66,"name":"render","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Render the validation results."},"parameters":[{"id":67,"name":"instruction","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The render instruction. Defines which results to render and which\nresults to unrender.\n"},"type":{"type":"reference","name":"RenderInstruction","id":60}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":187,"character":14}]}],"groups":[{"title":"Methods","kind":2048,"children":[65]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":181,"character":39}],"implementedBy":[{"type":"reference","name":"ValidationErrorsCustomAttribute","id":289}]},{"id":812,"name":"AccessScope","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":552,"character":27}],"type":{"type":"intrinsic","name":"any"}},{"id":811,"name":"AccessThis","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":551,"character":26}],"type":{"type":"intrinsic","name":"any"}},{"id":810,"name":"Assign","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":550,"character":22}],"type":{"type":"intrinsic","name":"any"}},{"id":814,"name":"CallFunction","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":554,"character":28}],"type":{"type":"intrinsic","name":"any"}},{"id":813,"name":"CallScope","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":553,"character":25}],"type":{"type":"intrinsic","name":"any"}},{"id":809,"name":"Chain","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":549,"character":21}],"type":{"type":"intrinsic","name":"any"}},{"id":817,"name":"LiteralArray","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":557,"character":28}],"type":{"type":"intrinsic","name":"any"}},{"id":818,"name":"LiteralObject","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":558,"character":29}],"type":{"type":"intrinsic","name":"any"}},{"id":816,"name":"LiteralPrimitive","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":556,"character":32}],"type":{"type":"intrinsic","name":"any"}},{"id":819,"name":"LiteralString","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":559,"character":29}],"type":{"type":"intrinsic","name":"any"}},{"id":815,"name":"PrefixNot","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":555,"character":25}],"type":{"type":"intrinsic","name":"any"}},{"id":797,"name":"PropertyAccessor","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"typeParameter":[{"id":798,"name":"TObject","kind":131072,"kindString":"Type parameter","flags":{}},{"id":799,"name":"TValue","kind":131072,"kindString":"Type parameter","flags":{}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":88,"character":32}],"type":{"type":"reflection","declaration":{"id":800,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":801,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":802,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TObject"}}],"type":{"type":"typeParameter","name":"TValue"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":88,"character":51}]}}},{"id":806,"name":"ValidationDisplayNameAccessor","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":499,"character":45}],"type":{"type":"reflection","declaration":{"id":807,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":808,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"string"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":499,"character":47}]}}},{"id":820,"name":"validationMessages","kind":32,"kindString":"Variable","flags":{"isExported":true,"isConst":true},"comment":{"shortText":"Dictionary of validation messages. [messageKey]: messageExpression"},"sources":[{"fileName":"aurelia-validation.d.ts","line":609,"character":35}],"type":{"type":"reference","name":"ValidationMessages","id":501}},{"id":821,"name":"configure","kind":64,"kindString":"Function","flags":{"isExported":true},"signatures":[{"id":822,"name":"configure","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Configures the plugin."},"parameters":[{"id":823,"name":"frameworkConfig","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reflection","declaration":{"id":824,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"children":[{"id":825,"name":"container","kind":32,"kindString":"Variable","flags":{},"sources":[{"fileName":"aurelia-validation.d.ts","line":975,"character":17}],"type":{"type":"reference","name":"Container"}},{"id":826,"name":"globalResources","kind":32,"kindString":"Variable","flags":{"isOptional":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":976,"character":23}],"type":{"type":"union","types":[{"type":"intrinsic","name":"undefined"},{"type":"reflection","declaration":{"id":827,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":828,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":829,"name":"resources","kind":32768,"kindString":"Parameter","flags":{"isRest":true},"type":{"type":"array","elementType":{"type":"intrinsic","name":"string"}}}],"type":{"type":"intrinsic","name":"any"}}]}}]}}],"groups":[{"title":"Variables","kind":32,"children":[825,826]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":974,"character":46}]}}},{"id":830,"name":"callback","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"intrinsic","name":"undefined"},{"type":"reflection","declaration":{"id":831,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":832,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":833,"name":"config","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"AureliaValidationConfiguration","id":768}}],"type":{"type":"intrinsic","name":"void"}}]}}]}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":974,"character":29}]},{"id":803,"name":"getAccessorExpression","kind":64,"kindString":"Function","flags":{"isExported":true},"signatures":[{"id":804,"name":"getAccessorExpression","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":805,"name":"fn","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"intrinsic","name":"string"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":95,"character":41}]},{"id":784,"name":"getPropertyInfo","kind":64,"kindString":"Function","flags":{"isExported":true},"signatures":[{"id":785,"name":"getPropertyInfo","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Retrieves the object and property name for the specified expression."},"parameters":[{"id":786,"name":"expression","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The expression"},"type":{"type":"reference","name":"Expression"}},{"id":787,"name":"source","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The scope\n"},"type":{"type":"reference","name":"Scope"}}],"type":{"type":"union","types":[{"type":"reflection","declaration":{"id":788,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"children":[{"id":789,"name":"object","kind":32,"kindString":"Variable","flags":{},"sources":[{"fileName":"aurelia-validation.d.ts","line":81,"character":14}],"type":{"type":"intrinsic","name":"object"}},{"id":790,"name":"propertyName","kind":32,"kindString":"Variable","flags":{},"sources":[{"fileName":"aurelia-validation.d.ts","line":82,"character":20}],"type":{"type":"intrinsic","name":"string"}}],"groups":[{"title":"Variables","kind":32,"children":[789,790]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":80,"character":75}]}},{"type":"intrinsic","name":"null"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":80,"character":35}]},{"id":780,"name":"getTargetDOMElement","kind":64,"kindString":"Function","flags":{"isExported":true},"signatures":[{"id":781,"name":"getTargetDOMElement","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Gets the DOM element associated with the data-binding. Most of the time it's\nthe binding.target but sometimes binding.target is an aurelia custom element,\nor custom attribute which is a javascript \"class\" instance, so we need to use\nthe controller's container to retrieve the actual DOM element."},"parameters":[{"id":782,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":783,"name":"view","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"reference","name":"Element"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":73,"character":39}]},{"id":794,"name":"isNumber","kind":64,"kindString":"Function","flags":{"isExported":true},"signatures":[{"id":795,"name":"isNumber","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":796,"name":"value","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"boolean"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":86,"character":28}]},{"id":791,"name":"isString","kind":64,"kindString":"Function","flags":{"isExported":true},"signatures":[{"id":792,"name":"isString","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":793,"name":"value","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"boolean"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":85,"character":28}]}],"groups":[{"title":"Enumerations","kind":4,"children":[52]},{"title":"Classes","kind":128,"children":[768,364,705,558,641,438,27,352,519,191,174,68,208,224,240,256,2,81,272,289,422,504,319,727,38]},{"title":"Interfaces","kind":256,"children":[23,765,60,286,57,334,331,19,501,64]},{"title":"Type aliases","kind":4194304,"children":[812,811,810,814,813,809,817,818,816,819,815,797,806]},{"title":"Variables","kind":32,"children":[820]},{"title":"Functions","kind":64,"children":[821,803,784,780,794,791]}]} +{"name":"aurelia-validation","children":[{"id":52,"name":"validateTrigger","kind":4,"kindString":"Enumeration","flags":{"isExported":true},"comment":{"shortText":"Validation triggers."},"children":[{"id":54,"name":"blur","kind":16,"kindString":"Enumeration member","flags":{"isExported":true},"comment":{"shortText":"Validate the binding when the binding's target element fires a DOM \"blur\" event."},"sources":[{"fileName":"aurelia-validation.d.ts","line":136,"character":12}],"defaultValue":"1"},{"id":55,"name":"change","kind":16,"kindString":"Enumeration member","flags":{"isExported":true},"comment":{"shortText":"Validate the binding when it updates the model due to a change in the view."},"sources":[{"fileName":"aurelia-validation.d.ts","line":140,"character":14}],"defaultValue":"2"},{"id":56,"name":"changeOrBlur","kind":16,"kindString":"Enumeration member","flags":{"isExported":true},"comment":{"shortText":"Validate the binding when the binding's target element fires a DOM \"blur\" event and\nwhen it updates the model due to a change in the view."},"sources":[{"fileName":"aurelia-validation.d.ts","line":145,"character":20}],"defaultValue":"3"},{"id":53,"name":"manual","kind":16,"kindString":"Enumeration member","flags":{"isExported":true},"comment":{"shortText":"Manual validation. Use the controller's `validate()` and `reset()` methods\nto validate all bindings."},"sources":[{"fileName":"aurelia-validation.d.ts","line":132,"character":14}],"defaultValue":"0"}],"groups":[{"title":"Enumeration members","kind":16,"children":[54,55,56,53]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":127,"character":31}]},{"id":732,"name":"AureliaValidationConfiguration","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Aurelia Validation Configuration API"},"children":[{"id":733,"name":"validatorType","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":959,"character":29}],"type":{"type":"intrinsic","name":"any"}},{"id":741,"name":"apply","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":742,"name":"apply","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the configuration."},"parameters":[{"id":743,"name":"container","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Container"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":969,"character":13}]},{"id":734,"name":"customValidator","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":735,"name":"customValidator","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Use a custom Validator implementation."},"parameters":[{"id":736,"name":"type","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reflection","declaration":{"id":737,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"children":[{"id":738,"name":"constructor","kind":512,"kindString":"Constructor","flags":{},"signatures":[{"id":739,"name":"new __type","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":740,"name":"args","kind":32768,"kindString":"Parameter","flags":{"isRest":true},"type":{"type":"array","elementType":{"type":"intrinsic","name":"any"}}}],"type":{"type":"reference","name":"Validator","id":38}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":963,"character":31}]}],"groups":[{"title":"Constructors","kind":512,"children":[738]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":963,"character":29}]}}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":963,"character":23}]}],"groups":[{"title":"Properties","kind":1024,"children":[733]},{"title":"Methods","kind":2048,"children":[741,734]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":958,"character":47}]},{"id":350,"name":"ExpressionVisitor","kind":128,"kindString":"Class","flags":{"isExported":true},"children":[{"id":405,"name":"visitArgs","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":579,"character":25}],"type":{"type":"intrinsic","name":"any"}},{"id":375,"name":"visitAccessKeyed","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":376,"name":"visitAccessKeyed","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":377,"name":"access","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"AccessKeyed"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":569,"character":24}]},{"id":372,"name":"visitAccessMember","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":373,"name":"visitAccessMember","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":374,"name":"access","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"AccessMember"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":568,"character":25}]},{"id":369,"name":"visitAccessScope","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":370,"name":"visitAccessScope","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":371,"name":"access","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"AccessScope"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":567,"character":24}]},{"id":366,"name":"visitAccessThis","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":367,"name":"visitAccessThis","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":368,"name":"access","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"AccessThis","id":775}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":566,"character":23}]},{"id":360,"name":"visitAssign","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":361,"name":"visitAssign","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":362,"name":"assign","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Assign","id":774}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":564,"character":19}]},{"id":390,"name":"visitBinary","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":391,"name":"visitBinary","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":392,"name":"binary","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Binary"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":574,"character":19}]},{"id":354,"name":"visitBindingBehavior","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":355,"name":"visitBindingBehavior","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":356,"name":"behavior","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"BindingBehavior"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":562,"character":28}]},{"id":381,"name":"visitCallFunction","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":382,"name":"visitCallFunction","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":383,"name":"call","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"CallFunction","id":778}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":571,"character":25}]},{"id":384,"name":"visitCallMember","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":385,"name":"visitCallMember","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":386,"name":"call","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"CallMember"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":572,"character":23}]},{"id":378,"name":"visitCallScope","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":379,"name":"visitCallScope","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":380,"name":"call","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"CallScope","id":777}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":570,"character":22}]},{"id":351,"name":"visitChain","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":352,"name":"visitChain","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":353,"name":"chain","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Chain","id":773}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":561,"character":18}]},{"id":363,"name":"visitConditional","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":364,"name":"visitConditional","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":365,"name":"conditional","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Conditional"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":565,"character":24}]},{"id":396,"name":"visitLiteralArray","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":397,"name":"visitLiteralArray","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":398,"name":"literal","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"LiteralArray","id":781}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":576,"character":25}]},{"id":399,"name":"visitLiteralObject","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":400,"name":"visitLiteralObject","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":401,"name":"literal","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"LiteralObject","id":782}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":577,"character":26}]},{"id":393,"name":"visitLiteralPrimitive","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":394,"name":"visitLiteralPrimitive","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":395,"name":"literal","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"LiteralPrimitive","id":780}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":575,"character":29}]},{"id":402,"name":"visitLiteralString","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":403,"name":"visitLiteralString","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":404,"name":"literal","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"LiteralString","id":783}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":578,"character":26}]},{"id":387,"name":"visitPrefix","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":388,"name":"visitPrefix","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":389,"name":"prefix","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"PrefixNot","id":779}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":573,"character":19}]},{"id":357,"name":"visitValueConverter","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":358,"name":"visitValueConverter","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":359,"name":"converter","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ValueConverter"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":563,"character":27}]}],"groups":[{"title":"Properties","kind":1024,"children":[405]},{"title":"Methods","kind":2048,"children":[375,372,369,366,360,390,354,381,384,378,351,363,396,399,393,402,387,357]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":560,"character":34}],"extendedBy":[{"type":"reference","name":"MessageExpressionValidator","id":420}]},{"id":673,"name":"FluentEnsure","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Part of the fluent rule API. Enables targeting properties and objects with rules."},"typeParameter":[{"id":674,"name":"TObject","kind":131072,"kindString":"Type parameter","flags":{}}],"children":[{"id":677,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":678,"name":"new FluentEnsure","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":679,"name":"parsers","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Parsers","id":729}}],"type":{"type":"reference","name":"FluentEnsure","id":673}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":867,"character":38}]},{"id":689,"name":"assertInitialized","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":884,"character":33}],"type":{"type":"intrinsic","name":"any"}},{"id":690,"name":"mergeRules","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":885,"character":26}],"type":{"type":"intrinsic","name":"any"}},{"id":675,"name":"parsers","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":863,"character":23}],"type":{"type":"intrinsic","name":"any"}},{"id":676,"name":"rules","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"Rules that have been defined using the fluent API."},"sources":[{"fileName":"aurelia-validation.d.ts","line":867,"character":13}],"type":{"type":"array","elementType":{"type":"array","elementType":{"type":"reference","name":"Rule","id":320,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"intrinsic","name":"any"}]}}}},{"id":680,"name":"ensure","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":681,"name":"ensure","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Target a property with validation rules."},"typeParameter":[{"id":682,"name":"TValue","kind":131072,"kindString":"Type parameter","flags":{}}],"parameters":[{"id":683,"name":"property","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The property to target. Can be the property name or a property accessor\nfunction.\n"},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"number"},{"type":"reference","name":"PropertyAccessor","id":761,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}]}}],"type":{"type":"reference","name":"FluentRules","id":609,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"intrinsic","name":"any"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":874,"character":14}]},{"id":684,"name":"ensureObject","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":685,"name":"ensureObject","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Targets an object with validation rules."},"type":{"type":"reference","name":"FluentRules","id":609,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"intrinsic","name":"any"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":878,"character":20}]},{"id":686,"name":"on","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":687,"name":"on","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the rules to a class or object, making them discoverable by the StandardValidator."},"parameters":[{"id":688,"name":"target","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"A class or object.\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"this"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":883,"character":10}]}],"groups":[{"title":"Constructors","kind":512,"children":[677]},{"title":"Properties","kind":1024,"children":[689,690,675,676]},{"title":"Methods","kind":2048,"children":[680,684,686]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":862,"character":29}]},{"id":526,"name":"FluentRuleCustomizer","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Part of the fluent rule API. Enables customizing property rules."},"typeParameter":[{"id":527,"name":"TObject","kind":131072,"kindString":"Type parameter","flags":{}},{"id":528,"name":"TValue","kind":131072,"kindString":"Type parameter","flags":{}}],"children":[{"id":533,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":534,"name":"new FluentRuleCustomizer","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":535,"name":"property","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"RuleProperty","id":317}},{"id":536,"name":"condition","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reflection","declaration":{"id":537,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":538,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":539,"name":"value","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TValue"}},{"id":540,"name":"object","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"reference","name":"TObject","id":527}}],"type":{"type":"union","types":[{"type":"intrinsic","name":"boolean"},{"type":"reference","name":"Promise","typeArguments":[{"type":"intrinsic","name":"boolean"}]}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":681,"character":54}]}}},{"id":541,"name":"config","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"union","types":[{"type":"intrinsic","name":"any"},{"type":"intrinsic","name":"undefined"}]}},{"id":542,"name":"fluentEnsure","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"FluentEnsure","id":673,"typeArguments":[{"type":"typeParameter","name":"TObject"}]}},{"id":543,"name":"fluentRules","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"FluentRules","id":609,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}},{"id":544,"name":"parsers","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Parsers","id":729}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":526}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":680,"character":21}]},{"id":529,"name":"fluentEnsure","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":677,"character":28}],"type":{"type":"intrinsic","name":"any"}},{"id":530,"name":"fluentRules","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":678,"character":27}],"type":{"type":"intrinsic","name":"any"}},{"id":531,"name":"parsers","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":679,"character":23}],"type":{"type":"intrinsic","name":"any"}},{"id":532,"name":"rule","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":680,"character":20}],"type":{"type":"intrinsic","name":"any"}},{"id":571,"name":"rules","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"Rules that have been defined using the fluent API."},"sources":[{"fileName":"aurelia-validation.d.ts","line":719,"character":22}],"type":{"type":"array","elementType":{"type":"array","elementType":{"type":"reference","name":"Rule","id":320,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"intrinsic","name":"any"}]}}}},{"id":592,"name":"email","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":593,"name":"email","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"email\" rule to the property.\nnull, undefined and empty-string values are considered valid."},"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":753,"character":13}]},{"id":562,"name":"ensure","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":563,"name":"ensure","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Target a property with validation rules."},"typeParameter":[{"id":564,"name":"TValue2","kind":131072,"kindString":"Type parameter","flags":{}}],"parameters":[{"id":565,"name":"subject","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"reflection","declaration":{"id":566,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":567,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":568,"name":"model","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TObject"}}],"type":{"type":"typeParameter","name":"TValue2"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":711,"character":41}]}}]}}],"type":{"type":"reference","name":"FluentRules","id":609,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"intrinsic","name":"any"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":711,"character":14}]},{"id":569,"name":"ensureObject","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":570,"name":"ensureObject","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Targets an object with validation rules."},"type":{"type":"reference","name":"FluentRules","id":609,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"intrinsic","name":"any"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":715,"character":20}]},{"id":606,"name":"equals","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":607,"name":"equals","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"equals\" validation rule to the property.\nnull, undefined and empty-string values are considered valid."},"parameters":[{"id":608,"name":"expectedValue","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TValue"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":778,"character":14}]},{"id":589,"name":"matches","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":590,"name":"matches","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"matches\" rule to the property.\nValue must match the specified regular expression.\nnull, undefined and empty-string values are considered valid."},"parameters":[{"id":591,"name":"regex","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"RegExp"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":748,"character":15}]},{"id":603,"name":"maxItems","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":604,"name":"maxItems","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"maxItems\" ARRAY validation rule to the property.\nnull and undefined values are considered valid."},"parameters":[{"id":605,"name":"count","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":773,"character":16}]},{"id":597,"name":"maxLength","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":598,"name":"maxLength","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"maxLength\" STRING validation rule to the property.\nnull, undefined and empty-string values are considered valid."},"parameters":[{"id":599,"name":"length","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":763,"character":17}]},{"id":600,"name":"minItems","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":601,"name":"minItems","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"minItems\" ARRAY validation rule to the property.\nnull and undefined values are considered valid."},"parameters":[{"id":602,"name":"count","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":768,"character":16}]},{"id":594,"name":"minLength","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":595,"name":"minLength","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"minLength\" STRING validation rule to the property.\nnull, undefined and empty-string values are considered valid."},"parameters":[{"id":596,"name":"length","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":758,"character":17}]},{"id":572,"name":"on","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":573,"name":"on","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the rules to a class or object, making them discoverable by the StandardValidator."},"parameters":[{"id":574,"name":"target","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"A class or object.\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"reference","name":"FluentEnsure","id":673,"typeArguments":[{"type":"typeParameter","name":"TObject"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":724,"character":10}]},{"id":587,"name":"required","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":588,"name":"required","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"required\" rule to the property.\nThe value cannot be null, undefined or whitespace."},"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":742,"character":16}]},{"id":575,"name":"satisfies","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":576,"name":"satisfies","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies an ad-hoc rule function to the ensured property or object."},"parameters":[{"id":577,"name":"condition","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The function to validate the rule.\nWill be called with two arguments, the property value and the object.\nShould return a boolean or a Promise that resolves to a boolean.\n"},"type":{"type":"reflection","declaration":{"id":578,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":579,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":580,"name":"value","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TValue"}},{"id":581,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TObject"}}],"type":{"type":"union","types":[{"type":"intrinsic","name":"boolean"},{"type":"reference","name":"Promise","typeArguments":[{"type":"intrinsic","name":"boolean"}]}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":731,"character":28}]}}},{"id":582,"name":"config","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"intrinsic","name":"undefined"},{"type":"intrinsic","name":"object"}]}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":731,"character":17}]},{"id":583,"name":"satisfiesRule","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":584,"name":"satisfiesRule","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies a rule by name."},"parameters":[{"id":585,"name":"name","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The name of the custom or standard rule."},"type":{"type":"intrinsic","name":"string"}},{"id":586,"name":"args","kind":32768,"kindString":"Parameter","flags":{"isRest":true},"comment":{"text":"The rule's arguments.\n"},"type":{"type":"array","elementType":{"type":"intrinsic","name":"any"}}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":737,"character":21}]},{"id":559,"name":"tag","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":560,"name":"tag","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Tags the rule instance, enabling the rule to be found easily\nusing ValidationRules.taggedRules(rules, tag)"},"parameters":[{"id":561,"name":"tag","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"intrinsic","name":"this"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":706,"character":11}]},{"id":545,"name":"then","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":546,"name":"then","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Validate subsequent rules after previously declared rules have\nbeen validated successfully. Use to postpone validation of costly\nrules until less expensive rules pass validation."},"type":{"type":"intrinsic","name":"this"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":687,"character":12}]},{"id":553,"name":"when","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":554,"name":"when","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Specifies a condition that must be met before attempting to validate the rule."},"parameters":[{"id":555,"name":"condition","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"A function that accepts the object as a parameter and returns true\nor false whether the rule should be evaluated.\n"},"type":{"type":"reflection","declaration":{"id":556,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":557,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":558,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TObject"}}],"type":{"type":"intrinsic","name":"boolean"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":701,"character":23}]}}}],"type":{"type":"intrinsic","name":"this"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":701,"character":12}]},{"id":550,"name":"withMessage","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":551,"name":"withMessage","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Specifies rule's validation message."},"parameters":[{"id":552,"name":"message","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"intrinsic","name":"this"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":695,"character":19}]},{"id":547,"name":"withMessageKey","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":548,"name":"withMessageKey","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Specifies the key to use when looking up the rule's validation message."},"parameters":[{"id":549,"name":"key","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"intrinsic","name":"this"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":691,"character":22}]}],"groups":[{"title":"Constructors","kind":512,"children":[533]},{"title":"Properties","kind":1024,"children":[529,530,531,532,571]},{"title":"Methods","kind":2048,"children":[592,562,569,606,589,603,597,600,594,572,587,575,583,559,545,553,550,547]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":676,"character":37}]},{"id":609,"name":"FluentRules","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Part of the fluent rule API. Enables applying rules to properties and objects."},"typeParameter":[{"id":610,"name":"TObject","kind":131072,"kindString":"Type parameter","flags":{}},{"id":611,"name":"TValue","kind":131072,"kindString":"Type parameter","flags":{}}],"children":[{"id":631,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":632,"name":"new FluentRules","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":633,"name":"fluentEnsure","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"FluentEnsure","id":673,"typeArguments":[{"type":"typeParameter","name":"TObject"}]}},{"id":634,"name":"parsers","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Parsers","id":729}},{"id":635,"name":"property","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"RuleProperty","id":317}}],"type":{"type":"reference","name":"FluentRules","id":609}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":798,"character":25}]},{"id":612,"name":"fluentEnsure","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":784,"character":28}],"type":{"type":"intrinsic","name":"any"}},{"id":613,"name":"parsers","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":785,"character":23}],"type":{"type":"intrinsic","name":"any"}},{"id":614,"name":"property","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":786,"character":24}],"type":{"type":"intrinsic","name":"any"}},{"id":630,"name":"sequence","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"Current rule sequence number. Used to postpone evaluation of rules until rules\nwith lower sequence number have successfully validated. The \"then\" fluent API method\nmanages this property, there's usually no need to set it directly."},"sources":[{"fileName":"aurelia-validation.d.ts","line":798,"character":16}],"type":{"type":"intrinsic","name":"number"}},{"id":615,"name":"customRules","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":787,"character":26}],"type":{"type":"reflection","declaration":{"id":616,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"indexSignature":{"id":617,"name":"__index","kind":8192,"kindString":"Index signature","flags":{},"parameters":[{"id":618,"name":"name","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"reflection","declaration":{"id":619,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"children":[{"id":626,"name":"argsToConfig","kind":32,"kindString":"Variable","flags":{"isOptional":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":790,"character":28}],"type":{"type":"union","types":[{"type":"intrinsic","name":"undefined"},{"type":"reflection","declaration":{"id":627,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":628,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":629,"name":"args","kind":32768,"kindString":"Parameter","flags":{"isRest":true},"type":{"type":"array","elementType":{"type":"intrinsic","name":"any"}}}],"type":{"type":"intrinsic","name":"any"}}]}}]}},{"id":620,"name":"condition","kind":32,"kindString":"Variable","flags":{},"sources":[{"fileName":"aurelia-validation.d.ts","line":789,"character":25}],"type":{"type":"reflection","declaration":{"id":621,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":622,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":623,"name":"value","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":624,"name":"object","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"any"}},{"id":625,"name":"fluentArgs","kind":32768,"kindString":"Parameter","flags":{"isRest":true},"type":{"type":"array","elementType":{"type":"intrinsic","name":"any"}}}],"type":{"type":"union","types":[{"type":"intrinsic","name":"boolean"},{"type":"reference","name":"Promise","typeArguments":[{"type":"intrinsic","name":"boolean"}]}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":789,"character":26}]}}}],"groups":[{"title":"Variables","kind":32,"children":[626,620]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":788,"character":27}]}}},"sources":[{"fileName":"aurelia-validation.d.ts","line":787,"character":27}]}}},{"id":636,"name":"displayName","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":637,"name":"displayName","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Sets the display name of the ensured property."},"parameters":[{"id":638,"name":"name","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"reference","name":"ValidationDisplayNameAccessor","id":770},{"type":"intrinsic","name":"null"}]}}],"type":{"type":"intrinsic","name":"this"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":803,"character":19}]},{"id":656,"name":"email","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":657,"name":"email","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"email\" rule to the property.\nnull, undefined and empty-string values are considered valid."},"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":832,"character":13}]},{"id":670,"name":"equals","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":671,"name":"equals","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"equals\" validation rule to the property.\nnull and undefined values are considered valid."},"parameters":[{"id":672,"name":"expectedValue","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TValue"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":857,"character":14}]},{"id":653,"name":"matches","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":654,"name":"matches","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"matches\" rule to the property.\nValue must match the specified regular expression.\nnull, undefined and empty-string values are considered valid."},"parameters":[{"id":655,"name":"regex","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"RegExp"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":827,"character":15}]},{"id":667,"name":"maxItems","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":668,"name":"maxItems","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"maxItems\" ARRAY validation rule to the property.\nnull and undefined values are considered valid."},"parameters":[{"id":669,"name":"count","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":852,"character":16}]},{"id":661,"name":"maxLength","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":662,"name":"maxLength","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"maxLength\" STRING validation rule to the property.\nnull, undefined and empty-string values are considered valid."},"parameters":[{"id":663,"name":"length","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":842,"character":17}]},{"id":664,"name":"minItems","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":665,"name":"minItems","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"minItems\" ARRAY validation rule to the property.\nnull and undefined values are considered valid."},"parameters":[{"id":666,"name":"count","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":847,"character":16}]},{"id":658,"name":"minLength","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":659,"name":"minLength","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"minLength\" STRING validation rule to the property.\nnull, undefined and empty-string values are considered valid."},"parameters":[{"id":660,"name":"length","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":837,"character":17}]},{"id":651,"name":"required","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":652,"name":"required","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the \"required\" rule to the property.\nThe value cannot be null, undefined or whitespace."},"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":821,"character":16}]},{"id":639,"name":"satisfies","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":640,"name":"satisfies","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies an ad-hoc rule function to the ensured property or object."},"parameters":[{"id":641,"name":"condition","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The function to validate the rule.\nWill be called with two arguments, the property value and the object.\nShould return a boolean or a Promise that resolves to a boolean.\n"},"type":{"type":"reflection","declaration":{"id":642,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":643,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":644,"name":"value","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TValue"}},{"id":645,"name":"object","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"reference","name":"TObject","id":610}}],"type":{"type":"union","types":[{"type":"intrinsic","name":"boolean"},{"type":"reference","name":"Promise","typeArguments":[{"type":"intrinsic","name":"boolean"}]}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":810,"character":28}]}}},{"id":646,"name":"config","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"intrinsic","name":"undefined"},{"type":"intrinsic","name":"object"}]}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":810,"character":17}]},{"id":647,"name":"satisfiesRule","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":648,"name":"satisfiesRule","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies a rule by name."},"parameters":[{"id":649,"name":"name","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The name of the custom or standard rule."},"type":{"type":"intrinsic","name":"string"}},{"id":650,"name":"args","kind":32768,"kindString":"Parameter","flags":{"isRest":true},"comment":{"text":"The rule's arguments.\n"},"type":{"type":"array","elementType":{"type":"intrinsic","name":"any"}}}],"type":{"type":"reference","name":"FluentRuleCustomizer","id":526,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":816,"character":21}]}],"groups":[{"title":"Constructors","kind":512,"children":[631]},{"title":"Properties","kind":1024,"children":[612,613,614,630,615]},{"title":"Methods","kind":2048,"children":[636,656,670,653,667,661,664,658,651,639,647]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":783,"character":28}]},{"id":420,"name":"MessageExpressionValidator","kind":128,"kindString":"Class","flags":{"isExported":true},"children":[{"id":426,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":427,"name":"new MessageExpressionValidator","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":428,"name":"originalMessage","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"reference","name":"MessageExpressionValidator","id":420}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":597,"character":79}]},{"id":421,"name":"originalMessage","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":596,"character":31}],"type":{"type":"intrinsic","name":"any"}},{"id":453,"name":"visitAccessKeyed","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":454,"name":"visitAccessKeyed","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":455,"name":"access","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"AccessKeyed"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitAccessKeyed","id":375}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":569,"character":24}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitAccessKeyed","id":375}},{"id":450,"name":"visitAccessMember","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":451,"name":"visitAccessMember","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":452,"name":"access","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"AccessMember"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitAccessMember","id":372}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":568,"character":25}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitAccessMember","id":372}},{"id":429,"name":"visitAccessScope","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":430,"name":"visitAccessScope","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":431,"name":"access","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"AccessScope"}}],"type":{"type":"intrinsic","name":"void"},"overwrites":{"type":"reference","name":"ExpressionVisitor.visitAccessScope","id":369}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":599,"character":24}],"overwrites":{"type":"reference","name":"ExpressionVisitor.visitAccessScope","id":369}},{"id":447,"name":"visitAccessThis","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":448,"name":"visitAccessThis","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":449,"name":"access","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"AccessThis","id":775}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitAccessThis","id":366}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":566,"character":23}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitAccessThis","id":366}},{"id":441,"name":"visitAssign","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":442,"name":"visitAssign","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":443,"name":"assign","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Assign","id":774}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitAssign","id":360}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":564,"character":19}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitAssign","id":360}},{"id":468,"name":"visitBinary","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":469,"name":"visitBinary","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":470,"name":"binary","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Binary"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitBinary","id":390}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":574,"character":19}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitBinary","id":390}},{"id":435,"name":"visitBindingBehavior","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":436,"name":"visitBindingBehavior","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":437,"name":"behavior","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"BindingBehavior"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitBindingBehavior","id":354}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":562,"character":28}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitBindingBehavior","id":354}},{"id":459,"name":"visitCallFunction","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":460,"name":"visitCallFunction","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":461,"name":"call","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"CallFunction","id":778}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitCallFunction","id":381}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":571,"character":25}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitCallFunction","id":381}},{"id":462,"name":"visitCallMember","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":463,"name":"visitCallMember","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":464,"name":"call","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"CallMember"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitCallMember","id":384}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":572,"character":23}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitCallMember","id":384}},{"id":456,"name":"visitCallScope","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":457,"name":"visitCallScope","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":458,"name":"call","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"CallScope","id":777}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitCallScope","id":378}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":570,"character":22}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitCallScope","id":378}},{"id":432,"name":"visitChain","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":433,"name":"visitChain","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":434,"name":"chain","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Chain","id":773}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitChain","id":351}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":561,"character":18}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitChain","id":351}},{"id":444,"name":"visitConditional","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":445,"name":"visitConditional","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":446,"name":"conditional","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Conditional"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitConditional","id":363}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":565,"character":24}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitConditional","id":363}},{"id":474,"name":"visitLiteralArray","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":475,"name":"visitLiteralArray","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":476,"name":"literal","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"LiteralArray","id":781}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitLiteralArray","id":396}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":576,"character":25}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitLiteralArray","id":396}},{"id":477,"name":"visitLiteralObject","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":478,"name":"visitLiteralObject","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":479,"name":"literal","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"LiteralObject","id":782}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitLiteralObject","id":399}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":577,"character":26}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitLiteralObject","id":399}},{"id":471,"name":"visitLiteralPrimitive","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":472,"name":"visitLiteralPrimitive","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":473,"name":"literal","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"LiteralPrimitive","id":780}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitLiteralPrimitive","id":393}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":575,"character":29}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitLiteralPrimitive","id":393}},{"id":480,"name":"visitLiteralString","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":481,"name":"visitLiteralString","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":482,"name":"literal","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"LiteralString","id":783}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitLiteralString","id":402}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":578,"character":26}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitLiteralString","id":402}},{"id":465,"name":"visitPrefix","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":466,"name":"visitPrefix","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":467,"name":"prefix","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"PrefixNot","id":779}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitPrefix","id":387}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":573,"character":19}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitPrefix","id":387}},{"id":438,"name":"visitValueConverter","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":439,"name":"visitValueConverter","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":440,"name":"converter","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ValueConverter"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitValueConverter","id":357}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":563,"character":27}],"inheritedFrom":{"type":"reference","name":"ExpressionVisitor.visitValueConverter","id":357}},{"id":422,"name":"validate","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":423,"name":"validate","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":424,"name":"expression","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Expression"}},{"id":425,"name":"originalMessage","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":597,"character":23}]}],"groups":[{"title":"Constructors","kind":512,"children":[426]},{"title":"Properties","kind":1024,"children":[421]},{"title":"Methods","kind":2048,"children":[453,450,429,447,441,468,435,459,462,456,432,444,474,477,471,480,465,438,422]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":595,"character":43}],"extendedTypes":[{"type":"reference","name":"ExpressionVisitor","id":350}]},{"id":27,"name":"PropertyAccessorParser","kind":128,"kindString":"Class","flags":{"isExported":true},"children":[{"id":30,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":31,"name":"new PropertyAccessorParser","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":32,"name":"parser","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Parser"}}],"type":{"type":"reference","name":"PropertyAccessorParser","id":27}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":91,"character":41}]},{"id":28,"name":"parser","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":90,"character":22}],"type":{"type":"intrinsic","name":"any"}},{"id":29,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":91,"character":21}],"type":{"type":"array","elementType":{"type":"reference","name":"Parser"}}},{"id":33,"name":"parse","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":34,"name":"parse","kind":4096,"kindString":"Call signature","flags":{},"typeParameter":[{"id":35,"name":"TObject","kind":131072,"kindString":"Type parameter","flags":{}},{"id":36,"name":"TValue","kind":131072,"kindString":"Type parameter","flags":{}}],"parameters":[{"id":37,"name":"property","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"number"},{"type":"reference","name":"PropertyAccessor","id":761,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}]}}],"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"number"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":93,"character":13}]}],"groups":[{"title":"Constructors","kind":512,"children":[30]},{"title":"Properties","kind":1024,"children":[28,29]},{"title":"Methods","kind":2048,"children":[33]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":89,"character":39}]},{"id":338,"name":"Rules","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Sets, unsets and retrieves rules on an object or constructor function."},"children":[{"id":339,"name":"key","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isPrivate":true,"isExported":true},"comment":{"shortText":"The name of the property that stores the rules."},"sources":[{"fileName":"aurelia-validation.d.ts","line":534,"character":26}],"type":{"type":"intrinsic","name":"any"}},{"id":347,"name":"get","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":348,"name":"get","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Retrieves the target's rules."},"parameters":[{"id":349,"name":"target","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"union","types":[{"type":"array","elementType":{"type":"array","elementType":{"type":"reference","name":"Rule","id":320,"typeArguments":[{"type":"intrinsic","name":"any"},{"type":"intrinsic","name":"any"}]}}},{"type":"intrinsic","name":"null"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":546,"character":18}]},{"id":340,"name":"set","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":341,"name":"set","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Applies the rules to a target."},"parameters":[{"id":342,"name":"target","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":343,"name":"rules","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"array","elementType":{"type":"array","elementType":{"type":"reference","name":"Rule","id":320,"typeArguments":[{"type":"intrinsic","name":"any"},{"type":"intrinsic","name":"any"}]}}}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":538,"character":18}]},{"id":344,"name":"unset","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":345,"name":"unset","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Removes rules from a target."},"parameters":[{"id":346,"name":"target","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":542,"character":20}]}],"groups":[{"title":"Properties","kind":1024,"children":[339]},{"title":"Methods","kind":2048,"children":[347,340,344]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":530,"character":22}]},{"id":501,"name":"StandardValidator","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Validates.\nResponsible for validating objects and properties."},"children":[{"id":506,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":507,"name":"new StandardValidator","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":508,"name":"messageProvider","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ValidationMessageProvider","id":486}},{"id":509,"name":"resources","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ViewResources"}}],"type":{"type":"reference","name":"StandardValidator","id":501}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":643,"character":31}]},{"id":505,"name":"getDisplayName","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":643,"character":30}],"type":{"type":"intrinsic","name":"any"}},{"id":523,"name":"getMessage","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":666,"character":26}],"type":{"type":"intrinsic","name":"any"}},{"id":504,"name":"lookupFunctions","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":642,"character":31}],"type":{"type":"intrinsic","name":"any"}},{"id":503,"name":"messageProvider","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":641,"character":31}],"type":{"type":"intrinsic","name":"any"}},{"id":525,"name":"validate","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":668,"character":24}],"type":{"type":"intrinsic","name":"any"}},{"id":524,"name":"validateRuleSequence","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":667,"character":36}],"type":{"type":"intrinsic","name":"any"}},{"id":502,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":640,"character":21}],"type":{"type":"array","elementType":{"type":"union","types":[{"type":"reference","name":"ViewResources"},{"type":"reference","name":"ValidationMessageProvider","id":486}]}}},{"id":519,"name":"ruleExists","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":520,"name":"ruleExists","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Determines whether a rule exists in a set of rules.","tags":[{"tag":"parem","text":"rule The rule to find.\n"}]},"parameters":[{"id":521,"name":"rules","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The rules to search."},"type":{"type":"array","elementType":{"type":"array","elementType":{"type":"reference","name":"Rule","id":320,"typeArguments":[{"type":"intrinsic","name":"any"},{"type":"intrinsic","name":"any"}]}}}},{"id":522,"name":"rule","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Rule","id":320,"typeArguments":[{"type":"intrinsic","name":"any"},{"type":"intrinsic","name":"any"}]}}],"type":{"type":"intrinsic","name":"boolean"},"overwrites":{"type":"reference","name":"Validator.ruleExists","id":48}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":665,"character":18}],"overwrites":{"type":"reference","name":"Validator.ruleExists","id":48}},{"id":515,"name":"validateObject","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":516,"name":"validateObject","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Validates all rules for specified object and it's properties."},"parameters":[{"id":517,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The object to validate."},"type":{"type":"intrinsic","name":"any"}},{"id":518,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"comment":{"text":"Optional. If unspecified, the rules will be looked up using the metadata\nfor the object created by ValidationRules....on(class/object)\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"reference","name":"Promise","typeArguments":[{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}]},"overwrites":{"type":"reference","name":"Validator.validateObject","id":44}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":659,"character":22}],"overwrites":{"type":"reference","name":"Validator.validateObject","id":44}},{"id":510,"name":"validateProperty","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":511,"name":"validateProperty","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Validates the specified property."},"parameters":[{"id":512,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The object to validate."},"type":{"type":"intrinsic","name":"any"}},{"id":513,"name":"propertyName","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The name of the property to validate."},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"number"}]}},{"id":514,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"comment":{"text":"Optional. If unspecified, the rules will be looked up using the metadata\nfor the object created by ValidationRules....on(class/object)\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"reference","name":"Promise","typeArguments":[{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}]},"overwrites":{"type":"reference","name":"Validator.validateProperty","id":39}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":652,"character":24}],"overwrites":{"type":"reference","name":"Validator.validateProperty","id":39}}],"groups":[{"title":"Constructors","kind":512,"children":[506]},{"title":"Properties","kind":1024,"children":[505,523,504,503,525,524,502]},{"title":"Methods","kind":2048,"children":[519,515,510]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":639,"character":34}],"extendedTypes":[{"type":"reference","name":"Validator","id":38}]},{"id":177,"name":"ValidateBindingBehavior","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Binding behavior. Indicates the bound property should be validated\nwhen the validate trigger specified by the associated controller's\nvalidateTrigger property occurs."},"children":[{"id":182,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":183,"name":"new ValidateBindingBehavior","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":184,"name":"taskQueue","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"TaskQueue"}}],"type":{"type":"reference","name":"ValidateBindingBehavior","id":177},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":162}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":389,"character":26}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":162}},{"id":178,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":405,"character":21}],"type":{"type":"array","elementType":{"type":"reference","name":"TaskQueue"}}},{"id":185,"name":"bind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":186,"name":"bind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":187,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":188,"name":"source","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":189,"name":"rulesOrController","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"reference","name":"ValidationController","id":81},{"type":"intrinsic","name":"any"}]}},{"id":190,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":168}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":392,"character":12}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":168}},{"id":179,"name":"getValidateTrigger","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":180,"name":"getValidateTrigger","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":181,"name":"controller","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ValidationController","id":81}}],"type":{"type":"reference","name":"validateTrigger","id":52},"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":165}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":406,"character":26}],"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":165}},{"id":191,"name":"unbind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":192,"name":"unbind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":193,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":174}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":393,"character":14}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":174}}],"groups":[{"title":"Constructors","kind":512,"children":[182]},{"title":"Properties","kind":1024,"children":[178]},{"title":"Methods","kind":2048,"children":[185,179,191]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":404,"character":40}],"extendedTypes":[{"type":"reference","name":"ValidateBindingBehaviorBase","id":160}]},{"id":160,"name":"ValidateBindingBehaviorBase","kind":128,"kindString":"Class","flags":{"isExported":true,"isAbstract":true},"comment":{"shortText":"Binding behavior. Indicates the bound property should be validated."},"children":[{"id":162,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":163,"name":"new ValidateBindingBehaviorBase","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":164,"name":"taskQueue","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"TaskQueue"}}],"type":{"type":"reference","name":"ValidateBindingBehaviorBase","id":160}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":389,"character":26}]},{"id":161,"name":"taskQueue","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":389,"character":25}],"type":{"type":"intrinsic","name":"any"}},{"id":168,"name":"bind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":169,"name":"bind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":170,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":171,"name":"source","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":172,"name":"rulesOrController","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"reference","name":"ValidationController","id":81},{"type":"intrinsic","name":"any"}]}},{"id":173,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":392,"character":12}]},{"id":165,"name":"getValidateTrigger","kind":2048,"kindString":"Method","flags":{"isExported":true,"isProtected":true,"isAbstract":true},"signatures":[{"id":166,"name":"getValidateTrigger","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":167,"name":"controller","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ValidationController","id":81}}],"type":{"type":"reference","name":"validateTrigger","id":52}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":391,"character":45}]},{"id":174,"name":"unbind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":175,"name":"unbind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":176,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":393,"character":14}]}],"groups":[{"title":"Constructors","kind":512,"children":[162]},{"title":"Properties","kind":1024,"children":[161]},{"title":"Methods","kind":2048,"children":[168,165,174]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":388,"character":53}],"extendedBy":[{"type":"reference","name":"ValidateBindingBehavior","id":177},{"type":"reference","name":"ValidateManuallyBindingBehavior","id":194},{"type":"reference","name":"ValidateOnBlurBindingBehavior","id":210},{"type":"reference","name":"ValidateOnChangeBindingBehavior","id":226},{"type":"reference","name":"ValidateOnChangeOrBlurBindingBehavior","id":242}]},{"id":68,"name":"ValidateEvent","kind":128,"kindString":"Class","flags":{"isExported":true},"children":[{"id":74,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":75,"name":"new ValidateEvent","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":76,"name":"type","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"union","types":[{"type":"stringLiteral","value":"validate"},{"type":"stringLiteral","value":"reset"}]}},{"id":77,"name":"errors","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}},{"id":78,"name":"results","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}},{"id":79,"name":"instruction","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"union","types":[{"type":"reference","name":"ValidateInstruction","id":19},{"type":"intrinsic","name":"null"}]}},{"id":80,"name":"controllerValidateResult","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"union","types":[{"type":"reference","name":"ControllerValidateResult","id":23},{"type":"intrinsic","name":"null"}]}}],"type":{"type":"reference","name":"ValidateEvent","id":68}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":220,"character":75}]},{"id":73,"name":"controllerValidateResult","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"In events with type === \"validate\", this property will contain the result\nof validating the instruction (see \"instruction\" property). Use the controllerValidateResult\nto access the validate results specific to the call to \"validate\"\n(as opposed to using the \"results\" and \"errors\" properties to access the controller's entire\nset of results/errors)."},"sources":[{"fileName":"aurelia-validation.d.ts","line":220,"character":41}],"type":{"type":"union","types":[{"type":"reference","name":"ControllerValidateResult","id":23},{"type":"intrinsic","name":"null"}]}},{"id":70,"name":"errors","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The controller's current array of errors. For an array containing both\nfailed rules and passed rules, use the \"results\" property."},"sources":[{"fileName":"aurelia-validation.d.ts","line":201,"character":23}],"type":{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}},{"id":72,"name":"instruction","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The instruction passed to the \"validate\" or \"reset\" event. Will be null when\nthe controller's validate/reset method was called with no instruction argument."},"sources":[{"fileName":"aurelia-validation.d.ts","line":212,"character":28}],"type":{"type":"union","types":[{"type":"reference","name":"ValidateInstruction","id":19},{"type":"intrinsic","name":"null"}]}},{"id":71,"name":"results","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The controller's current array of validate results. This\nincludes both passed rules and failed rules. For an array of only failed rules,\nuse the \"errors\" property."},"sources":[{"fileName":"aurelia-validation.d.ts","line":207,"character":24}],"type":{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}},{"id":69,"name":"type","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The type of validate event. Either \"validate\" or \"reset\"."},"sources":[{"fileName":"aurelia-validation.d.ts","line":196,"character":21}],"type":{"type":"union","types":[{"type":"stringLiteral","value":"validate"},{"type":"stringLiteral","value":"reset"}]}}],"groups":[{"title":"Constructors","kind":512,"children":[74]},{"title":"Properties","kind":1024,"children":[73,70,72,71,69]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":192,"character":30}]},{"id":194,"name":"ValidateManuallyBindingBehavior","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Binding behavior. Indicates the bound property will be validated\nmanually, by calling controller.validate(). No automatic validation\ntriggered by data-entry or blur will occur."},"children":[{"id":198,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":199,"name":"new ValidateManuallyBindingBehavior","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":200,"name":"taskQueue","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"TaskQueue"}}],"type":{"type":"reference","name":"ValidateManuallyBindingBehavior","id":194},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":162}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":389,"character":26}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":162}},{"id":195,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":414,"character":21}],"type":{"type":"array","elementType":{"type":"reference","name":"TaskQueue"}}},{"id":201,"name":"bind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":202,"name":"bind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":203,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":204,"name":"source","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":205,"name":"rulesOrController","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"reference","name":"ValidationController","id":81},{"type":"intrinsic","name":"any"}]}},{"id":206,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":168}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":392,"character":12}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":168}},{"id":196,"name":"getValidateTrigger","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":197,"name":"getValidateTrigger","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"reference","name":"validateTrigger","id":52},"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":165}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":415,"character":26}],"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":165}},{"id":207,"name":"unbind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":208,"name":"unbind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":209,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":174}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":393,"character":14}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":174}}],"groups":[{"title":"Constructors","kind":512,"children":[198]},{"title":"Properties","kind":1024,"children":[195]},{"title":"Methods","kind":2048,"children":[201,196,207]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":413,"character":48}],"extendedTypes":[{"type":"reference","name":"ValidateBindingBehaviorBase","id":160}]},{"id":210,"name":"ValidateOnBlurBindingBehavior","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Binding behavior. Indicates the bound property should be validated\nwhen the associated element blurs."},"children":[{"id":214,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":215,"name":"new ValidateOnBlurBindingBehavior","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":216,"name":"taskQueue","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"TaskQueue"}}],"type":{"type":"reference","name":"ValidateOnBlurBindingBehavior","id":210},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":162}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":389,"character":26}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":162}},{"id":211,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":422,"character":21}],"type":{"type":"array","elementType":{"type":"reference","name":"TaskQueue"}}},{"id":217,"name":"bind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":218,"name":"bind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":219,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":220,"name":"source","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":221,"name":"rulesOrController","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"reference","name":"ValidationController","id":81},{"type":"intrinsic","name":"any"}]}},{"id":222,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":168}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":392,"character":12}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":168}},{"id":212,"name":"getValidateTrigger","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":213,"name":"getValidateTrigger","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"reference","name":"validateTrigger","id":52},"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":165}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":423,"character":26}],"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":165}},{"id":223,"name":"unbind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":224,"name":"unbind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":225,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":174}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":393,"character":14}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":174}}],"groups":[{"title":"Constructors","kind":512,"children":[214]},{"title":"Properties","kind":1024,"children":[211]},{"title":"Methods","kind":2048,"children":[217,212,223]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":421,"character":46}],"extendedTypes":[{"type":"reference","name":"ValidateBindingBehaviorBase","id":160}]},{"id":226,"name":"ValidateOnChangeBindingBehavior","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Binding behavior. Indicates the bound property should be validated\nwhen the associated element is changed by the user, causing a change\nto the model."},"children":[{"id":230,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":231,"name":"new ValidateOnChangeBindingBehavior","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":232,"name":"taskQueue","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"TaskQueue"}}],"type":{"type":"reference","name":"ValidateOnChangeBindingBehavior","id":226},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":162}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":389,"character":26}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":162}},{"id":227,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":431,"character":21}],"type":{"type":"array","elementType":{"type":"reference","name":"TaskQueue"}}},{"id":233,"name":"bind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":234,"name":"bind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":235,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":236,"name":"source","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":237,"name":"rulesOrController","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"reference","name":"ValidationController","id":81},{"type":"intrinsic","name":"any"}]}},{"id":238,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":168}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":392,"character":12}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":168}},{"id":228,"name":"getValidateTrigger","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":229,"name":"getValidateTrigger","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"reference","name":"validateTrigger","id":52},"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":165}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":432,"character":26}],"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":165}},{"id":239,"name":"unbind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":240,"name":"unbind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":241,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":174}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":393,"character":14}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":174}}],"groups":[{"title":"Constructors","kind":512,"children":[230]},{"title":"Properties","kind":1024,"children":[227]},{"title":"Methods","kind":2048,"children":[233,228,239]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":430,"character":48}],"extendedTypes":[{"type":"reference","name":"ValidateBindingBehaviorBase","id":160}]},{"id":242,"name":"ValidateOnChangeOrBlurBindingBehavior","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Binding behavior. Indicates the bound property should be validated\nwhen the associated element blurs or is changed by the user, causing\na change to the model."},"children":[{"id":246,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":247,"name":"new ValidateOnChangeOrBlurBindingBehavior","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":248,"name":"taskQueue","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"TaskQueue"}}],"type":{"type":"reference","name":"ValidateOnChangeOrBlurBindingBehavior","id":242},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":162}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":389,"character":26}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.__constructor","id":162}},{"id":243,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":440,"character":21}],"type":{"type":"array","elementType":{"type":"reference","name":"TaskQueue"}}},{"id":249,"name":"bind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":250,"name":"bind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":251,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":252,"name":"source","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":253,"name":"rulesOrController","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"reference","name":"ValidationController","id":81},{"type":"intrinsic","name":"any"}]}},{"id":254,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":168}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":392,"character":12}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.bind","id":168}},{"id":244,"name":"getValidateTrigger","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":245,"name":"getValidateTrigger","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"reference","name":"validateTrigger","id":52},"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":165}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":441,"character":26}],"overwrites":{"type":"reference","name":"ValidateBindingBehaviorBase.getValidateTrigger","id":165}},{"id":255,"name":"unbind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":256,"name":"unbind","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":257,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"},"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":174}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":393,"character":14}],"inheritedFrom":{"type":"reference","name":"ValidateBindingBehaviorBase.unbind","id":174}}],"groups":[{"title":"Constructors","kind":512,"children":[246]},{"title":"Properties","kind":1024,"children":[243]},{"title":"Methods","kind":2048,"children":[249,244,255]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":439,"character":54}],"extendedTypes":[{"type":"reference","name":"ValidateBindingBehaviorBase","id":160}]},{"id":2,"name":"ValidateResult","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"The result of validating an individual validation rule."},"children":[{"id":10,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"comment":{},"signatures":[{"id":11,"name":"new ValidateResult","kind":16384,"kindString":"Constructor signature","flags":{},"comment":{},"parameters":[{"id":12,"name":"rule","kind":32768,"kindString":"Parameter","flags":{},"comment":{"shortText":"The rule associated with the result. Validator implementation specific."},"type":{"type":"intrinsic","name":"any"}},{"id":13,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"comment":{"shortText":"The object that was validated."},"type":{"type":"intrinsic","name":"any"}},{"id":14,"name":"propertyName","kind":32768,"kindString":"Parameter","flags":{},"comment":{"shortText":"The name of the property that was validated."},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"number"},{"type":"intrinsic","name":"null"}]}},{"id":15,"name":"valid","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"boolean"}},{"id":16,"name":"message","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"null"}]}}],"type":{"type":"reference","name":"ValidateResult","id":2}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":19,"character":19}]},{"id":9,"name":"id","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"A number that uniquely identifies the result instance."},"sources":[{"fileName":"aurelia-validation.d.ts","line":19,"character":10}],"type":{"type":"intrinsic","name":"number"}},{"id":7,"name":"message","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":14,"character":15}],"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"null"}]}},{"id":4,"name":"object","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":11,"character":14}],"type":{"type":"intrinsic","name":"any"}},{"id":5,"name":"propertyName","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":12,"character":20}],"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"number"},{"type":"intrinsic","name":"null"}]}},{"id":3,"name":"rule","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":10,"character":12}],"type":{"type":"intrinsic","name":"any"}},{"id":6,"name":"valid","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":13,"character":13}],"type":{"type":"intrinsic","name":"boolean"}},{"id":8,"name":"nextId","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":15,"character":29}],"type":{"type":"intrinsic","name":"any"}},{"id":17,"name":"toString","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":18,"name":"toString","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"null"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":27,"character":16}]}],"groups":[{"title":"Constructors","kind":512,"children":[10]},{"title":"Properties","kind":1024,"children":[9,7,4,5,3,6,8]},{"title":"Methods","kind":2048,"children":[17]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":9,"character":31}]},{"id":81,"name":"ValidationController","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Orchestrates validation.\nManages a set of bindings, renderers and objects.\nExposes the current list of validation results for binding purposes."},"children":[{"id":95,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":96,"name":"new ValidationController","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":97,"name":"validator","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Validator","id":38}},{"id":98,"name":"propertyParser","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"PropertyAccessorParser","id":27}}],"type":{"type":"reference","name":"ValidationController","id":81}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":290,"character":31}]},{"id":85,"name":"bindings","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":269,"character":24}],"type":{"type":"intrinsic","name":"any"}},{"id":90,"name":"elements","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":283,"character":24}],"type":{"type":"intrinsic","name":"any"}},{"id":88,"name":"errors","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"Validation errors that have been rendered by the controller."},"sources":[{"fileName":"aurelia-validation.d.ts","line":278,"character":14}],"type":{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}},{"id":94,"name":"eventCallbacks","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":290,"character":30}],"type":{"type":"intrinsic","name":"any"}},{"id":93,"name":"finishValidating","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":289,"character":32}],"type":{"type":"intrinsic","name":"any"}},{"id":146,"name":"getAssociatedElements","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"comment":{"shortText":"Gets the elements associated with an object and propertyName (if any)."},"sources":[{"fileName":"aurelia-validation.d.ts","line":361,"character":37}],"type":{"type":"intrinsic","name":"any"}},{"id":139,"name":"getInstructionPredicate","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"comment":{"shortText":"Interprets the instruction and returns a predicate that will identify\nrelevant results in the list of rendered validation results."},"sources":[{"fileName":"aurelia-validation.d.ts","line":345,"character":39}],"type":{"type":"intrinsic","name":"any"}},{"id":159,"name":"invokeCallbacks","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":380,"character":31}],"type":{"type":"intrinsic","name":"any"}},{"id":91,"name":"objects","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":284,"character":23}],"type":{"type":"intrinsic","name":"any"}},{"id":147,"name":"processResultDelta","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":362,"character":34}],"type":{"type":"intrinsic","name":"any"}},{"id":83,"name":"propertyParser","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":267,"character":30}],"type":{"type":"intrinsic","name":"any"}},{"id":86,"name":"renderers","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":270,"character":25}],"type":{"type":"intrinsic","name":"any"}},{"id":87,"name":"results","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"comment":{"shortText":"Validation results that have been rendered by the controller."},"sources":[{"fileName":"aurelia-validation.d.ts","line":274,"character":23}],"type":{"type":"intrinsic","name":"any"}},{"id":92,"name":"validateTrigger","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The trigger that will invoke automatic validation of a property used in a binding."},"sources":[{"fileName":"aurelia-validation.d.ts","line":288,"character":23}],"type":{"type":"reference","name":"validateTrigger","id":52}},{"id":89,"name":"validating","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":" Whether the controller is currently validating."},"sources":[{"fileName":"aurelia-validation.d.ts","line":282,"character":18}],"type":{"type":"intrinsic","name":"boolean"}},{"id":82,"name":"validator","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":266,"character":25}],"type":{"type":"intrinsic","name":"any"}},{"id":84,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":268,"character":21}],"type":{"type":"array","elementType":{"type":"union","types":[{"type":"reference","name":"PropertyAccessorParser","id":27},{"type":"reference","name":"Validator","id":38}]}}},{"id":116,"name":"addError","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":117,"name":"addError","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Adds and renders an error."},"typeParameter":[{"id":118,"name":"TObject","kind":131072,"kindString":"Type parameter","flags":{}}],"parameters":[{"id":119,"name":"message","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}},{"id":120,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TObject"}},{"id":121,"name":"propertyName","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"reference","name":"PropertyAccessor","id":761,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"intrinsic","name":"string"}]},{"type":"intrinsic","name":"null"}]}}],"type":{"type":"reference","name":"ValidateResult","id":2}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":314,"character":16}]},{"id":109,"name":"addObject","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":110,"name":"addObject","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Adds an object to the set of objects that should be validated when validate is called."},"parameters":[{"id":111,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The object."},"type":{"type":"intrinsic","name":"any"}},{"id":112,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"comment":{"text":"Optional. The rules. If rules aren't supplied the Validator implementation will lookup the rules.\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":305,"character":17}]},{"id":125,"name":"addRenderer","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":126,"name":"addRenderer","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Adds a renderer."},"parameters":[{"id":127,"name":"renderer","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The renderer.\n"},"type":{"type":"reference","name":"ValidationRenderer","id":64}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":323,"character":19}]},{"id":154,"name":"changeTrigger","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":155,"name":"changeTrigger","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Changes the controller's validateTrigger."},"parameters":[{"id":156,"name":"newTrigger","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The new validateTrigger\n"},"type":{"type":"reference","name":"validateTrigger","id":52}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":375,"character":21}]},{"id":131,"name":"registerBinding","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":132,"name":"registerBinding","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Registers a binding with the controller."},"parameters":[{"id":133,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The binding instance."},"type":{"type":"reference","name":"Binding"}},{"id":134,"name":"target","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The DOM element."},"type":{"type":"reference","name":"Element"}},{"id":135,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"comment":{"text":"(optional) rules associated with the binding. Validator implementation specific.\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":335,"character":23}]},{"id":122,"name":"removeError","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":123,"name":"removeError","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Removes and unrenders an error."},"parameters":[{"id":124,"name":"result","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ValidateResult","id":2}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":318,"character":19}]},{"id":113,"name":"removeObject","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":114,"name":"removeObject","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Removes an object from the set of objects that should be validated when validate is called."},"parameters":[{"id":115,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The object.\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":310,"character":20}]},{"id":128,"name":"removeRenderer","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":129,"name":"removeRenderer","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Removes a renderer."},"parameters":[{"id":130,"name":"renderer","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The renderer.\n"},"type":{"type":"reference","name":"ValidationRenderer","id":64}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":328,"character":22}]},{"id":143,"name":"reset","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":144,"name":"reset","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Resets any rendered validation results (unrenders)."},"parameters":[{"id":145,"name":"instruction","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"comment":{"text":"Optional. Instructions on what to reset. If unspecified all rendered results\nwill be unrendered.\n"},"type":{"type":"reference","name":"ValidateInstruction","id":19}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":357,"character":13}]},{"id":151,"name":"resetBinding","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":152,"name":"resetBinding","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Resets the results for a property associated with a binding."},"parameters":[{"id":153,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Binding"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":370,"character":20}]},{"id":157,"name":"revalidateErrors","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":158,"name":"revalidateErrors","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Revalidates the controller's current set of errors."},"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":379,"character":24}]},{"id":99,"name":"subscribe","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":100,"name":"subscribe","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Subscribe to controller validate and reset events. These events occur when the\ncontroller's \"validate\"\" and \"reset\" methods are called."},"parameters":[{"id":101,"name":"callback","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The callback to be invoked when the controller validates or resets.\n"},"type":{"type":"reflection","declaration":{"id":102,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":103,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":104,"name":"event","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ValidateEvent","id":68}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":297,"character":27}]}}}],"type":{"type":"reflection","declaration":{"id":105,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"children":[{"id":106,"name":"dispose","kind":32,"kindString":"Variable","flags":{},"sources":[{"fileName":"aurelia-validation.d.ts","line":298,"character":19}],"type":{"type":"reflection","declaration":{"id":107,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":108,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":298,"character":20}]}}}],"groups":[{"title":"Variables","kind":32,"children":[106]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":297,"character":60}]}}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":297,"character":17}]},{"id":136,"name":"unregisterBinding","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":137,"name":"unregisterBinding","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Unregisters a binding with the controller."},"parameters":[{"id":138,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The binding instance.\n"},"type":{"type":"reference","name":"Binding"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":340,"character":25}]},{"id":140,"name":"validate","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":141,"name":"validate","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Validates and renders results."},"parameters":[{"id":142,"name":"instruction","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"comment":{"text":"Optional. Instructions on what to validate. If undefined, all\nobjects and bindings will be validated.\n"},"type":{"type":"reference","name":"ValidateInstruction","id":19}}],"type":{"type":"reference","name":"Promise","typeArguments":[{"type":"reference","name":"ControllerValidateResult","id":23}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":351,"character":16}]},{"id":148,"name":"validateBinding","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":149,"name":"validateBinding","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Validates the property associated with a binding."},"parameters":[{"id":150,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Binding"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":366,"character":23}]}],"groups":[{"title":"Constructors","kind":512,"children":[95]},{"title":"Properties","kind":1024,"children":[85,90,88,94,93,146,139,159,91,147,83,86,87,92,89,82,84]},{"title":"Methods","kind":2048,"children":[116,109,125,154,131,122,113,128,143,151,157,99,136,140,148]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":265,"character":37}]},{"id":258,"name":"ValidationControllerFactory","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Creates ValidationController instances."},"children":[{"id":263,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":264,"name":"new ValidationControllerFactory","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":265,"name":"container","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Container"}}],"type":{"type":"reference","name":"ValidationControllerFactory","id":258}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":451,"character":70}]},{"id":259,"name":"container","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":450,"character":25}],"type":{"type":"intrinsic","name":"any"}},{"id":266,"name":"create","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":267,"name":"create","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Creates a new controller instance."},"parameters":[{"id":268,"name":"validator","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"reference","name":"Validator","id":38}}],"type":{"type":"reference","name":"ValidationController","id":81}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":456,"character":14}]},{"id":269,"name":"createForCurrentScope","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":270,"name":"createForCurrentScope","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Creates a new controller and registers it in the current element's container so that it's\navailable to the validate binding behavior and renderers."},"parameters":[{"id":271,"name":"validator","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"reference","name":"Validator","id":38}}],"type":{"type":"reference","name":"ValidationController","id":81}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":461,"character":29}]},{"id":260,"name":"get","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":261,"name":"get","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":262,"name":"container","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Container"}}],"type":{"type":"reference","name":"ValidationControllerFactory","id":258}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":451,"character":18}]}],"groups":[{"title":"Constructors","kind":512,"children":[263]},{"title":"Properties","kind":1024,"children":[259]},{"title":"Methods","kind":2048,"children":[266,269,260]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":449,"character":44}]},{"id":275,"name":"ValidationErrorsCustomAttribute","kind":128,"kindString":"Class","flags":{"isExported":true},"children":[{"id":287,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":288,"name":"new ValidationErrorsCustomAttribute","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":289,"name":"boundaryElement","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"Element"}},{"id":290,"name":"controllerAccessor","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reflection","declaration":{"id":291,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":292,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"reference","name":"ValidationController","id":81}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":481,"character":65}]}}}],"type":{"type":"reference","name":"ValidationErrorsCustomAttribute","id":275}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":480,"character":31}]},{"id":276,"name":"boundaryElement","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":472,"character":31}],"type":{"type":"intrinsic","name":"any"}},{"id":284,"name":"controller","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":478,"character":18}],"type":{"type":"union","types":[{"type":"reference","name":"ValidationController","id":81},{"type":"intrinsic","name":"null"}]}},{"id":277,"name":"controllerAccessor","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":473,"character":34}],"type":{"type":"intrinsic","name":"any"}},{"id":285,"name":"errors","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":479,"character":14}],"type":{"type":"array","elementType":{"type":"reference","name":"RenderedError","id":272}}},{"id":286,"name":"errorsInternal","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":480,"character":30}],"type":{"type":"intrinsic","name":"any"}},{"id":301,"name":"bind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":302,"name":"bind","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":485,"character":12}]},{"id":295,"name":"interestingElements","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":296,"name":"interestingElements","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":297,"name":"elements","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"array","elementType":{"type":"reference","name":"Element"}}}],"type":{"type":"array","elementType":{"type":"reference","name":"Element"}}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":483,"character":27}]},{"id":298,"name":"render","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":299,"name":"render","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":300,"name":"instruction","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"RenderInstruction","id":60}}],"type":{"type":"intrinsic","name":"void"},"implementationOf":{"type":"reference","name":"ValidationRenderer.render","id":66}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":484,"character":14}],"implementationOf":{"type":"reference","name":"ValidationRenderer.render","id":65}},{"id":293,"name":"sort","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":294,"name":"sort","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":482,"character":12}]},{"id":303,"name":"unbind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":304,"name":"unbind","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":486,"character":14}]},{"id":278,"name":"inject","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":279,"name":"inject","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"array","elementType":{"type":"union","types":[{"type":"reflection","declaration":{"id":280,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"children":[{"id":281,"name":"constructor","kind":512,"kindString":"Constructor","flags":{},"signatures":[{"id":282,"name":"new __type","kind":16384,"kindString":"Constructor signature","flags":{},"type":{"type":"reference","name":"Element"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":474,"character":27}]},{"id":283,"name":"prototype","kind":32,"kindString":"Variable","flags":{},"sources":[{"fileName":"aurelia-validation.d.ts","line":476,"character":21}],"type":{"type":"reference","name":"Element"}}],"groups":[{"title":"Constructors","kind":512,"children":[281]},{"title":"Variables","kind":32,"children":[283]}]}},{"type":"reference","name":"Lazy"}]}}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":474,"character":21}]}],"groups":[{"title":"Constructors","kind":512,"children":[287]},{"title":"Properties","kind":1024,"children":[276,284,277,285,286]},{"title":"Methods","kind":2048,"children":[301,295,298,293,303,278]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":471,"character":48}],"implementedTypes":[{"type":"reference","name":"ValidationRenderer","id":64}]},{"id":406,"name":"ValidationMessageParser","kind":128,"kindString":"Class","flags":{"isExported":true},"children":[{"id":413,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":414,"name":"new ValidationMessageParser","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":415,"name":"bindinqLanguage","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"BindingLanguage"}}],"type":{"type":"reference","name":"ValidationMessageParser","id":406}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":590,"character":22}]},{"id":407,"name":"bindinqLanguage","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":585,"character":31}],"type":{"type":"intrinsic","name":"any"}},{"id":412,"name":"cache","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":590,"character":21}],"type":{"type":"intrinsic","name":"any"}},{"id":419,"name":"coalesce","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":593,"character":24}],"type":{"type":"intrinsic","name":"any"}},{"id":409,"name":"emptyStringExpression","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":587,"character":37}],"type":{"type":"intrinsic","name":"any"}},{"id":410,"name":"nullExpression","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":588,"character":30}],"type":{"type":"intrinsic","name":"any"}},{"id":411,"name":"undefinedExpression","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":589,"character":35}],"type":{"type":"intrinsic","name":"any"}},{"id":408,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":586,"character":21}],"type":{"type":"array","elementType":{"type":"reference","name":"BindingLanguage"}}},{"id":416,"name":"parse","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":417,"name":"parse","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":418,"name":"message","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"reference","name":"Expression"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":592,"character":13}]}],"groups":[{"title":"Constructors","kind":512,"children":[413]},{"title":"Properties","kind":1024,"children":[407,412,419,409,410,411,408]},{"title":"Methods","kind":2048,"children":[416]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":584,"character":40}]},{"id":486,"name":"ValidationMessageProvider","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Retrieves validation messages and property display names."},"children":[{"id":489,"name":"constructor","kind":512,"kindString":"Constructor","flags":{"isExported":true},"signatures":[{"id":490,"name":"new ValidationMessageProvider","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":491,"name":"parser","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ValidationMessageParser","id":406}}],"type":{"type":"reference","name":"ValidationMessageProvider","id":486}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":615,"character":58}]},{"id":487,"name":"parser","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":614,"character":14}],"type":{"type":"reference","name":"ValidationMessageParser","id":406}},{"id":488,"name":"inject","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":615,"character":21}],"type":{"type":"array","elementType":{"type":"reference","name":"ValidationMessageParser","id":406}}},{"id":495,"name":"getDisplayName","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":496,"name":"getDisplayName","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Formulates a property display name using the property name and the configured\ndisplayName (if provided).\nOverride this with your own custom logic."},"parameters":[{"id":497,"name":"propertyName","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The property name.\n"},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"number"}]}},{"id":498,"name":"displayName","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"null"},{"type":"reflection","declaration":{"id":499,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":500,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"string"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":628,"character":83}]}}]}}],"type":{"type":"intrinsic","name":"string"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":628,"character":22}]},{"id":492,"name":"getMessage","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":493,"name":"getMessage","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Returns a message binding expression that corresponds to the key."},"parameters":[{"id":494,"name":"key","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The message key.\n"},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"reference","name":"Expression"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":621,"character":18}]}],"groups":[{"title":"Constructors","kind":512,"children":[489]},{"title":"Properties","kind":1024,"children":[487,488]},{"title":"Methods","kind":2048,"children":[495,492]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":613,"character":42}]},{"id":305,"name":"ValidationRendererCustomAttribute","kind":128,"kindString":"Class","flags":{"isExported":true},"children":[{"id":306,"name":"container","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":490,"character":25}],"type":{"type":"intrinsic","name":"any"}},{"id":307,"name":"controller","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":491,"character":26}],"type":{"type":"intrinsic","name":"any"}},{"id":309,"name":"renderer","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":493,"character":24}],"type":{"type":"intrinsic","name":"any"}},{"id":308,"name":"value","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":492,"character":21}],"type":{"type":"intrinsic","name":"any"}},{"id":313,"name":"bind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":314,"name":"bind","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":495,"character":12}]},{"id":310,"name":"created","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":311,"name":"created","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":312,"name":"view","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":494,"character":15}]},{"id":315,"name":"unbind","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":316,"name":"unbind","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":496,"character":14}]}],"groups":[{"title":"Properties","kind":1024,"children":[306,307,309,308]},{"title":"Methods","kind":2048,"children":[313,310,315]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":489,"character":50}]},{"id":691,"name":"ValidationRules","kind":128,"kindString":"Class","flags":{"isExported":true},"comment":{"shortText":"Fluent rule definition API."},"children":[{"id":692,"name":"parsers","kind":1024,"kindString":"Property","flags":{"isStatic":true,"isPrivate":true,"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":891,"character":30}],"type":{"type":"intrinsic","name":"any"}},{"id":705,"name":"customRule","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":706,"name":"customRule","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Defines a custom rule."},"parameters":[{"id":707,"name":"name","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The name of the custom rule. Also serves as the message key."},"type":{"type":"intrinsic","name":"string"}},{"id":708,"name":"condition","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The rule function."},"type":{"type":"reflection","declaration":{"id":709,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":710,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":711,"name":"value","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":712,"name":"object","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"any"}},{"id":713,"name":"args","kind":32768,"kindString":"Parameter","flags":{"isRest":true},"type":{"type":"array","elementType":{"type":"intrinsic","name":"any"}}}],"type":{"type":"union","types":[{"type":"intrinsic","name":"boolean"},{"type":"reference","name":"Promise","typeArguments":[{"type":"intrinsic","name":"boolean"}]}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":910,"character":50}]}}},{"id":714,"name":"message","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The message expression"},"type":{"type":"intrinsic","name":"string"}},{"id":715,"name":"argsToConfig","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"comment":{"text":"A function that maps the rule's arguments to a \"config\"\nobject that can be used when evaluating the message expression.\n"},"type":{"type":"union","types":[{"type":"intrinsic","name":"undefined"},{"type":"reflection","declaration":{"id":716,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":717,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":718,"name":"args","kind":32768,"kindString":"Parameter","flags":{"isRest":true},"type":{"type":"array","elementType":{"type":"intrinsic","name":"any"}}}],"type":{"type":"intrinsic","name":"any"}}]}}]}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":910,"character":25}]},{"id":697,"name":"ensure","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":698,"name":"ensure","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Target a property with validation rules."},"typeParameter":[{"id":699,"name":"TObject","kind":131072,"kindString":"Type parameter","flags":{}},{"id":700,"name":"TValue","kind":131072,"kindString":"Type parameter","flags":{}}],"parameters":[{"id":701,"name":"property","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The property to target. Can be the property name or a property accessor function.\n"},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"number"},{"type":"reference","name":"PropertyAccessor","id":761,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"typeParameter","name":"TValue"}]}]}}],"type":{"type":"reference","name":"FluentRules","id":609,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"intrinsic","name":"any"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":897,"character":21}]},{"id":702,"name":"ensureObject","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":703,"name":"ensureObject","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Targets an object with validation rules."},"typeParameter":[{"id":704,"name":"TObject","kind":131072,"kindString":"Type parameter","flags":{}}],"type":{"type":"reference","name":"FluentRules","id":609,"typeArguments":[{"type":"typeParameter","name":"TObject"},{"type":"intrinsic","name":"any"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":901,"character":27}]},{"id":693,"name":"initialize","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":694,"name":"initialize","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":695,"name":"messageParser","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"ValidationMessageParser","id":406}},{"id":696,"name":"propertyParser","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"PropertyAccessorParser","id":27}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":892,"character":25}]},{"id":726,"name":"off","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":727,"name":"off","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Removes the rules from a class or object."},"parameters":[{"id":728,"name":"target","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"A class or object.\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":926,"character":18}]},{"id":719,"name":"taggedRules","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":720,"name":"taggedRules","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Returns rules with the matching tag."},"parameters":[{"id":721,"name":"rules","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The rules to search."},"type":{"type":"array","elementType":{"type":"array","elementType":{"type":"reference","name":"Rule","id":320,"typeArguments":[{"type":"intrinsic","name":"any"},{"type":"intrinsic","name":"any"}]}}}},{"id":722,"name":"tag","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The tag to search for.\n"},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"array","elementType":{"type":"array","elementType":{"type":"reference","name":"Rule","id":320,"typeArguments":[{"type":"intrinsic","name":"any"},{"type":"intrinsic","name":"any"}]}}}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":916,"character":26}]},{"id":723,"name":"untaggedRules","kind":2048,"kindString":"Method","flags":{"isStatic":true,"isExported":true},"signatures":[{"id":724,"name":"untaggedRules","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Returns rules that have no tag."},"parameters":[{"id":725,"name":"rules","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The rules to search.\n"},"type":{"type":"array","elementType":{"type":"array","elementType":{"type":"reference","name":"Rule","id":320,"typeArguments":[{"type":"intrinsic","name":"any"},{"type":"intrinsic","name":"any"}]}}}}],"type":{"type":"array","elementType":{"type":"array","elementType":{"type":"reference","name":"Rule","id":320,"typeArguments":[{"type":"intrinsic","name":"any"},{"type":"intrinsic","name":"any"}]}}}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":921,"character":28}]}],"groups":[{"title":"Properties","kind":1024,"children":[692]},{"title":"Methods","kind":2048,"children":[705,697,702,693,726,719,723]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":890,"character":32}]},{"id":38,"name":"Validator","kind":128,"kindString":"Class","flags":{"isExported":true,"isAbstract":true},"comment":{"shortText":"Validates objects and properties."},"children":[{"id":48,"name":"ruleExists","kind":2048,"kindString":"Method","flags":{"isExported":true,"isAbstract":true},"signatures":[{"id":49,"name":"ruleExists","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Determines whether a rule exists in a set of rules.","tags":[{"tag":"parem","text":"rule The rule to find.\n"}]},"parameters":[{"id":50,"name":"rules","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The rules to search."},"type":{"type":"intrinsic","name":"any"}},{"id":51,"name":"rule","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"boolean"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":121,"character":27}]},{"id":44,"name":"validateObject","kind":2048,"kindString":"Method","flags":{"isExported":true,"isAbstract":true},"signatures":[{"id":45,"name":"validateObject","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Validates all rules for specified object and it's properties."},"parameters":[{"id":46,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The object to validate."},"type":{"type":"intrinsic","name":"any"}},{"id":47,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"comment":{"text":"Optional. If unspecified, the implementation should lookup the rules for the\nspecified object. This may not be possible for all implementations of this interface.\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"reference","name":"Promise","typeArguments":[{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":115,"character":31}]},{"id":39,"name":"validateProperty","kind":2048,"kindString":"Method","flags":{"isExported":true,"isAbstract":true},"signatures":[{"id":40,"name":"validateProperty","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Validates the specified property."},"parameters":[{"id":41,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The object to validate."},"type":{"type":"intrinsic","name":"any"}},{"id":42,"name":"propertyName","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The name of the property to validate."},"type":{"type":"intrinsic","name":"string"}},{"id":43,"name":"rules","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"comment":{"text":"Optional. If unspecified, the implementation should lookup the rules for the\nspecified object. This may not be possible for all implementations of this interface.\n"},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"reference","name":"Promise","typeArguments":[{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":108,"character":33}]}],"groups":[{"title":"Methods","kind":2048,"children":[48,44,39]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":100,"character":35}],"extendedBy":[{"type":"reference","name":"StandardValidator","id":501}]},{"id":23,"name":"ControllerValidateResult","kind":256,"kindString":"Interface","flags":{"isExported":true},"comment":{"shortText":"The result of a call to the validation controller's validate method."},"children":[{"id":26,"name":"instruction","kind":1024,"kindString":"Property","flags":{"isExported":true,"isOptional":true},"comment":{"shortText":"The instruction passed to the controller's validate method."},"sources":[{"fileName":"aurelia-validation.d.ts","line":64,"character":19}],"type":{"type":"reference","name":"ValidateInstruction","id":19}},{"id":25,"name":"results","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The validation result of every rule that was evaluated."},"sources":[{"fileName":"aurelia-validation.d.ts","line":60,"character":15}],"type":{"type":"array","elementType":{"type":"reference","name":"ValidateResult","id":2}}},{"id":24,"name":"valid","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"Whether validation passed."},"sources":[{"fileName":"aurelia-validation.d.ts","line":56,"character":13}],"type":{"type":"intrinsic","name":"boolean"}}],"groups":[{"title":"Properties","kind":1024,"children":[26,25,24]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":52,"character":45}]},{"id":729,"name":"Parsers","kind":256,"kindString":"Interface","flags":{"isExported":true},"children":[{"id":730,"name":"message","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":929,"character":15}],"type":{"type":"reference","name":"ValidationMessageParser","id":406}},{"id":731,"name":"property","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":930,"character":16}],"type":{"type":"reference","name":"PropertyAccessorParser","id":27}}],"groups":[{"title":"Properties","kind":1024,"children":[730,731]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":928,"character":28}]},{"id":60,"name":"RenderInstruction","kind":256,"kindString":"Interface","flags":{"isExported":true},"comment":{"shortText":"Defines which validation results to render and which validation results to unrender."},"children":[{"id":61,"name":"kind","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The \"kind\" of render instruction. Either 'validate' or 'reset'."},"sources":[{"fileName":"aurelia-validation.d.ts","line":168,"character":12}],"type":{"type":"union","types":[{"type":"stringLiteral","value":"validate"},{"type":"stringLiteral","value":"reset"}]}},{"id":62,"name":"render","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The results to render."},"sources":[{"fileName":"aurelia-validation.d.ts","line":172,"character":14}],"type":{"type":"array","elementType":{"type":"reference","name":"ResultInstruction","id":57}}},{"id":63,"name":"unrender","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The results to unrender."},"sources":[{"fileName":"aurelia-validation.d.ts","line":176,"character":16}],"type":{"type":"array","elementType":{"type":"reference","name":"ResultInstruction","id":57}}}],"groups":[{"title":"Properties","kind":1024,"children":[61,62,63]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":164,"character":38}]},{"id":272,"name":"RenderedError","kind":256,"kindString":"Interface","flags":{"isExported":true},"children":[{"id":273,"name":"error","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":468,"character":13}],"type":{"type":"reference","name":"ValidateResult","id":2}},{"id":274,"name":"targets","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":469,"character":15}],"type":{"type":"array","elementType":{"type":"reference","name":"Element"}}}],"groups":[{"title":"Properties","kind":1024,"children":[273,274]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":467,"character":34}]},{"id":57,"name":"ResultInstruction","kind":256,"kindString":"Interface","flags":{"isExported":true},"comment":{"shortText":"A result to render (or unrender) and the associated elements (if any)"},"children":[{"id":59,"name":"elements","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The associated elements (if any)."},"sources":[{"fileName":"aurelia-validation.d.ts","line":159,"character":16}],"type":{"type":"array","elementType":{"type":"reference","name":"Element"}}},{"id":58,"name":"result","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The validation result."},"sources":[{"fileName":"aurelia-validation.d.ts","line":155,"character":14}],"type":{"type":"reference","name":"ValidateResult","id":2}}],"groups":[{"title":"Properties","kind":1024,"children":[59,58]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":151,"character":38}]},{"id":320,"name":"Rule","kind":256,"kindString":"Interface","flags":{"isExported":true},"comment":{"shortText":"A rule definition. Associations a rule with a property or object."},"typeParameter":[{"id":321,"name":"TObject","kind":131072,"kindString":"Type parameter","flags":{}},{"id":322,"name":"TValue","kind":131072,"kindString":"Type parameter","flags":{}}],"children":[{"id":324,"name":"condition","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":518,"character":17}],"type":{"type":"reflection","declaration":{"id":325,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":326,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":327,"name":"value","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TValue"}},{"id":328,"name":"object","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"reference","name":"TObject","id":321}}],"type":{"type":"union","types":[{"type":"intrinsic","name":"boolean"},{"type":"reference","name":"Promise","typeArguments":[{"type":"intrinsic","name":"boolean"}]}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":518,"character":18}]}}},{"id":329,"name":"config","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":519,"character":14}],"type":{"type":"intrinsic","name":"object"}},{"id":335,"name":"message","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":522,"character":15}],"type":{"type":"union","types":[{"type":"reference","name":"Expression"},{"type":"intrinsic","name":"null"}]}},{"id":334,"name":"messageKey","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":521,"character":18}],"type":{"type":"intrinsic","name":"string"}},{"id":323,"name":"property","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":517,"character":16}],"type":{"type":"reference","name":"RuleProperty","id":317}},{"id":336,"name":"sequence","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":523,"character":16}],"type":{"type":"intrinsic","name":"number"}},{"id":337,"name":"tag","kind":1024,"kindString":"Property","flags":{"isExported":true,"isOptional":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":524,"character":11}],"type":{"type":"union","types":[{"type":"intrinsic","name":"undefined"},{"type":"intrinsic","name":"string"}]}},{"id":330,"name":"when","kind":1024,"kindString":"Property","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":520,"character":12}],"type":{"type":"union","types":[{"type":"reflection","declaration":{"id":331,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":332,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":333,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TObject"}}],"type":{"type":"intrinsic","name":"boolean"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":520,"character":13}]}},{"type":"intrinsic","name":"null"}]}}],"groups":[{"title":"Properties","kind":1024,"children":[324,329,335,334,323,336,337,330]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":516,"character":25}]},{"id":317,"name":"RuleProperty","kind":256,"kindString":"Interface","flags":{"isExported":true},"comment":{"shortText":"Information related to a property that is the subject of validation."},"children":[{"id":319,"name":"displayName","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The displayName of the property (or object)."},"sources":[{"fileName":"aurelia-validation.d.ts","line":511,"character":19}],"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"reference","name":"ValidationDisplayNameAccessor","id":770},{"type":"intrinsic","name":"null"}]}},{"id":318,"name":"name","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The property name. null indicates the rule targets the object itself."},"sources":[{"fileName":"aurelia-validation.d.ts","line":507,"character":12}],"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"number"},{"type":"intrinsic","name":"null"}]}}],"groups":[{"title":"Properties","kind":1024,"children":[319,318]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":503,"character":33}]},{"id":19,"name":"ValidateInstruction","kind":256,"kindString":"Interface","flags":{"isExported":true},"comment":{"shortText":"Instructions for the validation controller's validate method."},"children":[{"id":20,"name":"object","kind":1024,"kindString":"Property","flags":{"isExported":true},"comment":{"shortText":"The object to validate."},"sources":[{"fileName":"aurelia-validation.d.ts","line":37,"character":14}],"type":{"type":"intrinsic","name":"any"}},{"id":21,"name":"propertyName","kind":1024,"kindString":"Property","flags":{"isExported":true,"isOptional":true},"comment":{"shortText":"The property to validate. Optional."},"sources":[{"fileName":"aurelia-validation.d.ts","line":41,"character":20}],"type":{"type":"intrinsic","name":"any"}},{"id":22,"name":"rules","kind":1024,"kindString":"Property","flags":{"isExported":true,"isOptional":true},"comment":{"shortText":"The rules to validate. Optional."},"sources":[{"fileName":"aurelia-validation.d.ts","line":45,"character":13}],"type":{"type":"intrinsic","name":"any"}}],"groups":[{"title":"Properties","kind":1024,"children":[20,21,22]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":33,"character":40}]},{"id":483,"name":"ValidationMessages","kind":256,"kindString":"Interface","flags":{"isExported":true},"indexSignature":{"id":484,"name":"__index","kind":8192,"kindString":"Index signature","flags":{},"parameters":[{"id":485,"name":"key","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"intrinsic","name":"string"}},"sources":[{"fileName":"aurelia-validation.d.ts","line":603,"character":39}]},{"id":64,"name":"ValidationRenderer","kind":256,"kindString":"Interface","flags":{"isExported":true},"comment":{"shortText":"Renders validation results."},"children":[{"id":65,"name":"render","kind":2048,"kindString":"Method","flags":{"isExported":true},"signatures":[{"id":66,"name":"render","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Render the validation results."},"parameters":[{"id":67,"name":"instruction","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The render instruction. Defines which results to render and which\nresults to unrender.\n"},"type":{"type":"reference","name":"RenderInstruction","id":60}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":187,"character":14}]}],"groups":[{"title":"Methods","kind":2048,"children":[65]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":181,"character":39}],"implementedBy":[{"type":"reference","name":"ValidationErrorsCustomAttribute","id":275}]},{"id":776,"name":"AccessScope","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":552,"character":27}],"type":{"type":"intrinsic","name":"any"}},{"id":775,"name":"AccessThis","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":551,"character":26}],"type":{"type":"intrinsic","name":"any"}},{"id":774,"name":"Assign","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":550,"character":22}],"type":{"type":"intrinsic","name":"any"}},{"id":778,"name":"CallFunction","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":554,"character":28}],"type":{"type":"intrinsic","name":"any"}},{"id":777,"name":"CallScope","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":553,"character":25}],"type":{"type":"intrinsic","name":"any"}},{"id":773,"name":"Chain","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":549,"character":21}],"type":{"type":"intrinsic","name":"any"}},{"id":781,"name":"LiteralArray","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":557,"character":28}],"type":{"type":"intrinsic","name":"any"}},{"id":782,"name":"LiteralObject","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":558,"character":29}],"type":{"type":"intrinsic","name":"any"}},{"id":780,"name":"LiteralPrimitive","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":556,"character":32}],"type":{"type":"intrinsic","name":"any"}},{"id":783,"name":"LiteralString","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":559,"character":29}],"type":{"type":"intrinsic","name":"any"}},{"id":779,"name":"PrefixNot","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":555,"character":25}],"type":{"type":"intrinsic","name":"any"}},{"id":761,"name":"PropertyAccessor","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"typeParameter":[{"id":762,"name":"TObject","kind":131072,"kindString":"Type parameter","flags":{}},{"id":763,"name":"TValue","kind":131072,"kindString":"Type parameter","flags":{}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":88,"character":32}],"type":{"type":"reflection","declaration":{"id":764,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":765,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":766,"name":"object","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"typeParameter","name":"TObject"}}],"type":{"type":"typeParameter","name":"TValue"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":88,"character":51}]}}},{"id":770,"name":"ValidationDisplayNameAccessor","kind":4194304,"kindString":"Type alias","flags":{"isExported":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":499,"character":45}],"type":{"type":"reflection","declaration":{"id":771,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":772,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"string"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":499,"character":47}]}}},{"id":784,"name":"validationMessages","kind":32,"kindString":"Variable","flags":{"isExported":true,"isConst":true},"comment":{"shortText":"Dictionary of validation messages. [messageKey]: messageExpression"},"sources":[{"fileName":"aurelia-validation.d.ts","line":609,"character":35}],"type":{"type":"reference","name":"ValidationMessages","id":483}},{"id":785,"name":"configure","kind":64,"kindString":"Function","flags":{"isExported":true},"signatures":[{"id":786,"name":"configure","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Configures the plugin."},"parameters":[{"id":787,"name":"frameworkConfig","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reflection","declaration":{"id":788,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"children":[{"id":789,"name":"container","kind":32,"kindString":"Variable","flags":{},"sources":[{"fileName":"aurelia-validation.d.ts","line":975,"character":17}],"type":{"type":"reference","name":"Container"}},{"id":790,"name":"globalResources","kind":32,"kindString":"Variable","flags":{"isOptional":true},"sources":[{"fileName":"aurelia-validation.d.ts","line":976,"character":23}],"type":{"type":"union","types":[{"type":"intrinsic","name":"undefined"},{"type":"reflection","declaration":{"id":791,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":792,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":793,"name":"resources","kind":32768,"kindString":"Parameter","flags":{"isRest":true},"type":{"type":"array","elementType":{"type":"reference","name":"Function"}}}],"type":{"type":"intrinsic","name":"any"}}]}}]}}],"groups":[{"title":"Variables","kind":32,"children":[789,790]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":974,"character":46}]}}},{"id":794,"name":"callback","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"union","types":[{"type":"intrinsic","name":"undefined"},{"type":"reflection","declaration":{"id":795,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"signatures":[{"id":796,"name":"__call","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":797,"name":"config","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","name":"AureliaValidationConfiguration","id":732}}],"type":{"type":"intrinsic","name":"void"}}]}}]}}],"type":{"type":"intrinsic","name":"void"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":974,"character":29}]},{"id":767,"name":"getAccessorExpression","kind":64,"kindString":"Function","flags":{"isExported":true},"signatures":[{"id":768,"name":"getAccessorExpression","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":769,"name":"fn","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"intrinsic","name":"string"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":95,"character":41}]},{"id":748,"name":"getPropertyInfo","kind":64,"kindString":"Function","flags":{"isExported":true},"signatures":[{"id":749,"name":"getPropertyInfo","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Retrieves the object and property name for the specified expression."},"parameters":[{"id":750,"name":"expression","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The expression"},"type":{"type":"reference","name":"Expression"}},{"id":751,"name":"source","kind":32768,"kindString":"Parameter","flags":{},"comment":{"text":"The scope\n"},"type":{"type":"reference","name":"Scope"}}],"type":{"type":"union","types":[{"type":"reflection","declaration":{"id":752,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"children":[{"id":753,"name":"object","kind":32,"kindString":"Variable","flags":{},"sources":[{"fileName":"aurelia-validation.d.ts","line":81,"character":14}],"type":{"type":"intrinsic","name":"object"}},{"id":754,"name":"propertyName","kind":32,"kindString":"Variable","flags":{},"sources":[{"fileName":"aurelia-validation.d.ts","line":82,"character":20}],"type":{"type":"intrinsic","name":"string"}}],"groups":[{"title":"Variables","kind":32,"children":[753,754]}],"sources":[{"fileName":"aurelia-validation.d.ts","line":80,"character":75}]}},{"type":"intrinsic","name":"null"}]}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":80,"character":35}]},{"id":744,"name":"getTargetDOMElement","kind":64,"kindString":"Function","flags":{"isExported":true},"signatures":[{"id":745,"name":"getTargetDOMElement","kind":4096,"kindString":"Call signature","flags":{},"comment":{"shortText":"Gets the DOM element associated with the data-binding. Most of the time it's\nthe binding.target but sometimes binding.target is an aurelia custom element,\nor custom attribute which is a javascript \"class\" instance, so we need to use\nthe controller's container to retrieve the actual DOM element."},"parameters":[{"id":746,"name":"binding","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}},{"id":747,"name":"view","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"reference","name":"Element"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":73,"character":39}]},{"id":758,"name":"isNumber","kind":64,"kindString":"Function","flags":{"isExported":true},"signatures":[{"id":759,"name":"isNumber","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":760,"name":"value","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"boolean"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":86,"character":28}]},{"id":755,"name":"isString","kind":64,"kindString":"Function","flags":{"isExported":true},"signatures":[{"id":756,"name":"isString","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":757,"name":"value","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"boolean"}}],"sources":[{"fileName":"aurelia-validation.d.ts","line":85,"character":28}]}],"groups":[{"title":"Enumerations","kind":4,"children":[52]},{"title":"Classes","kind":128,"children":[732,350,673,526,609,420,27,338,501,177,160,68,194,210,226,242,2,81,258,275,406,486,305,691,38]},{"title":"Interfaces","kind":256,"children":[23,729,60,272,57,320,317,19,483,64]},{"title":"Type aliases","kind":4194304,"children":[776,775,774,778,777,773,781,782,780,783,779,761,770]},{"title":"Variables","kind":32,"children":[784]},{"title":"Functions","kind":64,"children":[785,767,748,744,758,755]}]}