schema-markdown 1.1.0 → 1.1.4
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.
- package/README.md +8 -7
- package/lib/parser.js +1 -1
- package/lib/schema.js +15 -17
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -24,13 +24,14 @@ its features at a glance:
|
|
|
24
24
|
## Usage
|
|
25
25
|
|
|
26
26
|
To schema-validate an object, first parse its *Schema Markdown* using the
|
|
27
|
-
[SchemaMarkdownParser](https://craigahobbs.github.io/schema-markdown-js/SchemaMarkdownParser.html)
|
|
27
|
+
[SchemaMarkdownParser](https://craigahobbs.github.io/schema-markdown-js/module-lib_parser.SchemaMarkdownParser.html)
|
|
28
28
|
class:
|
|
29
29
|
|
|
30
30
|
``` javascript
|
|
31
|
-
import
|
|
31
|
+
import {SchemaMarkdownParser} from 'schema-markdown/parser.js';
|
|
32
|
+
import {validateType} from 'schema-markdown/schema.js';
|
|
32
33
|
|
|
33
|
-
const parser = new
|
|
34
|
+
const parser = new SchemaMarkdownParser(`\
|
|
34
35
|
# An aggregation function
|
|
35
36
|
enum Aggregation
|
|
36
37
|
Average
|
|
@@ -47,11 +48,11 @@ struct Operation
|
|
|
47
48
|
```
|
|
48
49
|
|
|
49
50
|
Then, validate an object using the
|
|
50
|
-
[validateType](https://craigahobbs.github.io/schema-markdown-js/
|
|
51
|
+
[validateType](https://craigahobbs.github.io/schema-markdown-js/module-lib_schema.html#.validateType)
|
|
51
52
|
function:
|
|
52
53
|
|
|
53
54
|
``` javascript
|
|
54
|
-
const obj =
|
|
55
|
+
const obj = validateType(parser.types, 'Operation', {
|
|
55
56
|
'numbers': [1, 2, '3', 4]
|
|
56
57
|
});
|
|
57
58
|
console.assert(obj.numbers[2] === 3);
|
|
@@ -62,7 +63,7 @@ Validation fails if the object does not match the schema:
|
|
|
62
63
|
|
|
63
64
|
``` javascript
|
|
64
65
|
try {
|
|
65
|
-
|
|
66
|
+
validateType(parser.types, 'Operation', {
|
|
66
67
|
'numbers': [1, 2, 'asdf', 4]
|
|
67
68
|
});
|
|
68
69
|
} catch ({message}) {
|
|
@@ -74,7 +75,7 @@ Validation also fails if a member contraint is violated:
|
|
|
74
75
|
|
|
75
76
|
``` javascript
|
|
76
77
|
try {
|
|
77
|
-
|
|
78
|
+
validateType(parser.types, 'Operation', {
|
|
78
79
|
'numbers': []
|
|
79
80
|
});
|
|
80
81
|
} catch ({message}) {
|
package/lib/parser.js
CHANGED
|
@@ -43,7 +43,7 @@ const RE_PART_TYPEDEF =
|
|
|
43
43
|
const RE_TYPEDEF = new RegExp('^typedef\\s+' + RE_PART_TYPEDEF + '\\s*$');
|
|
44
44
|
const RE_MEMBER = new RegExp('^\\s+(?<optional>optional\\s+)?' + RE_PART_TYPEDEF + '\\s*$');
|
|
45
45
|
const RE_VALUE = new RegExp('^\\s+(?<id>' + RE_PART_ID + ')\\s*$');
|
|
46
|
-
const RE_VALUE_QUOTED =
|
|
46
|
+
const RE_VALUE_QUOTED = /^\s+"(?<id>.*?)"\s*$/;
|
|
47
47
|
const RE_URL = /^\s+(?<method>[A-Za-z]+|\*)(?:\s+(?<path>\/[^\s]*))?/;
|
|
48
48
|
|
|
49
49
|
|
package/lib/schema.js
CHANGED
|
@@ -235,12 +235,12 @@ function validateTypeHelper(types, type, value, memberFqn) {
|
|
|
235
235
|
for (let ixArrayValue = 0; ixArrayValue < valueNew.length; ixArrayValue++) {
|
|
236
236
|
const memberFqnValue = memberFqn !== null ? `${memberFqn}.${ixArrayValue}` : `${ixArrayValue}`;
|
|
237
237
|
let arrayValue = valueNew[ixArrayValue];
|
|
238
|
-
if (arrayValue === null ||
|
|
238
|
+
if (arrayValueNullable && (arrayValue === null || arrayValue === 'null')) {
|
|
239
239
|
arrayValue = null;
|
|
240
240
|
} else {
|
|
241
241
|
arrayValue = validateTypeHelper(types, arrayType, arrayValue, memberFqnValue);
|
|
242
|
+
validateAttr(arrayType, arrayAttr, arrayValue, memberFqnValue);
|
|
242
243
|
}
|
|
243
|
-
validateAttr(arrayType, arrayAttr, arrayValue, memberFqnValue);
|
|
244
244
|
valueCopy.push(arrayValue);
|
|
245
245
|
}
|
|
246
246
|
|
|
@@ -269,20 +269,20 @@ function validateTypeHelper(types, type, value, memberFqn) {
|
|
|
269
269
|
const memberFqnKey = memberFqn !== null ? `${memberFqn}.${dictKey}` : `${dictKey}`;
|
|
270
270
|
|
|
271
271
|
// Validate the key
|
|
272
|
-
if (dictKey === null ||
|
|
272
|
+
if (dictKeyNullable && (dictKey === null || dictKey === 'null')) {
|
|
273
273
|
dictKey = null;
|
|
274
274
|
} else {
|
|
275
275
|
dictKey = validateTypeHelper(types, dictKeyType, dictKey, memberFqn);
|
|
276
|
+
validateAttr(dictKeyType, dictKeyAttr, dictKey, memberFqn);
|
|
276
277
|
}
|
|
277
|
-
validateAttr(dictKeyType, dictKeyAttr, dictKey, memberFqn);
|
|
278
278
|
|
|
279
279
|
// Validate the value
|
|
280
|
-
if (dictValue === null ||
|
|
280
|
+
if (dictValueNullable && (dictValue === null || dictValue === 'null')) {
|
|
281
281
|
dictValue = null;
|
|
282
282
|
} else {
|
|
283
283
|
dictValue = validateTypeHelper(types, dictType, dictValue, memberFqnKey);
|
|
284
|
+
validateAttr(dictType, dictAttr, dictValue, memberFqnKey);
|
|
284
285
|
}
|
|
285
|
-
validateAttr(dictType, dictAttr, dictValue, memberFqnKey);
|
|
286
286
|
|
|
287
287
|
// Copy the key/value
|
|
288
288
|
if (valueCopy instanceof Map) {
|
|
@@ -311,12 +311,12 @@ function validateTypeHelper(types, type, value, memberFqn) {
|
|
|
311
311
|
|
|
312
312
|
// Validate the value
|
|
313
313
|
const valueNullable = typedefAttr !== null && 'nullable' in typedefAttr && typedefAttr.nullable;
|
|
314
|
-
if (value === null ||
|
|
314
|
+
if (valueNullable && (value === null || value === 'null')) {
|
|
315
315
|
valueNew = null;
|
|
316
316
|
} else {
|
|
317
317
|
valueNew = validateTypeHelper(types, typedef.type, value, memberFqn);
|
|
318
|
+
validateAttr(type, typedefAttr, valueNew, memberFqn);
|
|
318
319
|
}
|
|
319
|
-
validateAttr(type, typedefAttr, valueNew, memberFqn);
|
|
320
320
|
|
|
321
321
|
// enum?
|
|
322
322
|
} else if ('enum' in userType) {
|
|
@@ -351,7 +351,8 @@ function validateTypeHelper(types, type, value, memberFqn) {
|
|
|
351
351
|
for (const member of getStructMembers(types, struct)) {
|
|
352
352
|
const memberName = member.name;
|
|
353
353
|
const memberFqnMember = memberFqn !== null ? `${memberFqn}.${memberName}` : `${memberName}`;
|
|
354
|
-
const memberOptional = 'optional' in member
|
|
354
|
+
const memberOptional = 'optional' in member && member.optional;
|
|
355
|
+
const memberNullable = 'attr' in member && 'nullable' in member.attr && member.attr.nullable;
|
|
355
356
|
|
|
356
357
|
// Missing non-optional member?
|
|
357
358
|
if (!(valueNew instanceof Map ? valueNew.has(memberName) : memberName in valueNew)) {
|
|
@@ -361,10 +362,12 @@ function validateTypeHelper(types, type, value, memberFqn) {
|
|
|
361
362
|
} else {
|
|
362
363
|
// Validate the member value
|
|
363
364
|
let memberValue = valueNew instanceof Map ? valueNew.get(memberName) : valueNew[memberName];
|
|
364
|
-
if (memberValue
|
|
365
|
+
if (memberNullable && (memberValue === null || memberValue === 'null')) {
|
|
366
|
+
memberValue = null;
|
|
367
|
+
} else {
|
|
365
368
|
memberValue = validateTypeHelper(types, member.type, memberValue, memberFqnMember);
|
|
369
|
+
validateAttr(member.type, 'attr' in member ? member.attr : null, memberValue, memberFqnMember);
|
|
366
370
|
}
|
|
367
|
-
validateAttr(member.type, 'attr' in member ? member.attr : null, memberValue, memberFqnMember);
|
|
368
371
|
|
|
369
372
|
// Copy the validated member
|
|
370
373
|
if (valueCopy instanceof Map) {
|
|
@@ -405,12 +408,7 @@ function throwMemberError(type, value, memberFqn, attr = null) {
|
|
|
405
408
|
|
|
406
409
|
|
|
407
410
|
function validateAttr(type, attr, value, memberFqn) {
|
|
408
|
-
if (
|
|
409
|
-
const valueNullable = attr !== null && 'nullable' in attr && attr.nullable;
|
|
410
|
-
if (!valueNullable) {
|
|
411
|
-
throwMemberError(type, value, memberFqn);
|
|
412
|
-
}
|
|
413
|
-
} else if (attr !== null) {
|
|
411
|
+
if (attr !== null) {
|
|
414
412
|
const length = Array.isArray(value) || typeof value === 'string' ? value.length
|
|
415
413
|
: (typeof value === 'object' ? Object.keys(value).length : null);
|
|
416
414
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "schema-markdown",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.4",
|
|
5
5
|
"description": "Human-friendly schema definition language and schema validator",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"schema",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"ava": "^4.0.0-rc.1",
|
|
28
28
|
"c8": "~7.10",
|
|
29
|
-
"eslint": "~8.
|
|
29
|
+
"eslint": "~8.4",
|
|
30
30
|
"jsdoc": "~3.6",
|
|
31
|
-
"jsdom": "~
|
|
31
|
+
"jsdom": "~19.0"
|
|
32
32
|
}
|
|
33
33
|
}
|