1 # JavaScript ObjectSchema Package
3 by [Nicholas C. Zakas](https://humanwhocodes.com)
5 If you find this useful, please consider supporting my work with a [donation](https://humanwhocodes.com/donate).
9 A 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()`.
13 You can install using either npm:
16 npm install @humanwhocodes/object-schema
22 yarn add @humanwhocodes/object-schema
27 Use CommonJS to get access to the `ObjectSchema` constructor:
30 const { ObjectSchema } = require("@humanwhocodes/object-schema");
32 const schema = new ObjectSchema({
34 // define a definition for the "downloads" key
37 merge(value1, value2) {
38 return value1 + value2;
41 if (typeof value !== "number") {
42 throw new Error("Expected downloads to be a number.");
47 // define a strategy for the "versions" key
50 merge(value1, value2) {
51 return value1.concat(value2);
54 if (!Array.isArray(value)) {
55 throw new Error("Expected versions to be an array.");
79 // make sure the records are valid
80 schema.validate(record1);
81 schema.validate(record2);
83 // merge together (schema.merge() accepts any number of objects)
84 const result = schema.merge(record1, record2);
86 // result looks like this:
103 ### Named merge strategies
105 Instead of specifying a `merge()` method, you can specify one of the following strings to use a default merge strategy:
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`.
114 const schema = new ObjectSchema({
122 ### Named validation strategies
124 Instead of specifying a `validate()` method, you can specify one of the following strings to use a default validation strategy:
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.
137 const schema = new ObjectSchema({
147 If 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:
150 const schema = new ObjectSchema({
173 ### Remove Keys During Merge
175 If the merge strategy for a key returns `undefined`, then the key will not appear in the final object. For example:
178 const schema = new ObjectSchema({
184 Date.parse(value); // throws an error when invalid
189 const object1 = { date: "5/5/2005" };
190 const object2 = { date: "6/6/2006" };
192 const result = schema.merge(object1, object2);
194 console.log("date" in result); // false
197 ### Requiring Another Key Be Present
199 If 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:
202 const schema = new ObjectSchema();
204 const schema = new ObjectSchema({
210 Date.parse(value); // throws an error when invalid
215 merge(first, second) {
224 // throws error: Key "time" requires keys "date"
230 In this example, even though `date` is an optional key, it is required to be present whenever `time` is present.