From 8c9c15d6fb7f326de8a6086474852f69baeedeed Mon Sep 17 00:00:00 2001 From: Sven Slootweg Date: Sun, 14 Jun 2020 03:19:36 +0200 Subject: [PATCH] Initial commit --- .gitignore | 1 + README.md | 5 ++ example.js | 33 +++++++++ index.js | 34 +++++++++ package.json | 23 ++++++ yarn.lock | 198 +++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 294 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 example.js create mode 100644 index.js create mode 100644 package.json create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/README.md b/README.md new file mode 100644 index 0000000..e867eb8 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# @validatem/when + +Documentation for this module has not been written yet. By the time it reaches 1.0.0, it will have full documentation. + +In the meantime, check out the `example.js` file in the repository for a usage demonstration. diff --git a/example.js b/example.js new file mode 100644 index 0000000..d89fff7 --- /dev/null +++ b/example.js @@ -0,0 +1,33 @@ +"use strict"; + +const { validateValue } = require("@validatem/core"); +const isString = require("@validatem/is-string"); +const when = require("./"); + +let rule = when((object) => object.type === "string", { + value: [ isString ] +}); + +let objectA = { + type: "string", + value: "hello world" +}; + +console.log(validateValue(objectA, rule)); // { type: 'string', value: 'hello world' } + +let objectB = { + type: "number", /* Note that there are no rules for this case! */ + value: 42 +}; + +console.log(validateValue(objectB, rule)); // { type: 'number', value: 42 } + +let objectC = { + type: "string", + value: 42 +}; + +console.log(validateValue(objectC, rule)); /* + AggregrateValidationError: One or more validation errors occurred: + - At value: Must be a string +*/ diff --git a/index.js b/index.js new file mode 100644 index 0000000..b4d61d0 --- /dev/null +++ b/index.js @@ -0,0 +1,34 @@ +"use strict"; + +const assureArray = require("assure-array"); + +const combinator = require("@validatem/combinator"); +const allowExtraProperties = require("@validatem/allow-extra-properties"); + +// TODO: Document that this passes on context +// TODO: Clearly document that the predicate is ALSO called when the value is not specified! + +module.exports = function (predicate, rules) { + if (rules == null) { + // User probably did `[ when(condition), [ rules ] ]` instead of `[ when(condition, [ rules ]) ]` + throw new Error("No rules specified for a `when` validation clause; did you misplace a parenthese?"); + } else { + let preparedRules = assureArray(rules).map((rule) => { + /* We automatically allow extraneous properties in a `when` clause, because it'll generally be used as a partial addition to an otherwise-fully-specified object structure. This can be overridden by using `withContext` explicitly, wrapped directly around the hasShape or object literal. */ + // TODO: Document this. + return allowExtraProperties(rule); + }); + + return combinator((value, applyValidators, context) => { + let matches = predicate(value); + + if (matches) { + // TODO: Translate this to a configuration wrapper approach, too? + return applyValidators(value, preparedRules, context); + } else { + // noop + return; + } + }); + } +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..a46de90 --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "@validatem/when", + "description": "Validatem combinator for conditionally applying one or more rules", + "keywords": [ + "validatem", + "validator", + "combinator" + ], + "version": "0.1.0", + "main": "index.js", + "repository": "http://git.cryto.net/validatem/when.git", + "author": "Sven Slootweg ", + "license": "WTFPL OR CC0-1.0", + "dependencies": { + "@validatem/allow-extra-properties": "^0.1.0", + "@validatem/combinator": "^0.1.2", + "assure-array": "^1.0.0" + }, + "devDependencies": { + "@validatem/core": "^0.3.3", + "@validatem/is-string": "^0.1.1" + } +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..316aa7b --- /dev/null +++ b/yarn.lock @@ -0,0 +1,198 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@validatem/allow-extra-properties@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@validatem/allow-extra-properties/-/allow-extra-properties-0.1.0.tgz#e8c434818d6fd74b8cb237cfaa4d548295de13c1" + integrity sha512-9jihpYxw1vp4FdjnbN0bTVZMLYv//9OjFNTsVLG5OV4xHESwtgkgQEF5/N5rY1iBwoH/pcKuRl44MBZ8eMdrKw== + dependencies: + "@validatem/with-context" "^0.1.0" + +"@validatem/annotate-errors@^0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@validatem/annotate-errors/-/annotate-errors-0.1.2.tgz#fa9152bb30f4f42b69496b527e38f0c31ff605a9" + integrity sha512-EuX7pzdYI/YpTmZcgdPG481Oi3elAg8JWh/LYXuE1h6MaZk3A8eP5DD33/l7EoKzrysn6y8nCsqNa1ngei562w== + dependencies: + "@validatem/match-validation-error" "^0.1.0" + +"@validatem/any-property@^0.1.0": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@validatem/any-property/-/any-property-0.1.3.tgz#fc7768c1922a8bacff9369ae48913672e5350f52" + integrity sha512-jYWxif5ff9pccu7566LIQ/4+snlApXEJUimBywzAriBgS3r4eDBbz3oZFHuiPmhxNK/NNof5YUS+L6Sk3zaMfg== + dependencies: + "@validatem/annotate-errors" "^0.1.2" + "@validatem/combinator" "^0.1.0" + "@validatem/error" "^1.0.0" + "@validatem/validation-result" "^0.1.1" + "@validatem/virtual-property" "^0.1.0" + default-value "^1.0.0" + +"@validatem/combinator@^0.1.0", "@validatem/combinator@^0.1.1", "@validatem/combinator@^0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@validatem/combinator/-/combinator-0.1.2.tgz#eab893d55f1643b9c6857eaf6ff7ed2a728e89ff" + integrity sha512-vE8t1tNXknmN62FlN6LxQmA2c6TwVKZ+fl/Wit3H2unFdOhu7SZj2kRPGjAXdK/ARh/3svYfUBeD75pea0j1Sw== + +"@validatem/core@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@validatem/core/-/core-0.3.3.tgz#f9d812ba75c073e3879b3afae8f5c8c356992717" + integrity sha512-2rJdTwc/KlyjQtdn9uWgWYdqLOB3F47tV/Ew5XQ67bHabZhrF6xZF97B6I+C340HH0A7YW1tgNTnKsNh0PvhCg== + dependencies: + "@validatem/annotate-errors" "^0.1.2" + "@validatem/any-property" "^0.1.0" + "@validatem/error" "^1.0.0" + "@validatem/is-plain-object" "^0.1.0" + "@validatem/match-validation-error" "^0.1.0" + "@validatem/match-versioned-special" "^0.1.0" + "@validatem/match-virtual-property" "^0.1.0" + "@validatem/normalize-rules" "^0.1.0" + "@validatem/required" "^0.1.0" + "@validatem/validation-result" "^0.1.1" + assure-array "^1.0.0" + create-error "^0.3.1" + default-value "^1.0.0" + flatten "^1.0.3" + is-arguments "^1.0.4" + +"@validatem/error@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@validatem/error/-/error-1.0.0.tgz#a975904aa4c3e7618d89088a393567a5e1778340" + integrity sha512-7M3tV4DhCuimuCRdC2L/topBByDjhzspzeQGNU0S4/mdn2aDNtESYE43K/2Kh/utCAhqXh2gyw89WYxy//t3fQ== + dependencies: + create-error "^0.3.1" + +"@validatem/has-shape@^0.1.0": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@validatem/has-shape/-/has-shape-0.1.5.tgz#7fc727e8254fa17c30e1eb4a7661767bb7701535" + integrity sha512-Ht+GOOZOle5A7QpcI8cXSfDoGIe//JrA70ibpFOVy7946WQAFmB2icoyUXwsZY+ybnZwY4g/y1NqyqVQ/Z8hzw== + dependencies: + "@validatem/annotate-errors" "^0.1.2" + "@validatem/combinator" "^0.1.0" + "@validatem/error" "^1.0.0" + "@validatem/validation-result" "^0.1.1" + as-expression "^1.0.0" + assure-array "^1.0.0" + default-value "^1.0.0" + flatten "^1.0.3" + +"@validatem/is-plain-object@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@validatem/is-plain-object/-/is-plain-object-0.1.1.tgz#b7a3ef8ef960882c7c41e84ed709fa0bfb932e93" + integrity sha512-aNGbNIbKRpYI0lRBczlTBbiA+nqN52ADAASdySKg2/QeSCVtYS4uOIeCNIJRAgXe/5sUnLTuL4pgq628uAl7Kw== + dependencies: + "@validatem/error" "^1.0.0" + is-plain-obj "^2.1.0" + +"@validatem/is-string@^0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@validatem/is-string/-/is-string-0.1.1.tgz#0710d8cebedd4d6861b4a8c63d7803ed6d2f9d6c" + integrity sha512-iyRVYRPgRt2ZlWyc7pzN1WkO6apzE8at39XQa4WUr8qRPfJn12V4khS9MumWbZs8N2qqajrxMigB2LJUCKOCRg== + dependencies: + "@validatem/error" "^1.0.0" + is-string "^1.0.5" + +"@validatem/match-special@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@validatem/match-special/-/match-special-0.1.0.tgz#4e0c28f1aee5bf53c1ef30bbf8c755d4946ae0ff" + integrity sha512-TFiq9Wk/1Hoja4PK85WwNYnwBXk3+Lgoj59ZIMxm2an1qmNYp8j+BnSvkKBflba451yIn6V1laU9NJf+/NYZgw== + +"@validatem/match-validation-error@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@validatem/match-validation-error/-/match-validation-error-0.1.0.tgz#fa87f5f1836e7c1d9bf6b75b2addf0a5b21e4c1e" + integrity sha512-6akGTk7DdulOreyqDiGdikwRSixQz/AlvARSX18dcWaTFc79KxCLouL2hyoFcor9IIUhu5RTY4/i756y4T1yxA== + dependencies: + "@validatem/match-versioned-special" "^0.1.0" + +"@validatem/match-versioned-special@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@validatem/match-versioned-special/-/match-versioned-special-0.1.0.tgz#2eacc48debecdbbe7e3d02f0c0a665afaea9bedf" + integrity sha512-xoOTY0bdA2ELj+ntcDVJ8YyMEFIJpjZ4HNPL9lGcbnRFwJBhQcHUAhUpZwkMxu02zH9wkNM1FvYGHxPz40745Q== + +"@validatem/match-virtual-property@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@validatem/match-virtual-property/-/match-virtual-property-0.1.0.tgz#4de2de1075987b5f3b356d3f2bcf6c0be5b5fb83" + integrity sha512-ssd3coFgwbLuqvZftLZTy3eHN0TFST8oTS2XTViQdXJPXVoJmwEKBpFhXgwnb5Ly1CE037R/KWpjhd1TP/56kQ== + +"@validatem/normalize-rules@^0.1.0": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@validatem/normalize-rules/-/normalize-rules-0.1.2.tgz#6529f17a6f36c6e2ae3ef285c59347c2ea208aa1" + integrity sha512-IHc81Sy/W0OiCbmvE3kTB+5OPVJnXWHP2tTXvKO6hVH0qykclMvIPRGgZf1s4dLaeOLKdkkfKyO/pLTVyNCIbA== + dependencies: + "@validatem/has-shape" "^0.1.0" + "@validatem/is-plain-object" "^0.1.0" + "@validatem/match-special" "^0.1.0" + assure-array "^1.0.0" + default-value "^1.0.0" + flatten "^1.0.3" + is-plain-obj "^2.1.0" + +"@validatem/required@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@validatem/required/-/required-0.1.1.tgz#64f4a87333fc5955511634036b7f8948ed269170" + integrity sha512-vI4NzLfay4RFAzp7xyU34PHb8sAo6w/3frrNh1EY9Xjnw2zxjY5oaxwmbFP1jVevBE6QQEnKogtzUHz/Zuvh6g== + +"@validatem/validation-result@^0.1.1": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@validatem/validation-result/-/validation-result-0.1.2.tgz#4e75cfd87305fc78f8d05ac84921a2c99a0348e0" + integrity sha512-okmP8JarIwIgfpaVcvZGuQ1yOsLKT3Egt49Ynz6h1MAeGsP/bGHXkkXtbiWOVsk5Tzku5vDVFSrFnF+5IEHKxw== + dependencies: + default-value "^1.0.0" + +"@validatem/virtual-property@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@validatem/virtual-property/-/virtual-property-0.1.0.tgz#880540dfd149f98ecf1095d93912e34443381fe4" + integrity sha512-JUUvWtdqoSkOwlsl20oB3qFHYIL05a/TAfdY4AJcs55QeVTiX5iI1b8IoQW644sIWWooBuLv+XwoxjRsQFczlQ== + +"@validatem/with-context@^0.1.0": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@validatem/with-context/-/with-context-0.1.2.tgz#3645c04897664f70995104961277e07b61b4f615" + integrity sha512-noAWf4CsmU+BCz+KOg3GPq9+R9BQLWOQnOgWVfkYHFdLnnbLhl8w/ONdzvFzUYGHIZGKZwsWVCp+Kwz/tAfMnA== + dependencies: + "@validatem/combinator" "^0.1.1" + +as-expression@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/as-expression/-/as-expression-1.0.0.tgz#7bc620ca4cb2fe0ee90d86729bd6add33b8fd831" + integrity sha512-Iqh4GxNUfxbJdGn6b7/XMzc8m1Dz2ZHouBQ9DDTzyMRO3VPPIAXeoY/sucRxxxXKbUtzwzWZSN6jPR3zfpYHHA== + +assure-array@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assure-array/-/assure-array-1.0.0.tgz#4f4ad16a87659d6200a4fb7103462033d216ec1f" + integrity sha1-T0rRaodlnWIApPtxA0YgM9IW7B8= + +create-error@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/create-error/-/create-error-0.3.1.tgz#69810245a629e654432bf04377360003a5351a23" + integrity sha1-aYECRaYp5lRDK/BDdzYAA6U1GiM= + +default-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-value/-/default-value-1.0.0.tgz#8c6f52a5a1193fe78fdc9f86eb71d16c9757c83a" + integrity sha1-jG9SpaEZP+eP3J+G63HRbJdXyDo= + dependencies: + es6-promise-try "0.0.1" + +es6-promise-try@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/es6-promise-try/-/es6-promise-try-0.0.1.tgz#10f140dad27459cef949973e5d21a087f7274b20" + integrity sha1-EPFA2tJ0Wc75SZc+XSGgh/cnSyA= + +flatten@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" + integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== + +is-arguments@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" + integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-string@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" + integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==