schema-markdown 1.0.5 → 1.1.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.
- package/README.md +4 -4
- package/lib/encode.js +130 -0
- package/{src/schema-markdown → lib}/parser.js +2 -0
- package/{src/schema-markdown → lib}/schema.js +17 -17
- package/{src/schema-markdown → lib}/schemaUtil.js +0 -0
- package/{src/schema-markdown → lib}/typeModel.js +5 -1
- package/package.json +5 -6
- package/index.js +0 -4
- package/src/schema-markdown/encode.js +0 -129
- package/src/schema-markdown/index.js +0 -26
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ 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
|
|
@@ -47,7 +47,7 @@ struct Operation
|
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
Then, validate an object using the
|
|
50
|
-
[validateType](https://craigahobbs.github.io/schema-markdown-js/
|
|
50
|
+
[validateType](https://craigahobbs.github.io/schema-markdown-js/module-lib_schema.html#.validateType)
|
|
51
51
|
function:
|
|
52
52
|
|
|
53
53
|
``` javascript
|
|
@@ -85,8 +85,8 @@ try {
|
|
|
85
85
|
|
|
86
86
|
## Development
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
using [javascript-template](https://github.com/craigahobbs/javascript-template#readme)
|
|
88
|
+
schema-markdown is developed using [javascript-build](https://github.com/craigahobbs/javascript-build#readme)
|
|
89
|
+
and it was started using [javascript-template](https://github.com/craigahobbs/javascript-template#readme):
|
|
90
90
|
|
|
91
91
|
```
|
|
92
92
|
template-specialize javascript-template/template/ schema-markdown-js/ -k package schema-markdown -k name 'Craig A. Hobbs' -k email 'craigahobbs@gmail.com' -k github 'craigahobbs' -k noapp 1
|
package/lib/encode.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// Licensed under the MIT License
|
|
2
|
+
// https://github.com/craigahobbs/schema-markdown-js/blob/main/LICENSE
|
|
3
|
+
|
|
4
|
+
/** @module lib/encode */
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Encode an object as a query/hash string. Dictionaries, lists, and tuples are recursed. Each member key is expressed
|
|
9
|
+
* in fully-qualified form. List keys are the index into the list, and are in order.
|
|
10
|
+
*
|
|
11
|
+
* @param {Object} obj - The parameters object
|
|
12
|
+
* @returns {string}
|
|
13
|
+
*/
|
|
14
|
+
export function encodeQueryString(obj) {
|
|
15
|
+
return encodeQueryStringHelper(obj).join('&');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
// Helper function for encodeQueryString
|
|
20
|
+
function encodeQueryStringHelper(obj, memberFqn = null, keyValues = []) {
|
|
21
|
+
const objType = typeof obj;
|
|
22
|
+
if (Array.isArray(obj)) {
|
|
23
|
+
if (obj.length === 0) {
|
|
24
|
+
keyValues.push(memberFqn !== null ? `${memberFqn}=` : '');
|
|
25
|
+
} else {
|
|
26
|
+
for (let ix = 0; ix < obj.length; ix++) {
|
|
27
|
+
encodeQueryStringHelper(obj[ix], memberFqn !== null ? `${memberFqn}.${ix}` : `${ix}`, keyValues);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
} else if (obj instanceof Date) {
|
|
31
|
+
const objEncoded = encodeURIComponent(obj.toISOString());
|
|
32
|
+
keyValues.push(memberFqn !== null ? `${memberFqn}=${objEncoded}` : `${objEncoded}`);
|
|
33
|
+
} else if (obj !== null && typeof obj === 'object') {
|
|
34
|
+
const keys = Object.keys(obj).sort();
|
|
35
|
+
if (keys.length === 0) {
|
|
36
|
+
keyValues.push(memberFqn !== null ? `${memberFqn}=` : '');
|
|
37
|
+
} else {
|
|
38
|
+
for (const key of keys) {
|
|
39
|
+
const keyEncoded = encodeQueryStringHelper(key);
|
|
40
|
+
encodeQueryStringHelper(obj[key], memberFqn !== null ? `${memberFqn}.${keyEncoded}` : `${keyEncoded}`, keyValues);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
} else if (obj === null || objType === 'boolean' || objType === 'number') {
|
|
44
|
+
keyValues.push(memberFqn !== null ? `${memberFqn}=${obj}` : `${obj}`);
|
|
45
|
+
} else {
|
|
46
|
+
const objEncoded = encodeURIComponent(obj);
|
|
47
|
+
keyValues.push(memberFqn !== null ? `${memberFqn}=${objEncoded}` : `${objEncoded}`);
|
|
48
|
+
}
|
|
49
|
+
return keyValues;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Decode an object from a query/hash string. Each member key of the query string is expressed in fully-qualified
|
|
55
|
+
* form. List keys are the index into the list, must be in order.
|
|
56
|
+
*
|
|
57
|
+
* @param {string} paramStr - The parameters string
|
|
58
|
+
* @returns {Object}
|
|
59
|
+
*/
|
|
60
|
+
export function decodeQueryString(paramStr) {
|
|
61
|
+
// Decode the parameter string key/values
|
|
62
|
+
const result = [null];
|
|
63
|
+
const keyValues = paramStr.split('&');
|
|
64
|
+
keyValues.forEach((keyValue, ixKeyValue) => {
|
|
65
|
+
const [keyFqn, valueEncoded = null] = keyValue.split('=', 2);
|
|
66
|
+
if (valueEncoded === null) {
|
|
67
|
+
// Ignore hash IDs
|
|
68
|
+
if (ixKeyValue === keyValues.length - 1) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
throw new Error(`Invalid key/value pair '${keyValue.slice(0, 100)}'`);
|
|
72
|
+
}
|
|
73
|
+
const value = decodeURIComponent(valueEncoded);
|
|
74
|
+
|
|
75
|
+
// Find/create the object on which to set the value
|
|
76
|
+
let parent = result;
|
|
77
|
+
let keyParent = 0;
|
|
78
|
+
const keys = keyFqn.split('.');
|
|
79
|
+
for (const keyEncoded of keys) {
|
|
80
|
+
let key = decodeURIComponent(keyEncoded);
|
|
81
|
+
let obj = parent[keyParent];
|
|
82
|
+
|
|
83
|
+
// Array key? First "key" of an array must start with "0".
|
|
84
|
+
if (Array.isArray(obj) || (obj === null && key === '0')) {
|
|
85
|
+
// Create this key's container, if necessary
|
|
86
|
+
if (obj === null) {
|
|
87
|
+
obj = [];
|
|
88
|
+
parent[keyParent] = obj;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Parse the key as an integer
|
|
92
|
+
if (isNaN(key)) {
|
|
93
|
+
throw new Error(`Invalid array index '${key.slice(0, 100)}' in key '${keyFqn.slice(0, 100)}'`);
|
|
94
|
+
}
|
|
95
|
+
const keyOrig = key;
|
|
96
|
+
key = parseInt(key, 10);
|
|
97
|
+
|
|
98
|
+
// Append the value placeholder null
|
|
99
|
+
if (key === obj.length) {
|
|
100
|
+
obj.push(null);
|
|
101
|
+
} else if (key < 0 || key > obj.length) {
|
|
102
|
+
throw new Error(`Invalid array index '${keyOrig.slice(0, 100)}' in key '${keyFqn.slice(0, 100)}'`);
|
|
103
|
+
}
|
|
104
|
+
} else {
|
|
105
|
+
// Create this key's container, if necessary
|
|
106
|
+
if (obj === null) {
|
|
107
|
+
obj = {};
|
|
108
|
+
parent[keyParent] = obj;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Create the index for this key
|
|
112
|
+
if (!(key in obj)) {
|
|
113
|
+
obj[key] = null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Update the parent object and key
|
|
118
|
+
parent = obj;
|
|
119
|
+
keyParent = key;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Set the value
|
|
123
|
+
if (parent[keyParent] !== null) {
|
|
124
|
+
throw new Error(`Duplicate key '${keyFqn.slice(0, 100)}'`);
|
|
125
|
+
}
|
|
126
|
+
parent[keyParent] = value;
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
return result[0] !== null ? result[0] : {};
|
|
130
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// Licensed under the MIT License
|
|
2
2
|
// https://github.com/craigahobbs/schema-markdown-js/blob/main/LICENSE
|
|
3
3
|
|
|
4
|
+
/** @module lib/schema */
|
|
5
|
+
|
|
4
6
|
import {typeModel} from './typeModel.js';
|
|
5
7
|
import {validateTypeModelTypesErrors} from './schemaUtil.js';
|
|
6
8
|
|
|
@@ -233,12 +235,12 @@ function validateTypeHelper(types, type, value, memberFqn) {
|
|
|
233
235
|
for (let ixArrayValue = 0; ixArrayValue < valueNew.length; ixArrayValue++) {
|
|
234
236
|
const memberFqnValue = memberFqn !== null ? `${memberFqn}.${ixArrayValue}` : `${ixArrayValue}`;
|
|
235
237
|
let arrayValue = valueNew[ixArrayValue];
|
|
236
|
-
if (arrayValue === null ||
|
|
238
|
+
if (arrayValueNullable && (arrayValue === null || arrayValue === 'null')) {
|
|
237
239
|
arrayValue = null;
|
|
238
240
|
} else {
|
|
239
241
|
arrayValue = validateTypeHelper(types, arrayType, arrayValue, memberFqnValue);
|
|
242
|
+
validateAttr(arrayType, arrayAttr, arrayValue, memberFqnValue);
|
|
240
243
|
}
|
|
241
|
-
validateAttr(arrayType, arrayAttr, arrayValue, memberFqnValue);
|
|
242
244
|
valueCopy.push(arrayValue);
|
|
243
245
|
}
|
|
244
246
|
|
|
@@ -267,20 +269,20 @@ function validateTypeHelper(types, type, value, memberFqn) {
|
|
|
267
269
|
const memberFqnKey = memberFqn !== null ? `${memberFqn}.${dictKey}` : `${dictKey}`;
|
|
268
270
|
|
|
269
271
|
// Validate the key
|
|
270
|
-
if (dictKey === null ||
|
|
272
|
+
if (dictKeyNullable && (dictKey === null || dictKey === 'null')) {
|
|
271
273
|
dictKey = null;
|
|
272
274
|
} else {
|
|
273
275
|
dictKey = validateTypeHelper(types, dictKeyType, dictKey, memberFqn);
|
|
276
|
+
validateAttr(dictKeyType, dictKeyAttr, dictKey, memberFqn);
|
|
274
277
|
}
|
|
275
|
-
validateAttr(dictKeyType, dictKeyAttr, dictKey, memberFqn);
|
|
276
278
|
|
|
277
279
|
// Validate the value
|
|
278
|
-
if (dictValue === null ||
|
|
280
|
+
if (dictValueNullable && (dictValue === null || dictValue === 'null')) {
|
|
279
281
|
dictValue = null;
|
|
280
282
|
} else {
|
|
281
283
|
dictValue = validateTypeHelper(types, dictType, dictValue, memberFqnKey);
|
|
284
|
+
validateAttr(dictType, dictAttr, dictValue, memberFqnKey);
|
|
282
285
|
}
|
|
283
|
-
validateAttr(dictType, dictAttr, dictValue, memberFqnKey);
|
|
284
286
|
|
|
285
287
|
// Copy the key/value
|
|
286
288
|
if (valueCopy instanceof Map) {
|
|
@@ -309,12 +311,12 @@ function validateTypeHelper(types, type, value, memberFqn) {
|
|
|
309
311
|
|
|
310
312
|
// Validate the value
|
|
311
313
|
const valueNullable = typedefAttr !== null && 'nullable' in typedefAttr && typedefAttr.nullable;
|
|
312
|
-
if (value === null ||
|
|
314
|
+
if (valueNullable && (value === null || value === 'null')) {
|
|
313
315
|
valueNew = null;
|
|
314
316
|
} else {
|
|
315
317
|
valueNew = validateTypeHelper(types, typedef.type, value, memberFqn);
|
|
318
|
+
validateAttr(type, typedefAttr, valueNew, memberFqn);
|
|
316
319
|
}
|
|
317
|
-
validateAttr(type, typedefAttr, valueNew, memberFqn);
|
|
318
320
|
|
|
319
321
|
// enum?
|
|
320
322
|
} else if ('enum' in userType) {
|
|
@@ -349,7 +351,8 @@ function validateTypeHelper(types, type, value, memberFqn) {
|
|
|
349
351
|
for (const member of getStructMembers(types, struct)) {
|
|
350
352
|
const memberName = member.name;
|
|
351
353
|
const memberFqnMember = memberFqn !== null ? `${memberFqn}.${memberName}` : `${memberName}`;
|
|
352
|
-
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;
|
|
353
356
|
|
|
354
357
|
// Missing non-optional member?
|
|
355
358
|
if (!(valueNew instanceof Map ? valueNew.has(memberName) : memberName in valueNew)) {
|
|
@@ -359,10 +362,12 @@ function validateTypeHelper(types, type, value, memberFqn) {
|
|
|
359
362
|
} else {
|
|
360
363
|
// Validate the member value
|
|
361
364
|
let memberValue = valueNew instanceof Map ? valueNew.get(memberName) : valueNew[memberName];
|
|
362
|
-
if (memberValue
|
|
365
|
+
if (memberNullable && (memberValue === null || memberValue === 'null')) {
|
|
366
|
+
memberValue = null;
|
|
367
|
+
} else {
|
|
363
368
|
memberValue = validateTypeHelper(types, member.type, memberValue, memberFqnMember);
|
|
369
|
+
validateAttr(member.type, 'attr' in member ? member.attr : null, memberValue, memberFqnMember);
|
|
364
370
|
}
|
|
365
|
-
validateAttr(member.type, 'attr' in member ? member.attr : null, memberValue, memberFqnMember);
|
|
366
371
|
|
|
367
372
|
// Copy the validated member
|
|
368
373
|
if (valueCopy instanceof Map) {
|
|
@@ -403,12 +408,7 @@ function throwMemberError(type, value, memberFqn, attr = null) {
|
|
|
403
408
|
|
|
404
409
|
|
|
405
410
|
function validateAttr(type, attr, value, memberFqn) {
|
|
406
|
-
if (
|
|
407
|
-
const valueNullable = attr !== null && 'nullable' in attr && attr.nullable;
|
|
408
|
-
if (!valueNullable) {
|
|
409
|
-
throwMemberError(type, value, memberFqn);
|
|
410
|
-
}
|
|
411
|
-
} else if (attr !== null) {
|
|
411
|
+
if (attr !== null) {
|
|
412
412
|
const length = Array.isArray(value) || typeof value === 'string' ? value.length
|
|
413
413
|
: (typeof value === 'object' ? Object.keys(value).length : null);
|
|
414
414
|
|
|
File without changes
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// Licensed under the MIT License
|
|
2
2
|
// https://github.com/craigahobbs/schema-markdown-js/blob/main/LICENSE
|
|
3
3
|
|
|
4
|
+
/** @module lib/typeModel */
|
|
5
|
+
|
|
4
6
|
import {SchemaMarkdownParser} from './parser.js';
|
|
5
7
|
|
|
6
8
|
|
|
@@ -251,7 +253,9 @@ struct ActionURL
|
|
|
251
253
|
`;
|
|
252
254
|
|
|
253
255
|
|
|
254
|
-
|
|
256
|
+
/**
|
|
257
|
+
* The Schema Markdown type model
|
|
258
|
+
*/
|
|
255
259
|
export const typeModel = {
|
|
256
260
|
'title': 'The Schema Markdown Type Model',
|
|
257
261
|
'types': (new SchemaMarkdownParser(typeModelSmd)).types
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "schema-markdown",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.1.2",
|
|
5
5
|
"description": "Human-friendly schema definition language and schema validator",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"schema",
|
|
@@ -18,17 +18,16 @@
|
|
|
18
18
|
"url": "https://github.com/craigahobbs"
|
|
19
19
|
},
|
|
20
20
|
"files": [
|
|
21
|
-
"
|
|
22
|
-
"src/schema-markdown/**/*"
|
|
21
|
+
"lib/**/*"
|
|
23
22
|
],
|
|
24
23
|
"scripts": {
|
|
25
|
-
"test": "ava -v
|
|
24
|
+
"test": "ava -v test/"
|
|
26
25
|
},
|
|
27
26
|
"devDependencies": {
|
|
28
27
|
"ava": "^4.0.0-rc.1",
|
|
29
28
|
"c8": "~7.10",
|
|
30
|
-
"eslint": "~8.
|
|
29
|
+
"eslint": "~8.3",
|
|
31
30
|
"jsdoc": "~3.6",
|
|
32
|
-
"jsdom": "~18.
|
|
31
|
+
"jsdom": "~18.1"
|
|
33
32
|
}
|
|
34
33
|
}
|
package/index.js
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
// Licensed under the MIT License
|
|
2
|
-
// https://github.com/craigahobbs/schema-markdown-js/blob/main/LICENSE
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Encode an object as a query/hash string. Dictionaries, lists, and tuples are recursed. Each member key is expressed
|
|
7
|
-
* in fully-qualified form. List keys are the index into the list, and are in order.
|
|
8
|
-
*
|
|
9
|
-
* @param {Object} obj - The parameters object
|
|
10
|
-
* @returns {string}
|
|
11
|
-
*/
|
|
12
|
-
export function encodeQueryString(obj) {
|
|
13
|
-
return encodeQueryStringHelper(obj).join('&');
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
// Helper function for encodeQueryString
|
|
18
|
-
function encodeQueryStringHelper(obj, memberFqn = null, keyValues = []) {
|
|
19
|
-
const objType = typeof obj;
|
|
20
|
-
if (Array.isArray(obj)) {
|
|
21
|
-
if (obj.length === 0) {
|
|
22
|
-
keyValues.push(memberFqn !== null ? `${memberFqn}=` : '');
|
|
23
|
-
} else {
|
|
24
|
-
for (let ix = 0; ix < obj.length; ix++) {
|
|
25
|
-
encodeQueryStringHelper(obj[ix], memberFqn !== null ? `${memberFqn}.${ix}` : `${ix}`, keyValues);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
} else if (obj instanceof Date) {
|
|
29
|
-
const objEncoded = encodeURIComponent(obj.toISOString());
|
|
30
|
-
keyValues.push(memberFqn !== null ? `${memberFqn}=${objEncoded}` : `${objEncoded}`);
|
|
31
|
-
} else if (obj !== null && typeof obj === 'object') {
|
|
32
|
-
const keys = Object.keys(obj).sort();
|
|
33
|
-
if (keys.length === 0) {
|
|
34
|
-
keyValues.push(memberFqn !== null ? `${memberFqn}=` : '');
|
|
35
|
-
} else {
|
|
36
|
-
for (const key of keys) {
|
|
37
|
-
const keyEncoded = encodeQueryStringHelper(key);
|
|
38
|
-
encodeQueryStringHelper(obj[key], memberFqn !== null ? `${memberFqn}.${keyEncoded}` : `${keyEncoded}`, keyValues);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
} else if (obj === null || objType === 'boolean' || objType === 'number') {
|
|
42
|
-
keyValues.push(memberFqn !== null ? `${memberFqn}=${obj}` : `${obj}`);
|
|
43
|
-
} else {
|
|
44
|
-
const objEncoded = encodeURIComponent(obj);
|
|
45
|
-
keyValues.push(memberFqn !== null ? `${memberFqn}=${objEncoded}` : `${objEncoded}`);
|
|
46
|
-
}
|
|
47
|
-
return keyValues;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Decode an object from a query/hash string. Each member key of the query string is expressed in fully-qualified
|
|
53
|
-
* form. List keys are the index into the list, must be in order.
|
|
54
|
-
*
|
|
55
|
-
* @param {string} paramStr - The parameters string
|
|
56
|
-
* @returns {Object}
|
|
57
|
-
*/
|
|
58
|
-
export function decodeQueryString(paramStr) {
|
|
59
|
-
// Decode the parameter string key/values
|
|
60
|
-
const result = [null];
|
|
61
|
-
paramStr.split('&').filter((keyValue) => keyValue.length).forEach(
|
|
62
|
-
(keyValue, ixKeyValue, keyValuesFiltered) => {
|
|
63
|
-
const [keyFqn, valueEncoded = null] = keyValue.split('=');
|
|
64
|
-
if (valueEncoded === null) {
|
|
65
|
-
// Ignore anchor tags
|
|
66
|
-
if (ixKeyValue === keyValuesFiltered.length - 1) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
throw new Error(`Invalid key/value pair '${keyValue.slice(0, 100)}'`);
|
|
70
|
-
}
|
|
71
|
-
const value = decodeURIComponent(valueEncoded);
|
|
72
|
-
|
|
73
|
-
// Find/create the object on which to set the value
|
|
74
|
-
let parent = result;
|
|
75
|
-
let keyParent = 0;
|
|
76
|
-
const keys = keyFqn.split('.');
|
|
77
|
-
for (const keyEncoded of keys) {
|
|
78
|
-
let key = decodeURIComponent(keyEncoded);
|
|
79
|
-
let obj = parent[keyParent];
|
|
80
|
-
|
|
81
|
-
// Array key? First "key" of an array must start with "0".
|
|
82
|
-
if (Array.isArray(obj) || (obj === null && key === '0')) {
|
|
83
|
-
// Create this key's container, if necessary
|
|
84
|
-
if (obj === null) {
|
|
85
|
-
obj = [];
|
|
86
|
-
parent[keyParent] = obj;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Parse the key as an integer
|
|
90
|
-
if (isNaN(key)) {
|
|
91
|
-
throw new Error(`Invalid array index '${key.slice(0, 100)}' in key '${keyFqn.slice(0, 100)}'`);
|
|
92
|
-
}
|
|
93
|
-
const keyOrig = key;
|
|
94
|
-
key = parseInt(key, 10);
|
|
95
|
-
|
|
96
|
-
// Append the value placeholder null
|
|
97
|
-
if (key === obj.length) {
|
|
98
|
-
obj.push(null);
|
|
99
|
-
} else if (key < 0 || key > obj.length) {
|
|
100
|
-
throw new Error(`Invalid array index '${keyOrig.slice(0, 100)}' in key '${keyFqn.slice(0, 100)}'`);
|
|
101
|
-
}
|
|
102
|
-
} else {
|
|
103
|
-
// Create this key's container, if necessary
|
|
104
|
-
if (obj === null) {
|
|
105
|
-
obj = {};
|
|
106
|
-
parent[keyParent] = obj;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Create the index for this key
|
|
110
|
-
if (!(key in obj)) {
|
|
111
|
-
obj[key] = null;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Update the parent object and key
|
|
116
|
-
parent = obj;
|
|
117
|
-
keyParent = key;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Set the value
|
|
121
|
-
if (parent[keyParent] !== null) {
|
|
122
|
-
throw new Error(`Duplicate key '${keyFqn.slice(0, 100)}'`);
|
|
123
|
-
}
|
|
124
|
-
parent[keyParent] = value;
|
|
125
|
-
}
|
|
126
|
-
);
|
|
127
|
-
|
|
128
|
-
return result[0] !== null ? result[0] : {};
|
|
129
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
// Licensed under the MIT License
|
|
2
|
-
// https://github.com/craigahobbs/schema-markdown-js/blob/main/LICENSE
|
|
3
|
-
|
|
4
|
-
export {
|
|
5
|
-
decodeQueryString,
|
|
6
|
-
encodeQueryString
|
|
7
|
-
} from './encode.js';
|
|
8
|
-
|
|
9
|
-
export {
|
|
10
|
-
SchemaMarkdownParser,
|
|
11
|
-
SchemaMarkdownParserError
|
|
12
|
-
} from './parser.js';
|
|
13
|
-
|
|
14
|
-
export {
|
|
15
|
-
ValidationError,
|
|
16
|
-
getEnumValues,
|
|
17
|
-
getReferencedTypes,
|
|
18
|
-
getStructMembers,
|
|
19
|
-
validateType,
|
|
20
|
-
validateTypeModel,
|
|
21
|
-
validateTypeModelTypes
|
|
22
|
-
} from './schema.js';
|
|
23
|
-
|
|
24
|
-
export {
|
|
25
|
-
typeModel
|
|
26
|
-
} from './typeModel.js';
|