{"_id":"@apatheticwes/validation","_rev":"4-f17fad78f705c1f2f20c5a0a11a642a4","name":"@apatheticwes/validation","dist-tags":{"latest":"1.0.3"},"versions":{"1.0.0":{"name":"@apatheticwes/validation","version":"1.0.0","description":"A lightweight schema-based validation librarie, with a holistic approach to asynchronicity","main":"index.js","scripts":{"build":"rm -rf dist && tsc -b && rollup -c","test":"echo \"Error: no test specified\" && exit 1"},"keywords":["validation","vue","vue3","schema"],"author":{"name":"wes hatch"},"license":"MIT","dependencies":{"@vuelidate/validators":"^2.0.0-alpha.5","vue-demi":"^0.6.0"},"devDependencies":{"@rollup/plugin-node-resolve":"^11.1.0","@rollup/plugin-replace":"^2.3.4","rollup":"^2.37.1","typescript":"^4.1.3","vue":"3.0.5"},"peerDependencies":{"@vue/composition-api":"^1.0.0-rc.1","vue":"^2.0.0 || >=3.0.0-rc.0 || ^3.0.0"},"gitHead":"2521c32be61d594f2d61a335334ff70d69f4b508","_id":"@apatheticwes/validation@1.0.0","_nodeVersion":"15.5.1","_npmVersion":"7.3.0","dist":{"integrity":"sha512-06r7+kPkqxPXFn85EOOvHJhnMv/FAR8xuTkmG3iuIPlO8006zyU2osf8ixGzYyDgcYhycCmLA6R7SiNTIlYXFQ==","shasum":"89aa61cead25050dd44860f7d6af74a558cd4968","tarball":"https://registry.npmjs.org/@apatheticwes/validation/-/validation-1.0.0.tgz","fileCount":20,"unpackedSize":90415,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgEhJ+CRA9TVsSAnZWagAAz8kP/j8euxaGhE03ss5OwRI8\nUgCezv6bKg5xMGN3KHxfeemNp39tx7Jt2jMTV+ZMHItWWxeRoeM/ySt0gOwp\nbyLTqSzL9clKPjAMWRrvN004AcTijVdw3h29eicMXLn+yck3SiYH4tqIVq6w\nrTwV0WTDS9yCoaJK2KGAnPy3+gk99ClV0yuZjl7E8fY57UaLWHzP7d7X59TL\nU4b99Z/NU3oEo7euA8p0JHcSaia/p5/zECnEvv7l2gQh2gSmn1Bkry3Oq+T0\nD9HSYdFbTR+v0CG+6FqX/sfReAQH2A4MS+W7Vdf+L1Oe64GSCHKJSYD8teeU\n4mvWCvL1PKz5Qb9L8cl8rLYIXENdH+kQjPVxh/4yrOntBOEcqdeChDLU2BHR\nj9Hl8P60ObSEpPPMPH422/0iy18/nJVHADcIkgb5kyV8L9G5l5ntJ9FFQU8a\nsgm+17TXozD89gGYtp9liKAyO/R7htzGyZayPsL0gMvOIn1yV8aN5sMYj62X\nZ+IDX/CEoLt9KYy3KKQ3kCKOo+uTMzmm1gGBTYCyNnSV2TLISfAsJYsGDfUA\nKJkEH44H2VlxTnPJCdVT4sabt/MXEVdlwlQr01B4JrszTO1c34745SVifQzZ\nTtg8ozMTLgbQvj2qazmg0zBz7+BL/CyozMtMJRVGqDP74jTury3cQFM3zkJJ\nf16S\r\n=rqRX\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGqkeOI3vkUy6rYs8PpxZoPtSCVq9sM1iYYpRZrEG4rSAiEAlwaT1eCp/jum3WLA6+KMT0XjjnpJESKYow5N+9mfQIo="}]},"_npmUser":{"name":"apatheticwes","email":"wes.hatch@gmail.com"},"directories":{},"maintainers":[{"name":"apatheticwes","email":"wes.hatch@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/validation_1.0.0_1611797117779_0.6375671786782662"},"_hasShrinkwrap":false},"1.0.1":{"name":"@apatheticwes/validation","version":"1.0.1","description":"A lightweight schema-based validation librarie, with a holistic approach to asynchronicity","main":"index.js","scripts":{"build":"rm -rf dist && tsc -b && rollup -c","test":"echo \"Error: no test specified\" && exit 1"},"keywords":["validation","vue","vue3","schema"],"author":{"name":"wes hatch"},"license":"MIT","dependencies":{"@vuelidate/validators":"^2.0.0-alpha.5","vue-demi":"^0.6.0"},"devDependencies":{"@rollup/plugin-node-resolve":"^11.1.0","@rollup/plugin-replace":"^2.3.4","rollup":"^2.37.1","typescript":"^4.1.3","vue":"3.0.5"},"peerDependencies":{"@vue/composition-api":"^1.0.0-rc.1","vue":"^2.0.0 || >=3.0.0"},"gitHead":"3ca6b3c422d3d62d94d8df4be1ee7b2c69d66c5e","_id":"@apatheticwes/validation@1.0.1","_nodeVersion":"15.5.1","_npmVersion":"7.3.0","dist":{"integrity":"sha512-9y05aeYsQd+EqesMSsiyyMkSuV1KXk5AlSZx9DaGH4YRrEfPFfP2NHO364MHYfPP2ei9VnwkGhk8vVY2+zdojA==","shasum":"4c814d5c9fe6356b88c44ace48d818b6d9476e20","tarball":"https://registry.npmjs.org/@apatheticwes/validation/-/validation-1.0.1.tgz","fileCount":10,"unpackedSize":19597,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgGWhoCRA9TVsSAnZWagAAv2wP/iiV3vGMjH2eBNpS8tKm\nOWgA4bYrDVcNoNtPVRyy3fatBj3S+ACZphTy+eN1lp5LVpTG8/Pqz99nZEZP\nPPwVLaJ9/wofxhcdi8kbctDZi3FEUmHPAFeFiZdOUIN7q47b0Wi2LlXLOQLU\n2fWu/+lTWfclAeNIOzCPi1xMQN+2rKuRVggBM5P0mwD9xt61oa2WCmFyrd9F\nfCdpxyJJmNZSX0MyR0bjEuXyIOXreex6qg83/u/gDpwK5oVlQKIGkufuRTNV\nmxtjo+EjtpXRUsZHUWjQZ/wBIj4Fyr0T47hJ5tIupoG4a1Nsb7XuHzB+sDtc\nifIIcr5N/0ICNQG5JyGUEYG9xJhI/61yzU7tZZhaY28azBnpQdfh741tmNPc\nQwzanCVelLuLqxXG82kzKaV/tLnCHNUb+mNHMA4PdbnhcPFVOt0Klm+J8XBr\nVOPU6VV3hAlZB16QbFt6lxkp4+QATr+ctKrPnLw1grILSeLIvJ44vKhYNtjI\n+G/gYQt1jUE2d9ICws2fXetRMJkn11r730e/1wvNHjWwEHADKKOlJuPqLRHf\nbhxkDOCw2QBN8lDw0zojAMUUovlcTVh3+eFivxkE80FRm2gJDzglMTkX+6+z\n4k0TYmAxv0c8jdn6svIY5Ub0sePBtuiumadcF/xF1KpnUoPsoZ/1SUJGkmhN\n+jLo\r\n=Ktis\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCixeVLogntKemlhNjPMxzWy0tevKXl54Ryli5CA+G3xgIhANluYtJa+fJssvg6iDGhGNlpGFRolFZOAypWQy/iS8BZ"}]},"_npmUser":{"name":"apatheticwes","email":"wes.hatch@gmail.com"},"directories":{},"maintainers":[{"name":"apatheticwes","email":"wes.hatch@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/validation_1.0.1_1612277863637_0.16832663368428413"},"_hasShrinkwrap":false},"1.0.2":{"name":"@apatheticwes/validation","version":"1.0.2","description":"A lightweight schema-based validation librarie, with a holistic approach to asynchronicity","main":"dist/index.js","scripts":{"build":"rm -rf dist && tsc -b && rollup -c","test":"echo \"Error: no test specified\" && exit 1"},"keywords":["validation","vue","vue3","schema"],"author":{"name":"wes hatch"},"license":"MIT","dependencies":{"@vuelidate/validators":"^2.0.0-alpha.5","vue-demi":"^0.6.0"},"devDependencies":{"@rollup/plugin-node-resolve":"^11.1.0","@rollup/plugin-replace":"^2.3.4","rollup":"^2.37.1","typescript":"^4.1.3","vue":"3.0.5"},"peerDependencies":{"@vue/composition-api":"^1.0.0-rc.1","vue":"^2.0.0 || >=3.0.0"},"gitHead":"eaa8042291cfebd8b920b6bb1615f9835050c69b","_id":"@apatheticwes/validation@1.0.2","_nodeVersion":"15.5.1","_npmVersion":"7.3.0","dist":{"integrity":"sha512-PA2i3L1stAG7JyCdsJxZq2hy9nq5MTRN2o8q+QM6oqTFTcIy/KKKeOBpwQ4YZfg53TdeV1et0UMBK+cvlGuUuA==","shasum":"82a0438eac691dff5493cdfc99b6fc555b9089fc","tarball":"https://registry.npmjs.org/@apatheticwes/validation/-/validation-1.0.2.tgz","fileCount":14,"unpackedSize":25206,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgGWjTCRA9TVsSAnZWagAAuQUP/iPg7CLaXvaBOt89cPm0\nr9prhiGwCgRIwL2+Yi3yDlv2SLQjy57tqs0xlfhuQO6wt1Ty4+3NsEMuY9VS\n1B0UVzZXeAcSncdyeHy0z6lhxWDDmNKdU8ZdMUGWb7PBv3soGb32mcLjzutH\neiOW7HdVL9Sq+ru7mTtePM/syIG/Bf7lvJNyWI8Mm9I1DzlmFznOVcLh6An9\nEQs2T/LFVDbHJUtj5i0O6FUQXIHW6IB3S0mrtGNwODCrxp/8NwYCeETtGgT2\nUrW/uLaiTWziJu8+CRkB+AfsoMIoRO28et7iiUZ1QH1QCepNV6L6TnEZsPo9\nVhN97G7GbfqG9pyk+X3hSBjQ8Qv4S3UdVXm1HCUaNyZzNIsppa6yk3enfXTl\nC2vETZreA0h1T/YI5GV14VayIaN7ncJBFECjBycWLo4bGkBUYtSAHzFuFKZe\ntHDbJvx/uMFAyVUDO8SvxIINnuIFU9+QvGZlmR0ISUKQ61xK2wyOYkbWPGXB\nvoS/ox82SKP50ckUY1BdMmwr8xOLa9K0fk0yWBKm7hVz8o8pgEvtEWCjjGjr\nVBALKtGTvq3q9548soj2d9ySTImZ4OtlBWbZvYgmBvyRBgEYfyzkhH7Dw+lw\nfzSLe9bo/CFMyHqk8fwvfoT+Unnkaddaj9y96tDSTR/c5b1q48tKniLz0bkj\nih7d\r\n=ix62\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDMbQ2+XSZS6jmpxsjk/8fV6MYhnMi+3RirMsuUgRtlWgIgOmOUhgGxQqDEfAL0TL5V4pV3IX4wV4DyIh1tu43pBzo="}]},"_npmUser":{"name":"apatheticwes","email":"wes.hatch@gmail.com"},"directories":{},"maintainers":[{"name":"apatheticwes","email":"wes.hatch@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/validation_1.0.2_1612277970575_0.6614557539958803"},"_hasShrinkwrap":false},"1.0.3":{"name":"@apatheticwes/validation","version":"1.0.3","description":"A lightweight schema-based validation librarie, with a holistic approach to asynchronicity","main":"dist/index.js","scripts":{"build":"rm -rf dist && tsc -b && rollup -c","test":"echo \"Error: no test specified\" && exit 1"},"keywords":["validation","vue","vue3","schema"],"author":{"name":"wes hatch"},"license":"MIT","dependencies":{"@vuelidate/validators":"^2.0.0-alpha.5","vue-demi":"^0.6.0"},"devDependencies":{"@rollup/plugin-node-resolve":"^11.1.0","@rollup/plugin-replace":"^2.3.4","rollup":"^2.37.1","typescript":"^4.1.3","vue":"3.0.5"},"peerDependencies":{"@vue/composition-api":"^1.0.0-rc.1","vue":"^2.0.0 || >=3.0.0"},"gitHead":"10b14a44a75b91574d6266e1a4763a0af9a5642e","_id":"@apatheticwes/validation@1.0.3","_nodeVersion":"15.5.1","_npmVersion":"7.3.0","dist":{"integrity":"sha512-jvBsIYUXaJiTi3IvDA9xXEBYqhdftHlHIbfNbKmx11bkUvKKECHuxwEX4BpdeQ8NDM6dzpTdsllOs5JRZMbZwA==","shasum":"81277b4fb864ab2ca77996684a814aa30b1cd8f5","tarball":"https://registry.npmjs.org/@apatheticwes/validation/-/validation-1.0.3.tgz","fileCount":18,"unpackedSize":341447,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgIbjvCRA9TVsSAnZWagAAHSgQAIAgkJ0GMXdsOUKZl/EQ\nkCPcnLktpM5S9sgCOsvgc526xPiaYy12PHt45rngFeFcRq5pnjQH8F9R1QhZ\nv2PTnafwFhZEhEEg5p44ToyRqC9jpJD6dyqk8E10sG3Ta/Xi+IKJGksmjKNj\nI/OPLW9rIVx182/S9uFGWd8jc1shT42k9CqmKsOL0mmXEZdiKBG3nprD5O8j\nhoErMBRX/+0Tdjn7HgaUQaB/FLdQg1BDkE1x7EWD5kMvh0sYxakQFv/n6CiM\nWtjC6vlbi64NpOWgnDP5JjGKsE48lZh2JbV42ptkD5ZWZYA+gPypWm/D5s98\ncPKt5gvId0pJnf7CUMhp6n1rTTiZ5T5d+Nk6anp8czYdJSO+3AhLsz6Ngm2Z\nAtNUmytWUxgy3+nwBFNHC+Y0JuYmNYodFzqhriI4x0MyhvHhjEhVHjelgW0B\nnqVCmJkFn+xTpjkw+MnCCbUDrqzZD2wTDaLZ0ooMOxicMRilPQzSROozZSIp\nBbMqE2REWJYo8/90T66Zenfy3szIHYbQBAMzdUnmqn9+k+xedZVr/aneogNK\nqpoumtHMRWZUCDArmBLNkNs7b6la543KNn9D7Q2NgaqlYROfZdKR/Desv1lU\nNo+4w8/iq6K9P35ZnkaWX9Lsv7Ro5qV7vy8SsFiWjdGu+VskRGMcsA7HSuJ1\nWtvP\r\n=nKkt\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDtITBAMvE93G4ktMWZsXTbSqbeIvQ9Rpz5d8FuJLAcfQIgSFz1oj6oUjWpPh0DHRtMNxHchWdTY3/0TpOv+10dLFo="}]},"_npmUser":{"name":"apatheticwes","email":"wes.hatch@gmail.com"},"directories":{},"maintainers":[{"name":"apatheticwes","email":"wes.hatch@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/validation_1.0.3_1612822766973_0.405089134706081"},"_hasShrinkwrap":false}},"time":{"created":"2021-01-28T01:25:17.744Z","1.0.0":"2021-01-28T01:25:17.955Z","modified":"2022-04-04T14:32:36.679Z","1.0.1":"2021-02-02T14:57:43.745Z","1.0.2":"2021-02-02T14:59:30.675Z","1.0.3":"2021-02-08T22:19:27.155Z"},"maintainers":[{"name":"apatheticwes","email":"wes.hatch@gmail.com"}],"description":"A lightweight schema-based validation librarie, with a holistic approach to asynchronicity","keywords":["validation","vue","vue3","schema"],"author":{"name":"wes hatch"},"license":"MIT","readme":"# Validation\n\n> A schema-driven validation framework for Vue 3, providing reactive, client-side validation.\n\nThe Validation composable is a _reactive form object_. This object is consumed by the page component and used in its template, where it will automatically validate any user-entered data.\n\nIt requires a set of `values` (ie. component data) and `rules` to validate the them. The rules are a JSON-schema that define which inputs on a page need validation, and how.\n\n## At a Glance\n\n- Schema-based. Validation rules and structure may be imported, keeping the component lean\n- Flexible. Simply provide the validation with rules + values\n  - use the component's `data` as `values`, and provide rules elsewhere (no \"black box\" set up)\n  - optionally, sweep away both rules and values into a schema config (for a very lean component)\n- Reactive. Validation reacts to user input\n- Extensible. Easy to override and add new rules\n- Utilizes prior art. Validators from Vuelidate are leveraged; no need to reinvent the wheel\n- De-coupled. The reactive form-object can be injected _directly into the middleware_\n  - In the middleware a `server-generated` error (in the JSON error format) may be used to _hydrate_ the validation object\n- Optionated. May be _tightly integrated_ with the [ZigZag UI](https://github.com/apathetic/zigzag-ui). For example:\n  - Dedicated wrappers (or \"validation providers\") such as `z-field`.\n- Front-end / back-end \"agnostic\". The form-object can consume validation errors generated on either client or server\n- Future-looking. Leverages Vue 3 composition API\n\n## Getting Started\n\nSetting up a validation _schema_ is easy and flexible enough to handle a variety of use-cases.\n\n### Option 1\n\n- set up the `values` and their validation `rules` in an external schema, and import it.\n\n```\n// schemas/validation.js\nconst coolSchema = { ... };\nconst coolValues = { ... };\n\nexport function useCoolFormValidation() {\n  return useValidation(coolSchema, coolValues);\n}\n```\n\n```\n// coolComponent.vue\nimport { useCoolFormValidation } from '@/schemas';\n\nconst { form } = useCoolFormValidation();\n\n...\ncomputed() {\n  form: () => form\n}\n```\n\nThe advantage in this set-up is simplicity; the disadvantage is that the component's values are not readily visible to the developer, which may be opaque in the template.\n\n### Option 2\n\n- use your page component's data as `values`.\n- define the validation schema externally and \"curry\" them into the `useValidation` composable\n- use the `setValues` helper from the composable to asynchronously add values when they're available\n\n```\n// schemas/index.js\nconst coolSchema = { ... };\nexport function useCoolFormValidationNoValues() {\n  return useValidation(coolSchema);\n}\n```\n\n```\n// coolComponent.vue\nimport { useCoolFormValidationNoValues } from '@/schemas';\nconst { form, setValues } = useCoolFormValidationNoValues();\n\n...\ndata() ({\n  values: {\n    name: '',\n    email: '',\n  }\n}),\n\nbeforeCreate() {\n  // minor shortcut:\n  // after `setValues`, we make `form` a computed prop in the template while we're at it\n  this.$options.computed.form = setValues(this.values);\n}\n```\n\n\n\n## Validation object\n\n`useValidation` creates a reactive `form` _validation_ object. The returned object matches the same shape as the validation schema, except each field will be decorated/returned as follows:\n\n* There are be five (5) _core_ properties: `$model`, `$error`, `$dirty`, `$invalid` and `$errors`.\n\n```\n  \"$model\": \"horace\",\n  \"$error\": false, // helper for: $invalid && $dirty\n  \"$dirty\": false,\n  \"$invalid\": false,\n  \"$errors\": [ ... ]\n```\n\n* There are be _dynamic_ properties for each specific validation rule added (i.e. `required`, `email`, etc)\n```\n  // validation props. These are dynamic:\n  \"required\": true,   // passes required check\n  \"minLength\": false, // does not meet minLength criteria\n  \"email\": true,      // passes email validation\n  ...\n```\n\nNote the similarities with [vuelidate](https://github.com/vuelidate), from which this structure was borrowed.\n\n\n## Portability\n\nOnce created, the composable creates a reactive object representating a component's data. Reactive validation bindings will automically update if any data field is updated, and can be surfaced in the template.\n\nNote though, that it is equally possible to export the composable to the middleware where it may be used to hydrate server-side errors; any field or validation that is then updated here will automatically be surfaced in the template where it is used.\n\nFirst, we create the validation object:\n\n``` js\n// schemas/index\nconst schema = { ... };\nconst values = { ... };\nconst exampleForm = useValidation(schema, values);\n\nexport { exampleForm };\n```\n\nWe'd use the `exampleForm` in a page component as normal, but also, in an action:\n\n``` js\nexport const exampleAction = async ({ commit }) => {\n  try {\n    const exampleData = await api.settings.getExampleData();\n    ...\n  } catch (error) {\n    import('@/schemas/exampleForm') // WEBPACK conditional import.\n      .then((exampleForm) => {\n        exampleForm.setErrors(error);\n      });\n  }\n};\n```\nHere, we conditionally load the module and hydrate it upon any error(s) originating from the server. That's it! We can now surface _server errors_ anywhere in the page, without needed any conditional logic in the page or elsewhere.  If the server response is in the JSON-error format, the framework will unwrap it and even apply it to the corresponding field in the template automatically.\n\n\n## z-field\n\nThe `z-field` component may be used as a field wrapper. It accepts `errors` array from validation rules, or even a single `errors[0].$message` if desired. `z-field` can wrap any other UI components, and act as a decorator for error feedback.\n\n``` html\n  <z-field\n    v-for=\"(field, key, index) in form\"\n    :key=\"'field-' + key\"\n    :label=\"key\"\n    :errors=\"field.$errors\"\n    :hint=\"'Type in something for ' + key\"\n  >\n    <input v-model=\"field.$model\" />\n  </z-field>\n```\n\n## Notes\n\nWhen `npm i`, you'll need to use the `--force` option, as a peer dependency in `vuelidate/validators` does not correctly resolve.\n\n## References:\n\n`Validatable` draws inspiration from multiple sources.\n\n[Vue Composable](https://pikax.me/vue-composable/composable/validation/validation.html): Vue 3 composition API approach to\n[Vee Validate](https://logaretm.github.io/vee-validate/): Vue 3 composition API + \"validation provider\" component\n[Vuelidate](https://github.com/vuelidate/vuelidate/blob/master/src/index.js) for model based validation\n[Vuetify](https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/mixins/validatable/index.ts): Array validation approach\n","readmeFilename":"README.md"}