yini-parser 1.0.1-beta → 1.1.0-beta
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/CHANGELOG.md +33 -0
- package/README.md +131 -328
- package/dist/YINI.d.ts +34 -11
- package/dist/YINI.js +206 -121
- package/dist/core/ASTBuilder.d.ts +191 -0
- package/dist/core/ASTBuilder.js +827 -0
- package/dist/core/ErrorDataHandler.d.ts +19 -19
- package/dist/core/ErrorDataHandler.js +258 -150
- package/dist/core/objectBuilder.d.ts +9 -3
- package/dist/core/objectBuilder.js +126 -163
- package/dist/core/types.d.ts +234 -44
- package/dist/core/types.js +7 -33
- package/dist/grammar/YiniLexer.d.ts +54 -48
- package/dist/grammar/YiniLexer.js +330 -293
- package/dist/grammar/YiniParser.d.ts +167 -150
- package/dist/grammar/YiniParser.js +1241 -1202
- package/dist/grammar/YiniParserVisitor.d.ts +59 -45
- package/dist/grammar/YiniParserVisitor.js +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +298 -120
- package/dist/parseEntry.d.ts +3 -2
- package/dist/parseEntry.js +352 -81
- package/dist/parsers/extractHeaderParts.d.ts +3 -2
- package/dist/parsers/extractHeaderParts.js +1 -0
- package/dist/parsers/parseBoolean.d.ts +1 -1
- package/dist/parsers/parseBoolean.js +2 -1
- package/dist/parsers/parseNumber.d.ts +8 -3
- package/dist/parsers/parseNumber.js +50 -16
- package/dist/parsers/parseSectionHeader.d.ts +3 -2
- package/dist/parsers/parseSectionHeader.js +1 -0
- package/dist/utils/number.d.ts +3 -0
- package/dist/utils/number.js +18 -0
- package/dist/utils/object.d.ts +55 -0
- package/dist/utils/object.js +85 -0
- package/dist/utils/string.d.ts +21 -1
- package/dist/utils/string.js +39 -4
- package/dist/utils/system.d.ts +15 -0
- package/dist/utils/system.js +21 -0
- package/dist/yiniHelpers.d.ts +3 -0
- package/dist/yiniHelpers.js +43 -7
- package/package.json +3 -3
- package/dist/core/YINIVisitor.d.ts +0 -158
- package/dist/core/YINIVisitor.js +0 -1010
|
@@ -1,185 +1,148 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.astToObject = void 0;
|
|
4
4
|
const env_1 = require("../config/env");
|
|
5
5
|
const print_1 = require("../utils/print");
|
|
6
6
|
/**
|
|
7
|
-
* Construct the final
|
|
7
|
+
* Construct the final JavaScript Object.
|
|
8
|
+
* Transforms the AST to the plain JS object.
|
|
9
|
+
*
|
|
10
|
+
* - Keys are used exactly as-is.
|
|
11
|
+
* - Order of properties matches the AST traversal order.
|
|
12
|
+
*
|
|
13
|
+
* @note All `tag` fields MUST be ignored.
|
|
8
14
|
*/
|
|
9
|
-
const
|
|
15
|
+
const astToObject = (ast, errorHandler) => {
|
|
10
16
|
(0, print_1.debugPrint)('-> constructFinalObject(..)');
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
(
|
|
17
|
+
// return sectionChildrenToObject(ast.root)
|
|
18
|
+
const out = {};
|
|
19
|
+
for (const child of ast.root.children) {
|
|
20
|
+
define(out, child.sectionName, sectionToObject(child));
|
|
15
21
|
}
|
|
16
|
-
|
|
17
|
-
(0, print_1.debugPrint)('<- About to leave constructFinalObject(..)');
|
|
18
|
-
if ((0, env_1.isDebug)()) {
|
|
19
|
-
console.log('Returning, jsObject:');
|
|
20
|
-
(0, print_1.printObject)(syntaxTreeC);
|
|
21
|
-
}
|
|
22
|
-
return jsObject;
|
|
22
|
+
return out;
|
|
23
23
|
};
|
|
24
|
-
exports.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
(0, print_1.debugPrint)('HIT - Detected that currentChain starts with level 1');
|
|
58
|
-
fullSubTreeList.push(workingFullSubTree);
|
|
59
|
-
(0, print_1.debugPrint)('The workingFullSubTree is finished, pushed it to the list.');
|
|
60
|
-
workingFullSubTree = syntaxTreeC._syntaxTree[i]; // (!) The tree MUST START at level 1.
|
|
61
|
-
(0, print_1.debugPrint)(`Setted new workingFullSubTree, from syntaxTreeC._syntaxTree[${i}]`);
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
(0, print_1.debugPrint)('About to mount currentChain onto workingFullSubTree at correct level...');
|
|
65
|
-
workingFullSubTree = this.mountChainOntoLevel(currentChainC, workingFullSubTree);
|
|
66
|
-
}
|
|
67
|
-
(0, print_1.debugPrint)();
|
|
68
|
-
}
|
|
69
|
-
fullSubTreeList.push(workingFullSubTree);
|
|
70
|
-
if ((0, env_1.isDebug)()) {
|
|
71
|
-
console.log();
|
|
72
|
-
console.log('--- fullSubTreeList: (list of FULL sub-trees.) -------');
|
|
73
|
-
(0, print_1.printObject)(fullSubTreeList);
|
|
74
|
-
console.log();
|
|
75
|
-
}
|
|
76
|
-
return fullSubTreeList;
|
|
24
|
+
exports.astToObject = astToObject;
|
|
25
|
+
/** Convert only the children of a section into an object keyed by sectionName. */
|
|
26
|
+
// function sectionChildrenToObject(
|
|
27
|
+
// section: YiniSection,
|
|
28
|
+
// ): Record<string, unknown> {
|
|
29
|
+
// const out: Record<string, unknown> = {}
|
|
30
|
+
// for (const child of section.children) {
|
|
31
|
+
// out[child.sectionName] = sectionToObject(child)
|
|
32
|
+
// }
|
|
33
|
+
// return out
|
|
34
|
+
// }
|
|
35
|
+
/** Convert a section (its members + nested sections) to a plain object. */
|
|
36
|
+
// function sectionToObject(node: YiniSection): Record<string, unknown> {
|
|
37
|
+
// const obj: Record<string, unknown> = {}
|
|
38
|
+
// // Members → properties
|
|
39
|
+
// for (const [key, val] of node.members.entries()) {
|
|
40
|
+
// obj[key] = literalToJS(val)
|
|
41
|
+
// }
|
|
42
|
+
// // Nested sections → nested objects keyed by sectionName
|
|
43
|
+
// for (const child of node.children) {
|
|
44
|
+
// obj[child.sectionName] = sectionToObject(child)
|
|
45
|
+
// }
|
|
46
|
+
// return obj
|
|
47
|
+
// }
|
|
48
|
+
/**
|
|
49
|
+
* Convert a section (members + nested sections) to a plain
|
|
50
|
+
* object, preserving order.
|
|
51
|
+
*/
|
|
52
|
+
const sectionToObject = (node) => {
|
|
53
|
+
const obj = {};
|
|
54
|
+
// 1) Members (Map preserves insertion order).
|
|
55
|
+
for (const [key, val] of node.members) {
|
|
56
|
+
define(obj, key, literalToJS(val));
|
|
77
57
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
(0, print_1.printObject)(chainC);
|
|
82
|
-
}
|
|
83
|
-
if (chainC.originLevel > 1) {
|
|
84
|
-
// NOP
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
// Note, after pushing processing may continue or exit, depending on the error and/or the bail threshold.
|
|
88
|
-
this.errorHandler.pushOrBail(null, 'Fatal-Error', 'Internal-Error: Detected incorrect chain in mountChainOntoLevel(..), start section has level: ' +
|
|
89
|
-
chainC.originLevel, 'The (chain) must start with a section level higher than 1', '' + (0, print_1.printObject)(chainC));
|
|
90
|
-
}
|
|
91
|
-
if (workingSubTree.originLevel != 1) {
|
|
92
|
-
// Note, after pushing processing may continue or exit, depending on the error and/or the bail threshold.
|
|
93
|
-
this.errorHandler.pushOrBail(null, 'Fatal-Error', 'Internal-Error: Detected incorrect full sub-tree in mountChainOntoLevel(..), start section has level: ' +
|
|
94
|
-
chainC.originLevel, 'A full sub-tree (chain) must start with a section at level 1', '' + (0, print_1.printObject)(chainC));
|
|
95
|
-
}
|
|
96
|
-
const chain = chainC.chain;
|
|
97
|
-
const targetLevel = chainC.originLevel;
|
|
98
|
-
if ((0, env_1.isDebug)()) {
|
|
99
|
-
(0, print_1.debugPrint)('Target level = ' + targetLevel);
|
|
100
|
-
(0, print_1.debugPrint)(`The chain to mount: (onto level: ${targetLevel})`);
|
|
101
|
-
(0, print_1.printObject)(chain);
|
|
102
|
-
(0, print_1.debugPrint)('--- workingFullSubTree: -------');
|
|
103
|
-
(0, print_1.debugPrint)('Before mounting onto workingSubTree.chain:');
|
|
104
|
-
(0, print_1.printObject)(workingSubTree.chain);
|
|
105
|
-
}
|
|
106
|
-
(0, print_1.debugPrint)('Mount currentChain onto workingFullSubTree.');
|
|
107
|
-
workingSubTree.chain = mountObjectAtLevel(workingSubTree.chain, chain, targetLevel, this.errorHandler);
|
|
108
|
-
if ((0, env_1.isDebug)()) {
|
|
109
|
-
(0, print_1.debugPrint)('After mounting onto workingSubTree.chain:');
|
|
110
|
-
(0, print_1.printObject)(workingSubTree.chain);
|
|
111
|
-
(0, print_1.debugPrint)('----------');
|
|
112
|
-
}
|
|
113
|
-
(0, print_1.debugPrint)('<- Builder: mountChainOntoLevel(..)');
|
|
114
|
-
return workingSubTree;
|
|
58
|
+
// 2) Nested sections (array order preserved).
|
|
59
|
+
for (const child of node.children) {
|
|
60
|
+
define(obj, child.sectionName, sectionToObject(child));
|
|
115
61
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
62
|
+
return obj;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Convert a literal to plain JS, ignoring both `tag` and `type`.
|
|
66
|
+
* - Scalars: return primitive value
|
|
67
|
+
* - List: return array (item order preserved)
|
|
68
|
+
* - Object: return plain object; iterate keys in creation order
|
|
69
|
+
*
|
|
70
|
+
* @note All `tag` fields MUST be ignored.
|
|
71
|
+
*/
|
|
72
|
+
const literalToJS = (v) => {
|
|
73
|
+
const IS_LOCAL_DEBUG = false;
|
|
74
|
+
(0, print_1.debugPrint)('In literalToJS(..)');
|
|
75
|
+
// if (!v) {
|
|
76
|
+
// // NOTE: Only in lenient-mode, if parsing a
|
|
77
|
+
// // member (key = value), but the value is invalid
|
|
78
|
+
// // key will get undefined
|
|
79
|
+
// return undefined
|
|
80
|
+
// }
|
|
81
|
+
switch (v.type) {
|
|
82
|
+
case 'String':
|
|
83
|
+
case 'Number':
|
|
84
|
+
case 'Boolean':
|
|
85
|
+
case 'Null':
|
|
86
|
+
return v.value;
|
|
87
|
+
case 'Undefined':
|
|
88
|
+
return undefined;
|
|
89
|
+
case 'List': {
|
|
90
|
+
if (IS_LOCAL_DEBUG) {
|
|
91
|
+
(0, print_1.debugPrint)("case 'List':");
|
|
122
92
|
if ((0, env_1.isDebug)()) {
|
|
123
|
-
console.log('
|
|
124
|
-
|
|
93
|
+
console.log('input:');
|
|
94
|
+
(0, print_1.printObject)(v);
|
|
125
95
|
}
|
|
126
|
-
|
|
96
|
+
}
|
|
97
|
+
const out = v.elems.map((elem) => {
|
|
98
|
+
const ret = literalToJS(elem);
|
|
99
|
+
if (IS_LOCAL_DEBUG) {
|
|
100
|
+
if ((0, env_1.isDebug)()) {
|
|
101
|
+
console.log(`elem:`);
|
|
102
|
+
(0, print_1.printObject)(elem);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return ret;
|
|
106
|
+
});
|
|
107
|
+
if (IS_LOCAL_DEBUG) {
|
|
127
108
|
if ((0, env_1.isDebug)()) {
|
|
128
|
-
console.log('
|
|
129
|
-
|
|
109
|
+
console.log('Returning:');
|
|
110
|
+
(0, print_1.printObject)(out);
|
|
130
111
|
}
|
|
131
112
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
case 'Object': {
|
|
116
|
+
const out = {};
|
|
117
|
+
// for (const key of Object.keys(v.entries)) {
|
|
118
|
+
// const entry = v.entries[key]
|
|
119
|
+
// if (isScalar(entry)) {
|
|
120
|
+
// // Scalar entries in object-literals: value
|
|
121
|
+
// // out[key] = { type: entry.type, value: entry.value }
|
|
122
|
+
// out[key] = entry.value
|
|
123
|
+
// } else if (entry.type === 'List') {
|
|
124
|
+
// out[key] = entry.elems.map(literalToJS)
|
|
125
|
+
// } else {
|
|
126
|
+
// out[key] = literalToJS(entry) // nested object-literal
|
|
127
|
+
// }
|
|
128
|
+
// }
|
|
129
|
+
// Object.keys preserves property insertion order for plain objects
|
|
130
|
+
for (const k of Object.keys(v.entries)) {
|
|
131
|
+
define(out, k, literalToJS(v.entries[k]));
|
|
136
132
|
}
|
|
133
|
+
return out;
|
|
137
134
|
}
|
|
138
|
-
return jsObject;
|
|
139
135
|
}
|
|
140
|
-
}
|
|
136
|
+
};
|
|
141
137
|
/**
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
* @return Returns a new object without mutating input objects.
|
|
138
|
+
* Helper function, defines a property to preserve explicit insertion
|
|
139
|
+
* order and enumerability.
|
|
145
140
|
*/
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
// Get all keys in current object.
|
|
154
|
-
const keys = Object.keys(current);
|
|
155
|
-
// Find first key where value is a plain object (not array).
|
|
156
|
-
const nextKey = keys.find((key) => current[key] &&
|
|
157
|
-
typeof current[key] === 'object' &&
|
|
158
|
-
!Array.isArray(current[key]));
|
|
159
|
-
if (!nextKey) {
|
|
160
|
-
// Could not reach the specified depth.
|
|
161
|
-
return result;
|
|
162
|
-
}
|
|
163
|
-
current = current[nextKey];
|
|
164
|
-
currentLevel++;
|
|
165
|
-
}
|
|
166
|
-
(0, print_1.debugPrint)('--------');
|
|
167
|
-
(0, print_1.debugPrint)(' current = ' + (0, print_1.toPrettyJSON)(current));
|
|
168
|
-
const [firstKey] = Object.keys(objectDest);
|
|
169
|
-
(0, print_1.debugPrint)('objectDest = ' + firstKey);
|
|
170
|
-
if (Object.prototype.hasOwnProperty.call(current, firstKey)) {
|
|
171
|
-
//@todo Add metadata with line number, onto chainC, so can use line number in error reporting
|
|
172
|
-
(0, print_1.debugPrint)(`(!) sectionName already exist, name: "${firstKey}", in: `);
|
|
173
|
-
(0, print_1.debugPrint)((0, print_1.toPrettyJSON)(current));
|
|
174
|
-
// Note, after pushing processing may continue or exit, depending on the error and/or the bail threshold.
|
|
175
|
-
errorHandler.pushOrBail(null, 'Syntax-Error', 'Section name already exists', 'Cannot redefine section name: "' +
|
|
176
|
-
firstKey +
|
|
177
|
-
'" at level ' +
|
|
178
|
-
currentLevel +
|
|
179
|
-
'.');
|
|
180
|
-
return current;
|
|
181
|
-
}
|
|
182
|
-
// Mount objectDest onto the object at the required level.
|
|
183
|
-
Object.assign(current, objectDest);
|
|
184
|
-
return result;
|
|
141
|
+
const define = (obj, key, value) => {
|
|
142
|
+
Object.defineProperty(obj, key, {
|
|
143
|
+
value,
|
|
144
|
+
enumerable: true,
|
|
145
|
+
configurable: true,
|
|
146
|
+
writable: true,
|
|
147
|
+
});
|
|
185
148
|
};
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1,59 +1,249 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @note
|
|
3
|
+
* The use of null vs undefined
|
|
4
|
+
* ----------------------------
|
|
5
|
+
* The convention here (in this file) is:
|
|
6
|
+
* - undefined is used where a value is missing, or does not apply.
|
|
7
|
+
* - null is used where a value is missing or has not yet been computed.
|
|
8
|
+
*/
|
|
3
9
|
export type TJSObject = any;
|
|
10
|
+
export type TSourceType = 'File' | 'Inline';
|
|
11
|
+
export type TSubjectType = 'None/Ignore' | TSourceType;
|
|
4
12
|
export type TBailSensitivityLevel = 0 | 1 | 2;
|
|
5
|
-
export
|
|
13
|
+
export type TPreferredFailLevel = 'auto' | 0 | 1 | 2;
|
|
14
|
+
export type TPersistThreshold = '0-Ignore-Errors' | '1-Abort-on-Errors' | '2-Abort-Even-on-Warnings';
|
|
15
|
+
/**
|
|
16
|
+
* Only for returned meta data to user.
|
|
17
|
+
* NOTE: Only use lower case snake_case for keys.
|
|
18
|
+
*/
|
|
19
|
+
export type TFailLevelKey = 'ignore_errors' | 'abort_on_errors' | 'abort_on_warnings';
|
|
20
|
+
/**
|
|
21
|
+
* Scalar literal, a single, indivisible piece of data:
|
|
22
|
+
* string, number, boolean, and null.
|
|
23
|
+
* @property {string | undefined} [tag]
|
|
24
|
+
* Its contents may change at any time and should not
|
|
25
|
+
* be relied upon for any significant purpose.
|
|
26
|
+
* @note Undefined is included here despite that JSON cannot represent
|
|
27
|
+
* it (undefined), but JS objects can (it's sometimes useful in
|
|
28
|
+
* debugging etc), it will later get stripped if converted into JSON.
|
|
29
|
+
*/
|
|
30
|
+
export type TScalarValue = {
|
|
31
|
+
type: 'String';
|
|
32
|
+
value: string;
|
|
33
|
+
tag: string | undefined;
|
|
34
|
+
} | {
|
|
35
|
+
type: 'Number';
|
|
36
|
+
value: number;
|
|
37
|
+
tag: string | undefined;
|
|
38
|
+
} | {
|
|
39
|
+
type: 'Boolean';
|
|
40
|
+
value: boolean;
|
|
41
|
+
tag: string | undefined;
|
|
42
|
+
} | {
|
|
43
|
+
type: 'Null';
|
|
44
|
+
value: null;
|
|
45
|
+
tag: string | undefined;
|
|
46
|
+
} | {
|
|
47
|
+
type: 'Undefined';
|
|
48
|
+
value: undefined;
|
|
49
|
+
tag: string | undefined;
|
|
50
|
+
};
|
|
51
|
+
/** Any literal value in YINI: scalar, list, or object. */
|
|
52
|
+
export type TValueLiteral = TScalarValue | TListValue | TObjectValue;
|
|
53
|
+
/**
|
|
54
|
+
* @property {string | undefined} [tag]
|
|
55
|
+
* Debugging only. Its contents may change at any time and
|
|
56
|
+
* must not be relied upon for any functional purpose.
|
|
57
|
+
*/
|
|
58
|
+
export type TListValue = {
|
|
59
|
+
type: 'List';
|
|
60
|
+
elems: readonly TValueLiteral[];
|
|
61
|
+
tag: string | undefined;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* @property {string | undefined} [tag]
|
|
65
|
+
* Debugging only. Its contents may change at any time and
|
|
66
|
+
* must not be relied upon for any functional purpose.
|
|
67
|
+
*/
|
|
68
|
+
export type TObjectValue = {
|
|
69
|
+
type: 'Object';
|
|
70
|
+
entries: Readonly<Record<string, TValueLiteral>>;
|
|
71
|
+
tag: string | undefined;
|
|
72
|
+
};
|
|
73
|
+
export type TSectionHeaderType = undefined | 'Classic-Header-Marker' | 'Numeric-Header-Marker';
|
|
74
|
+
export type TIssueType = 'Fatal-Error' | 'Internal-Error' | 'Syntax-Error' | 'Syntax-Warning' | 'Notice' | 'Info';
|
|
75
|
+
interface IMetaBaseInfo {
|
|
76
|
+
sourceType: TSourceType;
|
|
77
|
+
fileName: string | undefined;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Internal runtime info / meta data.
|
|
81
|
+
* @note Used for internal diagnostics, bookkeeping, state, etc.
|
|
82
|
+
*/
|
|
83
|
+
export interface IRuntimeInfo extends IMetaBaseInfo {
|
|
84
|
+
lineCount: number | null;
|
|
85
|
+
fileByteSize: number | null;
|
|
86
|
+
timeIoMs: number | null;
|
|
87
|
+
preferredBailSensitivity: null | TPreferredFailLevel;
|
|
88
|
+
sha256: string | null;
|
|
89
|
+
}
|
|
90
|
+
export interface IParseCoreOptions {
|
|
6
91
|
isStrict: boolean;
|
|
7
|
-
|
|
92
|
+
bailSensitivity: TBailSensitivityLevel;
|
|
8
93
|
isIncludeMeta: boolean;
|
|
9
94
|
isWithDiagnostics: boolean;
|
|
10
95
|
isWithTiming: boolean;
|
|
96
|
+
isKeepUndefinedInMeta: boolean;
|
|
97
|
+
isRequireDocTerminator: boolean;
|
|
11
98
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
99
|
+
/**
|
|
100
|
+
* User-facing options, these are external and should be more user friendly,
|
|
101
|
+
* and shorter, parameter names than the (more descriptive) internal
|
|
102
|
+
* engine option names.
|
|
103
|
+
*
|
|
104
|
+
* @note These parameters are emphasizes a bit more than the other options,
|
|
105
|
+
* therefor these are kept a bit shorter for usability-purposes.
|
|
106
|
+
* @note These are the same as in the "simple positional API" function in
|
|
107
|
+
* the YINI class.
|
|
108
|
+
*/
|
|
109
|
+
interface IPrimaryUserParams {
|
|
110
|
+
strictMode?: boolean;
|
|
111
|
+
failLevel?: TPreferredFailLevel;
|
|
112
|
+
includeMetaData?: boolean;
|
|
113
|
+
}
|
|
114
|
+
export interface IAllUserOptions extends IPrimaryUserParams {
|
|
115
|
+
includeDiagnostics?: boolean;
|
|
116
|
+
includeTiming?: boolean;
|
|
117
|
+
preserveUndefinedInMeta?: boolean;
|
|
118
|
+
requireDocTerminator?: boolean;
|
|
119
|
+
}
|
|
120
|
+
export interface IYiniAST extends IMetaBaseInfo {
|
|
121
|
+
root: IYiniSection;
|
|
122
|
+
isStrict: boolean;
|
|
123
|
+
terminatorSeen: boolean;
|
|
124
|
+
yiniMarkerSeen: boolean;
|
|
125
|
+
maxDepth: number | null;
|
|
126
|
+
numOfSections: number;
|
|
127
|
+
numOfMembers: number;
|
|
128
|
+
sectionNamePaths: string[] | null;
|
|
129
|
+
}
|
|
130
|
+
export interface IYiniSection {
|
|
131
|
+
sectionName: string;
|
|
132
|
+
level: number;
|
|
133
|
+
members: Map<string, TValueLiteral>;
|
|
134
|
+
children: IYiniSection[];
|
|
135
|
+
}
|
|
136
|
+
export interface IBuildOptions {
|
|
137
|
+
mode?: 'lenient' | 'strict';
|
|
138
|
+
onDuplicateKey?: 'error' | 'warn' | 'keep-first' | 'overwrite';
|
|
139
|
+
}
|
|
140
|
+
export interface IIssuePayload {
|
|
141
|
+
line: number | undefined;
|
|
142
|
+
column: number | undefined;
|
|
143
|
+
typeKey: string;
|
|
144
|
+
message: string;
|
|
145
|
+
advice: string | undefined;
|
|
146
|
+
hint: string | undefined;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* @note NOTE: USE NO TYPES here (or neither in nested structures), they
|
|
150
|
+
* should only be strings (and content MUST be transformed from the
|
|
151
|
+
* types to lower snake case)
|
|
152
|
+
*
|
|
153
|
+
* *** DUE TO make easier for tooling ***
|
|
154
|
+
*
|
|
155
|
+
* @note UPDATE 'metaSchemaVersion' on any edits to the meta structure.
|
|
156
|
+
*/
|
|
157
|
+
export interface IResultMetaData {
|
|
158
|
+
parserVersion: string;
|
|
159
|
+
mode: 'lenient' | 'strict';
|
|
160
|
+
orderPreserved: boolean;
|
|
161
|
+
totalErrors: number;
|
|
162
|
+
totalWarnings: number;
|
|
163
|
+
totalMessages: number;
|
|
164
|
+
runStartedAt: string;
|
|
165
|
+
runFinishedAt: string;
|
|
166
|
+
durationMs: number;
|
|
167
|
+
source: {
|
|
168
|
+
sourceType: string;
|
|
169
|
+
fileName: undefined | string;
|
|
170
|
+
hasDocumentTerminator: boolean;
|
|
171
|
+
hasYiniMarker: boolean;
|
|
172
|
+
byteSize: null | number;
|
|
173
|
+
lineCount: null | number;
|
|
174
|
+
sha256: null | string;
|
|
175
|
+
};
|
|
176
|
+
structure: {
|
|
177
|
+
maxDepth: null | number;
|
|
178
|
+
sectionCount: null | number;
|
|
179
|
+
memberCount: null | number;
|
|
180
|
+
keysParsedCount: null | number;
|
|
181
|
+
sectionNamePaths: string[] | null;
|
|
182
|
+
};
|
|
183
|
+
metaSchemaVersion: '1.0.0';
|
|
19
184
|
diagnostics?: {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
185
|
+
failLevel: {
|
|
186
|
+
preferredLevel: null | 'auto' | 0 | 1 | 2;
|
|
187
|
+
levelUsed: TBailSensitivityLevel;
|
|
188
|
+
levelKey: TFailLevelKey;
|
|
189
|
+
levelLabel: TPersistThreshold;
|
|
190
|
+
levelDescription: string | null;
|
|
191
|
+
};
|
|
192
|
+
errors: {
|
|
193
|
+
errorCount: number;
|
|
194
|
+
payload: IIssuePayload[];
|
|
195
|
+
};
|
|
196
|
+
warnings: {
|
|
197
|
+
warningCount: number;
|
|
198
|
+
payload: IIssuePayload[];
|
|
199
|
+
};
|
|
200
|
+
notices: {
|
|
201
|
+
noticeCount: number;
|
|
202
|
+
payload: IIssuePayload[];
|
|
203
|
+
};
|
|
204
|
+
infos: {
|
|
205
|
+
infoCount: number;
|
|
206
|
+
payload: IIssuePayload[];
|
|
207
|
+
};
|
|
208
|
+
environment: {
|
|
25
209
|
NODE_ENV: undefined | string;
|
|
26
210
|
APP_ENV: undefined | string;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
211
|
+
lib: {
|
|
212
|
+
nodeEnv: undefined | string;
|
|
213
|
+
appEnv: undefined | string;
|
|
214
|
+
flags: {
|
|
215
|
+
isDev: boolean;
|
|
216
|
+
isDebug: boolean;
|
|
217
|
+
};
|
|
218
|
+
};
|
|
33
219
|
};
|
|
220
|
+
optionsUsed: IAllUserOptions;
|
|
34
221
|
};
|
|
35
222
|
timing?: {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
223
|
+
total: null | {
|
|
224
|
+
timeMs: number;
|
|
225
|
+
name: string;
|
|
226
|
+
};
|
|
227
|
+
phase0: undefined | {
|
|
228
|
+
timeMs: number;
|
|
229
|
+
name: string;
|
|
230
|
+
};
|
|
231
|
+
phase1: null | {
|
|
232
|
+
timeMs: number;
|
|
233
|
+
name: string;
|
|
234
|
+
};
|
|
235
|
+
phase2: null | {
|
|
236
|
+
timeMs: number;
|
|
237
|
+
name: string;
|
|
238
|
+
};
|
|
239
|
+
phase3: null | {
|
|
240
|
+
timeMs: number;
|
|
241
|
+
name: string;
|
|
242
|
+
};
|
|
243
|
+
phase4: null | {
|
|
244
|
+
timeMs: number;
|
|
245
|
+
name: string;
|
|
246
|
+
};
|
|
40
247
|
};
|
|
41
248
|
}
|
|
42
|
-
export
|
|
43
|
-
_syntaxTree: TSyntaxTree;
|
|
44
|
-
_hasTerminal: boolean;
|
|
45
|
-
_meta_numOfSections: number;
|
|
46
|
-
_meta_numOfMembers: number;
|
|
47
|
-
_meta_numOfChains: number;
|
|
48
|
-
};
|
|
49
|
-
export type TSyntaxTree = IChainContainer[];
|
|
50
|
-
export type TSectionHeaderType = undefined | 'Classic-Header-Marker' | 'Numeric-Header-Marker';
|
|
51
|
-
export interface IChainContainer {
|
|
52
|
-
originLevel: number;
|
|
53
|
-
chain: any;
|
|
54
|
-
}
|
|
55
|
-
export interface ISectionResult {
|
|
56
|
-
level: number;
|
|
57
|
-
name: string;
|
|
58
|
-
members: any;
|
|
59
|
-
}
|
|
249
|
+
export {};
|
package/dist/core/types.js
CHANGED
|
@@ -1,36 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- Represents a single path from the starting section to the last (deepest) nested section.
|
|
10
|
-
- In other words, it’s a branch that forms a continuous, unbranched sequence of nested sections.
|
|
11
|
-
|
|
12
|
-
Example:
|
|
13
|
-
"
|
|
14
|
-
^ Section1
|
|
15
|
-
sValue = 1
|
|
16
|
-
^^ Section11
|
|
17
|
-
sValue = 11
|
|
18
|
-
bValue = OFF
|
|
19
|
-
^ Section2
|
|
20
|
-
sValue = 2
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
Has two Nested Linear Branches:
|
|
24
|
-
1:
|
|
25
|
-
^ Section1
|
|
26
|
-
sValue = 1
|
|
27
|
-
^^ Section11
|
|
28
|
-
sValue = 11
|
|
29
|
-
bValue = OFF
|
|
30
|
-
|
|
31
|
-
2:
|
|
32
|
-
^ Section2
|
|
33
|
-
sValue = 2
|
|
34
|
-
|
|
2
|
+
/**
|
|
3
|
+
* @note
|
|
4
|
+
* The use of null vs undefined
|
|
5
|
+
* ----------------------------
|
|
6
|
+
* The convention here (in this file) is:
|
|
7
|
+
* - undefined is used where a value is missing, or does not apply.
|
|
8
|
+
* - null is used where a value is missing or has not yet been computed.
|
|
35
9
|
*/
|
|
36
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|