basant307/AI_Governance_Project
048
1# JavaScript ObjectSchema Package2 3by [Nicholas C. Zakas](https://humanwhocodes.com)4 5If you find this useful, please consider supporting my work with a [donation](https://humanwhocodes.com/donate).6 7## Overview8 9A JavaScript object merge/validation utility where you can define a different merge and validation strategy for each key. This is helpful when you need to validate complex data structures and then merge them in a way that is more complex than `Object.assign()`.10 11## Installation12 13You can install using either npm:14 15```16npm install @humanwhocodes/object-schema17```18 19Or Yarn:20 21```22yarn add @humanwhocodes/object-schema23```24 25## Usage26 27Use CommonJS to get access to the `ObjectSchema` constructor:28 29```js30const { ObjectSchema } = require("@humanwhocodes/object-schema");31 32const schema = new ObjectSchema({33 34 // define a definition for the "downloads" key35 downloads: {36 required: true,37 merge(value1, value2) {38 return value1 + value2;39 },40 validate(value) {41 if (typeof value !== "number") {42 throw new Error("Expected downloads to be a number.");43 }44 }45 },46 47 // define a strategy for the "versions" key48 version: {49 required: true,50 merge(value1, value2) {51 return value1.concat(value2);52 },53 validate(value) {54 if (!Array.isArray(value)) {55 throw new Error("Expected versions to be an array.");56 }57 }58 }59});60 61const record1 = {62 downloads: 25,63 versions: [64 "v1.0.0",65 "v1.1.0",66 "v1.2.0"67 ]68};69 70const record2 = {71 downloads: 125,72 versions: [73 "v2.0.0",74 "v2.1.0",75 "v3.0.0"76 ]77};78 79// make sure the records are valid80schema.validate(record1);81schema.validate(record2);82 83// merge together (schema.merge() accepts any number of objects)84const result = schema.merge(record1, record2);85 86// result looks like this:87 88const result = {89 downloads: 75,90 versions: [91 "v1.0.0",92 "v1.1.0",93 "v1.2.0",94 "v2.0.0",95 "v2.1.0",96 "v3.0.0"97 ]98};99```100 101## Tips and Tricks102 103### Named merge strategies104 105Instead of specifying a `merge()` method, you can specify one of the following strings to use a default merge strategy:106 107* `"assign"` - use `Object.assign()` to merge the two values into one object.108* `"overwrite"` - the second value always replaces the first.109* `"replace"` - the second value replaces the first if the second is not `undefined`.110 111For example:112 113```js114const schema = new ObjectSchema({115 name: {116 merge: "replace",117 validate() {}118 }119});120```121 122### Named validation strategies123 124Instead of specifying a `validate()` method, you can specify one of the following strings to use a default validation strategy:125 126* `"array"` - value must be an array.127* `"boolean"` - value must be a boolean.128* `"number"` - value must be a number.129* `"object"` - value must be an object.130* `"object?"` - value must be an object or null.131* `"string"` - value must be a string.132* `"string!"` - value must be a non-empty string.133 134For example:135 136```js137const schema = new ObjectSchema({138 name: {139 merge: "replace",140 validate: "string"141 }142});143```144 145### Subschemas146 147If you are defining a key that is, itself, an object, you can simplify the process by using a subschema. Instead of defining `merge()` and `validate()`, assign a `schema` key that contains a schema definition, like this:148 149```js150const schema = new ObjectSchema({151 name: {152 schema: {153 first: {154 merge: "replace",155 validate: "string"156 },157 last: {158 merge: "replace",159 validate: "string"160 }161 }162 }163});164 165schema.validate({166 name: {167 first: "n",168 last: "z"169 }170});171```172 173### Remove Keys During Merge174 175If the merge strategy for a key returns `undefined`, then the key will not appear in the final object. For example:176 177```js178const schema = new ObjectSchema({179 date: {180 merge() {181 return undefined;182 },183 validate(value) {184 Date.parse(value); // throws an error when invalid185 }186 }187});188 189const object1 = { date: "5/5/2005" };190const object2 = { date: "6/6/2006" };191 192const result = schema.merge(object1, object2);193 194console.log("date" in result); // false195```196 197### Requiring Another Key Be Present198 199If you'd like the presence of one key to require the presence of another key, you can use the `requires` property to specify an array of other properties that any key requires. For example:200 201```js202const schema = new ObjectSchema();203 204const schema = new ObjectSchema({205 date: {206 merge() {207 return undefined;208 },209 validate(value) {210 Date.parse(value); // throws an error when invalid211 }212 },213 time: {214 requires: ["date"],215 merge(first, second) {216 return second;217 },218 validate(value) {219 // ...220 }221 }222});223 224// throws error: Key "time" requires keys "date"225schema.validate({226 time: "13:45"227});228```229 230In this example, even though `date` is an optional key, it is required to be present whenever `time` is present.231 232## License233 234BSD 3-Clause235 