arstotzka 0.11.0 → 0.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/index.js +11 -7
  2. package/package.json +1 -1
  3. package/readme.md +28 -3
package/index.js CHANGED
@@ -4,7 +4,8 @@ export const ERRORS = {
4
4
  customFail: "Custom validation function failed",
5
5
  extraProperty: "Provided object contains properties not present in schema",
6
6
  exceptionOnCustom: "Exception thrown during constraint validation",
7
- notArray: "Tried using ARRAY_OF constraint on non-array value"
7
+ notArray: "Tried using ARRAY_OF constraint on non-array value",
8
+ targetIsNull: "Passed object or array item is null"
8
9
  };
9
10
 
10
11
  export const OPTIONAL = Symbol();
@@ -18,7 +19,7 @@ export function ARRAY_OF(rawConstraints){
18
19
  }
19
20
 
20
21
  const TYPE = t => x => typeof x == t;
21
- export const NOT_NULL = x => x !== null;
22
+ export const IS_NULL = x => x === null;
22
23
  export const IS_ARRAY = x => Array.isArray(x);
23
24
 
24
25
  function forbiddenObject(){
@@ -112,17 +113,21 @@ function stricterConstraints(raw){
112
113
  * - selfAlias ("_self"): Schema property name for referring nested object itself
113
114
  * @return Array of errors
114
115
  */
115
- export function validate(target = {}, schema = {}, options = {}){
116
+ export function validate(target, schema = {}, options = {}){
116
117
  options = Object.assign(VALIDATION_DEFAULTS, options)
117
118
  const errors = [];
118
119
 
119
- const targetKeys = Object.keys(target);
120
+ if (IS_NULL(target)) return [error(null, "targetIsNull", "object", target)];
121
+
122
+ const targetKeys = Object.keys(target || {});
120
123
  const schemaKeys = Object.keys(schema);
121
124
 
122
125
  for (let sKey of schemaKeys){
123
126
  if (!options.allErrors && errors.length > 0)
124
127
  return errors;
125
128
 
129
+ if (sKey == options.selfAlias) continue;
130
+
126
131
  const rawPropertySchema = schema[sKey];
127
132
  const schemaAsArray = arrayOfConstraints(rawPropertySchema, options.selfAlias);
128
133
  const flags = schemaAsArray.filter(c => typeof c == "symbol");
@@ -170,11 +175,10 @@ export function validate(target = {}, schema = {}, options = {}){
170
175
  }
171
176
 
172
177
  if (typeof rawPropertySchema == "object" && !Array.isArray(rawPropertySchema) && !isForbidden(rawPropertySchema)){
173
- delete rawPropertySchema[options.selfAlias];
174
-
175
178
  const nestedErrors = validate(target[sKey], rawPropertySchema, options);
176
179
  const mappedErrors = nestedErrors.map(e => {
177
- e.propertyName = `${sKey}.${e.propertyName}`;
180
+ const dot = IS_NULL(e.propertyName) ? "" : ".";
181
+ e.propertyName = `${sKey}${dot}${e.propertyName || ""}`;
178
182
  return e;
179
183
  });
180
184
  errors.push(...mappedErrors);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arstotzka",
3
- "version": "0.11.0",
3
+ "version": "0.11.2",
4
4
  "description": "JS validation utility",
5
5
  "main": "index.js",
6
6
  "type": "module",
package/readme.md CHANGED
@@ -5,6 +5,31 @@ JS data validation tool featuring laconic schema format and a sexy name.
5
5
 
6
6
  See detailed usage example in **[usage.js](https://github.com/MilesVII/arstotzka/blob/master/usage.js)**
7
7
 
8
+ ```
9
+ const schema = {
10
+ id: "number",
11
+ username: ["string", x => x.length < 10],
12
+ post: "string",
13
+ comments: Arstotzka.ARRAY_OF({
14
+ author: ["string", Arstotzka.OPTIONAL],
15
+ text: "string"
16
+ })
17
+ }
18
+
19
+ const goodData = {
20
+ id: 1337,
21
+ username: "mr.hands",
22
+ post: "Henlo there",
23
+ comments: [
24
+ {author: "Johnny", text: "henlo"},
25
+ {text: "hey hey"},
26
+ {author: "miles", text: "birb"},
27
+ ]
28
+ }
29
+
30
+ console.log(Arstotzka.validate(goodData, schema, {allowExtraProperties: false}));
31
+ ```
32
+
8
33
  ### Import:
9
34
  `import * as Arstotzka from "Arstotzka";`
10
35
 
@@ -14,14 +39,14 @@ See detailed usage example in **[usage.js](https://github.com/MilesVII/arstotzka
14
39
  - Aforemetioned requirements are called **constraints**.
15
40
  - Plain string constraints check porperty's type with [typeof operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof), with exception of "array" constraint -- validator will [treat this type](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray) as special case.
16
41
  - Examples: `name: "string"`, `id: "number"`, `list: "array"`
17
- - You can also specify custom constraint by providing a validation function. Validator will pass property value to it and will add an error if returned value is falsy. Exception thrown inside validation faction will be catched and added as errors into output
18
- - Examples: `positiveNumber: x => x > 0`, `nickname: x => x.length < 10`
42
+ - You can also specify custom constraint by providing a validation function. Validator will pass property value to it and will add an error if returned value is falsy. Exception thrown inside validation function will be catched and added as errors into output
43
+ - Examples: `notaNaN: x => !isNaN(x)`, `nickname: x => x.length < 10`
19
44
  - It is possible to validate nested objects by passing a schema object instead of constraint:
20
45
  - `user: {name: "string", age: "number"}`
21
46
  - If needed, you can still add constraints to the nested object itself, passing them to it's `_self` property. Name of the property can be changed in the options.
22
47
  - `phrase: {_self: x => x.text.length == x.letterCount, text: "string", letterCount: "number"}`
23
48
  - You can combine different constraints by passing an array of them.
24
- - Just like that: `nickname: ["string", x => x.length < 10]`, `count: ["number", x => x >= 0, x => x % 1 == 0]`
49
+ - Just like that: `nickname: ["string", x => x.length < 10]`, `count: ["number", x => x >= 0, x => x % 1 == 0]`
25
50
  - There are special constraints that serve as flags. (The only) one of them is **Arstotzka.OPTIONAL**. It allows to validate a property but prevents validator from adding an error if that property is not present in target object.
26
51
  - `commentary: ["string", Arstotzka.OPTIONAL]`
27
52
  - Finally, you can apply constraints to array's elements with **Arstotzka.ARRAY_OF()**. All the constraints passed to that function will be applied for each element.