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.
Files changed (43) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +131 -328
  3. package/dist/YINI.d.ts +34 -11
  4. package/dist/YINI.js +206 -121
  5. package/dist/core/ASTBuilder.d.ts +191 -0
  6. package/dist/core/ASTBuilder.js +827 -0
  7. package/dist/core/ErrorDataHandler.d.ts +19 -19
  8. package/dist/core/ErrorDataHandler.js +258 -150
  9. package/dist/core/objectBuilder.d.ts +9 -3
  10. package/dist/core/objectBuilder.js +126 -163
  11. package/dist/core/types.d.ts +234 -44
  12. package/dist/core/types.js +7 -33
  13. package/dist/grammar/YiniLexer.d.ts +54 -48
  14. package/dist/grammar/YiniLexer.js +330 -293
  15. package/dist/grammar/YiniParser.d.ts +167 -150
  16. package/dist/grammar/YiniParser.js +1241 -1202
  17. package/dist/grammar/YiniParserVisitor.d.ts +59 -45
  18. package/dist/grammar/YiniParserVisitor.js +1 -1
  19. package/dist/index.d.ts +4 -2
  20. package/dist/index.js +298 -120
  21. package/dist/parseEntry.d.ts +3 -2
  22. package/dist/parseEntry.js +352 -81
  23. package/dist/parsers/extractHeaderParts.d.ts +3 -2
  24. package/dist/parsers/extractHeaderParts.js +1 -0
  25. package/dist/parsers/parseBoolean.d.ts +1 -1
  26. package/dist/parsers/parseBoolean.js +2 -1
  27. package/dist/parsers/parseNumber.d.ts +8 -3
  28. package/dist/parsers/parseNumber.js +50 -16
  29. package/dist/parsers/parseSectionHeader.d.ts +3 -2
  30. package/dist/parsers/parseSectionHeader.js +1 -0
  31. package/dist/utils/number.d.ts +3 -0
  32. package/dist/utils/number.js +18 -0
  33. package/dist/utils/object.d.ts +55 -0
  34. package/dist/utils/object.js +85 -0
  35. package/dist/utils/string.d.ts +21 -1
  36. package/dist/utils/string.js +39 -4
  37. package/dist/utils/system.d.ts +15 -0
  38. package/dist/utils/system.js +21 -0
  39. package/dist/yiniHelpers.d.ts +3 -0
  40. package/dist/yiniHelpers.js +43 -7
  41. package/package.json +3 -3
  42. package/dist/core/YINIVisitor.d.ts +0 -158
  43. package/dist/core/YINIVisitor.js +0 -1010
@@ -1,49 +1,83 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const number_1 = require("../utils/number");
3
4
  const print_1 = require("../utils/print");
5
+ /**
6
+ * @property {string | undefined} [tag]
7
+ * This parameter is for debugging only. Its
8
+ * contents may change at any time and should not
9
+ * be relied upon for any significant purpose.
10
+ */
4
11
  const parseNumberLiteral = (txt) => {
5
12
  (0, print_1.debugPrint)('-> Entered parseNumberLiteral(..), txt: ' + txt);
6
- if (/^0[xX]|#/.test(txt)) {
13
+ if (/^[+-]?(?:\d+\.\d*|\d*\.?\d+)e[+-]?\d+$/i.test(txt)) {
14
+ // Exp. numbers
15
+ (0, print_1.debugPrint)('* Identified as an exp number');
16
+ return {
17
+ tag: 'From exp number, Number-Float',
18
+ // value: parseInt(txt.replace('#', '0x'), 16),
19
+ value: parseFloat(txt),
20
+ };
21
+ }
22
+ // --- Hexadecimal ---------
23
+ if (/^[+-]?(0[xX]|#)/.test(txt)) {
7
24
  // Prefix: 0x, 0X, #
8
25
  (0, print_1.debugPrint)('* Identified as a hex number');
26
+ (0, print_1.debugPrint)('parsed out HEX: ' + txt.replace(/0[xX]|#/, ''));
9
27
  return {
10
- type: 'Number-Integer',
28
+ tag: 'From hex number, Number-Integer',
11
29
  // value: parseInt(txt.replace('#', '0x'), 16),
12
- value: parseInt(txt.replace(/^0[xX]|#/, ''), 16),
30
+ value: parseInt(txt.replace(/0[xX]|#/, ''), 16),
13
31
  };
14
32
  }
15
- if (/^0[bB]|%/.test(txt)) {
33
+ // --- Binary ---------
34
+ if (/^[+-]?(0[bB]|%)/.test(txt)) {
16
35
  // Prefix: 0b, 0B, %
17
36
  (0, print_1.debugPrint)('* Identified as a bin number');
37
+ (0, print_1.debugPrint)('parsed out BIN: ' + txt.replace(/0[bB]|%/, ''));
18
38
  return {
19
- type: 'Number-Integer',
20
- value: parseInt(txt.replace(/^0[bB]|%/, ''), 2),
39
+ tag: 'From bin number, Number-Integer',
40
+ value: parseInt(txt.replace(/0[bB]|%/, ''), 2),
21
41
  };
22
42
  }
23
- if (/^0[oO]/.test(txt)) {
43
+ // --- Octal ---------
44
+ if (/^[+-]?0[oO]/.test(txt)) {
24
45
  // Prefix: 0o, 0O
25
- (0, print_1.debugPrint)('* Identified as a ord number');
46
+ (0, print_1.debugPrint)('* Identified as a oct number');
47
+ (0, print_1.debugPrint)('parsed out OCT: ' + txt.replace(/0[oO]/, ''));
26
48
  return {
27
- type: 'Number-Integer',
28
- value: parseInt(txt.replace(/^0[oO]/, ''), 8),
49
+ tag: 'From oct number, Number-Integer',
50
+ value: parseInt(txt.replace(/0[oO]/, ''), 8),
29
51
  };
30
52
  }
31
- if (/^0[zZ]/.test(txt)) {
32
- // Prefix: 0z, 0Z
53
+ // --- Duodecimal ---------
54
+ if (/^[+-]?0[zZ]/.test(txt)) {
55
+ // Prefix: 0z, 0Z, x = A = 10, e = B = 11.
33
56
  (0, print_1.debugPrint)('* Identified as a duodecimal number');
57
+ (0, print_1.debugPrint)('parsed out DOZ: ' + txt.replace(/0[zZ]/, ''));
58
+ txt = txt.replace(/[xX]/g, 'A');
59
+ txt = txt.replace(/[eE]/g, 'B');
60
+ (0, print_1.debugPrint)('Converter to AB form: ' + txt.replace(/0[zZ]/, ''));
34
61
  return {
35
- type: 'Number-Integer',
36
- value: parseInt(txt.replace(/^0[zZ]/, ''), 12),
62
+ tag: 'From doz (duodecimal) number, Number-Integer',
63
+ value: parseInt(txt.replace(/0[zZ]/, ''), 12),
37
64
  };
38
65
  }
39
66
  // In a regex literal the dot must be escaped (\.) to match a literal '.'
40
67
  if (/\./.test(txt)) {
41
68
  (0, print_1.debugPrint)('* Identified as a float number');
42
- return { type: 'Number-Float', value: parseFloat(txt) };
69
+ return {
70
+ tag: 'From float number, Number-Float',
71
+ value: parseFloat(txt),
72
+ };
43
73
  }
44
74
  // TODO: Depending, on mode, below continue or break on error
45
75
  //console.error('Error: Failed to parse number value: ' + txt)
76
+ if (!(0, number_1.isValidJSNumber)(txt)) {
77
+ (0, print_1.debugPrint)('* Identified as invalid number');
78
+ return { tag: 'From invalid number/value', value: undefined };
79
+ }
46
80
  (0, print_1.debugPrint)('* Identified as a int number');
47
- return { type: 'Number-Integer', value: parseInt(txt) };
81
+ return { tag: 'From int number, Number-Integer', value: parseInt(txt) };
48
82
  };
49
83
  exports.default = parseNumberLiteral;
@@ -1,11 +1,12 @@
1
1
  import { ErrorDataHandler } from '../core/ErrorDataHandler';
2
2
  import { TSectionHeaderType } from '../core/types';
3
- import { SectionContext } from '../grammar/YiniParser';
3
+ import { StmtContext } from '../grammar/YiniParser';
4
4
  /**
5
5
  * Extract ...
6
6
  * @param rawLine Raw line with the section header.
7
+ * @note Implemented without regexp to keep it less cryptic, etc.
7
8
  */
8
- declare const parseSectionHeader: (rawLine: string, errorHandler: ErrorDataHandler, ctx: null | SectionContext) => {
9
+ declare const parseSectionHeader: (rawLine: string, errorHandler: ErrorDataHandler, ctx: null | StmtContext) => {
9
10
  markerType: TSectionHeaderType;
10
11
  sectionName: string;
11
12
  sectionLevel: number;
@@ -11,6 +11,7 @@ const yiniHelpers_1 = require("../yiniHelpers");
11
11
  /**
12
12
  * Extract ...
13
13
  * @param rawLine Raw line with the section header.
14
+ * @note Implemented without regexp to keep it less cryptic, etc.
14
15
  */
15
16
  const parseSectionHeader = (rawLine, errorHandler, ctx) => {
16
17
  (0, print_1.debugPrint)('-> Entered parseSectionHeader(..)');
@@ -0,0 +1,3 @@
1
+ export declare const isNaNValue: (n: number) => boolean;
2
+ export declare const isInfinityValue: (n: number) => boolean;
3
+ export declare const isValidJSNumber: (str: string) => boolean;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isValidJSNumber = exports.isInfinityValue = exports.isNaNValue = void 0;
4
+ const isNaNValue = (n) => {
5
+ return Number.isNaN(n);
6
+ };
7
+ exports.isNaNValue = isNaNValue;
8
+ const isInfinityValue = (n) => {
9
+ return n === Infinity || n === -Infinity;
10
+ };
11
+ exports.isInfinityValue = isInfinityValue;
12
+ const isValidJSNumber = (str) => {
13
+ if (str.trim() === '')
14
+ return false; // Reject empty or whitespace-only.
15
+ const n = Number(str);
16
+ return !Number.isNaN(n); // True only if parse succeeded.
17
+ };
18
+ exports.isValidJSNumber = isValidJSNumber;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Removes top-level properties with value `undefined`.
3
+ * Does not recurse into nested objects or arrays.
4
+ *
5
+ * @param obj Any JS object
6
+ * @returns A shallow copy with undefined properties removed,
7
+ * except in nested objects or arrays.
8
+ *
9
+ * @example
10
+ * Input:
11
+ * const input = {
12
+ * a: 1,
13
+ * b: undefined,
14
+ * c: { d: undefined, e: 2 },
15
+ * f: [1, undefined, 2]
16
+ * };
17
+ *
18
+ * Output:
19
+ * {
20
+ * a: 1,
21
+ * c: { d: undefined, e: 2 },
22
+ * f: [1, undefined, 2]
23
+ * }
24
+ */
25
+ export declare const removeUndefinedShallow: <T extends object>(obj: T) => Partial<T>;
26
+ /**
27
+ * Recursively removes properties with value `undefined` from objects
28
+ * and arrays.
29
+ *
30
+ * @param obj Any JS value (object, array, primitive)
31
+ * @returns A deep-cloned copy with all `undefined` removed, including in
32
+ * nested objects and arrays.
33
+ *
34
+ * @example
35
+ * Input:
36
+ * const input = {
37
+ * a: 1,
38
+ * b: undefined,
39
+ * c: {
40
+ * d: undefined,
41
+ * e: 2,
42
+ * f: [1, undefined, { g: undefined, h: 42 }]
43
+ * }
44
+ * };
45
+ *
46
+ * Output:
47
+ * {
48
+ * a: 1,
49
+ * c: {
50
+ * e: 2,
51
+ * f: [1, { h: 42 }]
52
+ * }
53
+ * }
54
+ */
55
+ export declare const removeUndefinedDeep: <T>(obj: T) => T;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.removeUndefinedDeep = exports.removeUndefinedShallow = void 0;
4
+ /**
5
+ * Removes top-level properties with value `undefined`.
6
+ * Does not recurse into nested objects or arrays.
7
+ *
8
+ * @param obj Any JS object
9
+ * @returns A shallow copy with undefined properties removed,
10
+ * except in nested objects or arrays.
11
+ *
12
+ * @example
13
+ * Input:
14
+ * const input = {
15
+ * a: 1,
16
+ * b: undefined,
17
+ * c: { d: undefined, e: 2 },
18
+ * f: [1, undefined, 2]
19
+ * };
20
+ *
21
+ * Output:
22
+ * {
23
+ * a: 1,
24
+ * c: { d: undefined, e: 2 },
25
+ * f: [1, undefined, 2]
26
+ * }
27
+ */
28
+ const removeUndefinedShallow = (obj) => {
29
+ const cleaned = {};
30
+ for (const [key, value] of Object.entries(obj)) {
31
+ if (value !== undefined) {
32
+ cleaned[key] = value;
33
+ }
34
+ }
35
+ return cleaned;
36
+ };
37
+ exports.removeUndefinedShallow = removeUndefinedShallow;
38
+ /**
39
+ * Recursively removes properties with value `undefined` from objects
40
+ * and arrays.
41
+ *
42
+ * @param obj Any JS value (object, array, primitive)
43
+ * @returns A deep-cloned copy with all `undefined` removed, including in
44
+ * nested objects and arrays.
45
+ *
46
+ * @example
47
+ * Input:
48
+ * const input = {
49
+ * a: 1,
50
+ * b: undefined,
51
+ * c: {
52
+ * d: undefined,
53
+ * e: 2,
54
+ * f: [1, undefined, { g: undefined, h: 42 }]
55
+ * }
56
+ * };
57
+ *
58
+ * Output:
59
+ * {
60
+ * a: 1,
61
+ * c: {
62
+ * e: 2,
63
+ * f: [1, { h: 42 }]
64
+ * }
65
+ * }
66
+ */
67
+ const removeUndefinedDeep = (obj) => {
68
+ if (obj === null || typeof obj !== 'object') {
69
+ return obj; // primitive value
70
+ }
71
+ if (Array.isArray(obj)) {
72
+ // Clean each element, and filter out undefined entries
73
+ return obj
74
+ .map((item) => (0, exports.removeUndefinedDeep)(item))
75
+ .filter((item) => item !== undefined);
76
+ }
77
+ const cleaned = {};
78
+ for (const [key, value] of Object.entries(obj)) {
79
+ if (value !== undefined) {
80
+ cleaned[key] = (0, exports.removeUndefinedDeep)(value);
81
+ }
82
+ }
83
+ return cleaned;
84
+ };
85
+ exports.removeUndefinedDeep = removeUndefinedDeep;
@@ -2,12 +2,27 @@
2
2
  * This file contains general string helper functions (utils).
3
3
  * @note More specific YINI helper functions should go into yiniHelpers.ts-file.
4
4
  */
5
+ /**
6
+ * Capitalizes the first character of a string.
7
+ *
8
+ * @param str The input string.
9
+ * @returns A new string with the first character uppercased.
10
+ */
11
+ export declare const capitalizeFirst: (str: string) => string;
12
+ export declare const computeSha256: (content: string) => string;
5
13
  /**
6
14
  * Splits a string into an array of lines, handling both LF and CRLF newlines.
7
15
  * @param content The input string.
8
16
  * @returns Array of lines (strings).
9
17
  */
10
- export declare function splitLines(content: string): string[];
18
+ export declare const splitLines: (content: string) => string[];
19
+ /**
20
+ * Trims trailing non-letter characters (A–Z, a–z) from the end of a string.
21
+ *
22
+ * @param str Input string
23
+ * @returns String with trailing non-letters removed
24
+ */
25
+ export declare const trimTrailingNonLetters: (str: string) => string;
11
26
  /**
12
27
  * If a string starts and ends with a backtick `, if so trims the
13
28
  * first and last character (the backticks).
@@ -40,3 +55,8 @@ export declare const isDigit: (character: string) => boolean;
40
55
  * @deprecated This seems not useful anymore, use stripCommentsAndAfter(..) instead.
41
56
  */
42
57
  export declare const stripNLAndAfter: (line: string) => string;
58
+ /**
59
+ * Transforms strings such as 'Id-Name' to 'id_name'.
60
+ * Replaces all '-' to '_', and returns rusult in lower case.
61
+ */
62
+ export declare const toLowerSnakeCase: (txt: string) => string;
@@ -4,18 +4,45 @@
4
4
  * @note More specific YINI helper functions should go into yiniHelpers.ts-file.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.stripNLAndAfter = exports.isDigit = exports.isAlpha = exports.isEnclosedInBackticks = exports.trimBackticks = void 0;
8
- exports.splitLines = splitLines;
7
+ exports.toLowerSnakeCase = exports.stripNLAndAfter = exports.isDigit = exports.isAlpha = exports.isEnclosedInBackticks = exports.trimBackticks = exports.trimTrailingNonLetters = exports.splitLines = exports.computeSha256 = exports.capitalizeFirst = void 0;
8
+ const crypto_1 = require("crypto");
9
9
  const print_1 = require("./print");
10
+ /**
11
+ * Capitalizes the first character of a string.
12
+ *
13
+ * @param str The input string.
14
+ * @returns A new string with the first character uppercased.
15
+ */
16
+ const capitalizeFirst = (str) => {
17
+ if (!str)
18
+ return str;
19
+ return str.charAt(0).toUpperCase() + str.slice(1);
20
+ };
21
+ exports.capitalizeFirst = capitalizeFirst;
22
+ const computeSha256 = (content) => {
23
+ return (0, crypto_1.createHash)('sha256').update(content, 'utf8').digest('hex');
24
+ };
25
+ exports.computeSha256 = computeSha256;
10
26
  /**
11
27
  * Splits a string into an array of lines, handling both LF and CRLF newlines.
12
28
  * @param content The input string.
13
29
  * @returns Array of lines (strings).
14
30
  */
15
- function splitLines(content) {
31
+ const splitLines = (content) => {
16
32
  // Chould handle \n (LF), \r\n (CRLF), and even just \r (old Mac style).
17
33
  return content.split(/\r\n|\r|\n/);
18
- }
34
+ };
35
+ exports.splitLines = splitLines;
36
+ /**
37
+ * Trims trailing non-letter characters (A–Z, a–z) from the end of a string.
38
+ *
39
+ * @param str Input string
40
+ * @returns String with trailing non-letters removed
41
+ */
42
+ const trimTrailingNonLetters = (str) => {
43
+ return str.replace(/[^a-zA-Z]+$/g, '');
44
+ };
45
+ exports.trimTrailingNonLetters = trimTrailingNonLetters;
19
46
  /**
20
47
  * If a string starts and ends with a backtick `, if so trims the
21
48
  * first and last character (the backticks).
@@ -95,3 +122,11 @@ const stripNLAndAfter = (line) => {
95
122
  return resultLine;
96
123
  };
97
124
  exports.stripNLAndAfter = stripNLAndAfter;
125
+ /**
126
+ * Transforms strings such as 'Id-Name' to 'id_name'.
127
+ * Replaces all '-' to '_', and returns rusult in lower case.
128
+ */
129
+ const toLowerSnakeCase = (txt) => {
130
+ return txt.trim().toLowerCase().replace(/[-]/g, '_');
131
+ };
132
+ exports.toLowerSnakeCase = toLowerSnakeCase;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Error instance helper.
3
+ * @example
4
+ * ...
5
+ * } catch (err: unknown) {
6
+ * if (err instanceof Error) {
7
+ * console.error("Message:", err.message)
8
+ * console.error("Stack:", err.stack)
9
+ * } else {
10
+ * console.error("Unknown error:", err)
11
+ * console.error("Thrown value:", JSON.stringify(err))
12
+ * }
13
+ * }
14
+ */
15
+ export declare const isError: (e: unknown) => e is Error;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isError = void 0;
4
+ /**
5
+ * Error instance helper.
6
+ * @example
7
+ * ...
8
+ * } catch (err: unknown) {
9
+ * if (err instanceof Error) {
10
+ * console.error("Message:", err.message)
11
+ * console.error("Stack:", err.stack)
12
+ * } else {
13
+ * console.error("Unknown error:", err)
14
+ * console.error("Thrown value:", JSON.stringify(err))
15
+ * }
16
+ * }
17
+ */
18
+ const isError = (e) => {
19
+ return e instanceof Error;
20
+ };
21
+ exports.isError = isError;
@@ -2,6 +2,7 @@
2
2
  * This file contains specific YINI helper functions (utils).
3
3
  * @note More general helper functions should go into the dir "src/utils/".
4
4
  */
5
+ import { TScalarValue, TValueLiteral } from './core/types';
5
6
  /**
6
7
  * Check if the character is a section marker character.
7
8
  * @param character A character in a string.
@@ -42,3 +43,5 @@ export declare const isValidSimpleIdent: (str: string) => boolean;
42
43
  * @link https://github.com/YINI-lang/YINI-spec/blob/develop/YINI-Specification.md#34-identifiers
43
44
  */
44
45
  export declare const isValidBacktickedIdent: (str: string) => boolean;
46
+ export declare const printLiteral: (value: TValueLiteral) => void;
47
+ export declare const isScalar: (v: TValueLiteral) => v is TScalarValue;
@@ -4,7 +4,7 @@
4
4
  * @note More general helper functions should go into the dir "src/utils/".
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.isValidBacktickedIdent = exports.isValidSimpleIdent = exports.stripCommentsAndAfter = exports.isMarkerCharacter = void 0;
7
+ exports.isScalar = exports.printLiteral = exports.isValidBacktickedIdent = exports.isValidSimpleIdent = exports.stripCommentsAndAfter = exports.isMarkerCharacter = void 0;
8
8
  const print_1 = require("./utils/print");
9
9
  const string_1 = require("./utils/string");
10
10
  const SECTION_MARKER1 = '^';
@@ -37,11 +37,14 @@ exports.isMarkerCharacter = isMarkerCharacter;
37
37
  * @throws Will throw if consisting more than 1 lines.
38
38
  */
39
39
  const stripCommentsAndAfter = (line) => {
40
- if ((0, string_1.splitLines)(line).length > 1) {
41
- throw new Error('Internal error: Detected several row lines in line: >>>' +
42
- line +
43
- '<<<');
44
- }
40
+ // if (splitLines(line).length > 1) {
41
+ // throw new Error(
42
+ // 'Internal error: Detected several row lines in line: >>>' +
43
+ // line +
44
+ // '<<<',
45
+ // )
46
+ // }
47
+ line = line.split('\n', 1)[0];
45
48
  let idx1 = line.indexOf('//');
46
49
  let idx2 = line.indexOf('# '); // NOTE: (!) Hash comments requires a WS after the hash!
47
50
  let idx3 = line.indexOf('#\t'); // NOTE: (!) Hash comments requires a WS after the hash!
@@ -66,7 +69,7 @@ const stripCommentsAndAfter = (line) => {
66
69
  const resultLine = idx === Number.MAX_SAFE_INTEGER ? line : line.substring(0, idx);
67
70
  (0, print_1.debugPrint)('stripCommentsAndAfter(..), line: >>>' + line + '<<<');
68
71
  (0, print_1.debugPrint)('stripCommentsAndAfter(..), resultLine: >>>' + resultLine + '<<<');
69
- return resultLine;
72
+ return resultLine.trim();
70
73
  };
71
74
  exports.stripCommentsAndAfter = stripCommentsAndAfter;
72
75
  /**
@@ -139,3 +142,36 @@ const isValidBacktickedIdent = (str) => {
139
142
  return true;
140
143
  };
141
144
  exports.isValidBacktickedIdent = isValidBacktickedIdent;
145
+ const assertNever = (x) => {
146
+ throw new Error(`Unhandled: ${JSON.stringify(x)}`);
147
+ };
148
+ const printLiteral = (value) => {
149
+ switch (value.type) {
150
+ case 'String':
151
+ case 'Number':
152
+ case 'Boolean':
153
+ case 'Null':
154
+ console.log('' + value.value);
155
+ break;
156
+ case 'Undefined':
157
+ console.log('' + value.value);
158
+ break;
159
+ case 'List':
160
+ (0, print_1.printObject)(value.elems);
161
+ break;
162
+ case 'Object':
163
+ (0, print_1.printObject)(value.entries);
164
+ break;
165
+ default:
166
+ return assertNever(value); // ensures exhaustiveness
167
+ }
168
+ };
169
+ exports.printLiteral = printLiteral;
170
+ const isScalar = (v) => v.type === 'String' ||
171
+ v.type === 'Number' ||
172
+ v.type === 'Boolean' ||
173
+ v.type === 'Null';
174
+ exports.isScalar = isScalar;
175
+ // export const isList = (v: TValueLiteral): v is TListValue => v.type === 'List'
176
+ // export const isObject = (v: TValueLiteral): v is TObjectValue =>
177
+ // v.type === 'Object'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "yini-parser",
3
- "version": "1.0.1-beta",
4
- "description": "Simple and flexible config parser for Node.js. YINI: an enhanced, readable alternative to JSON, INI, and YAML—built for modern JavaScript and TypeScript projects.",
3
+ "version": "1.1.0-beta",
4
+ "description": "Node.js parser for YINI a clean, structured INI alternative with types, simple section nesting, comments, and strict mode.",
5
5
  "keywords": [
6
6
  "yini",
7
7
  "yini-parser",
@@ -19,7 +19,7 @@
19
19
  "nodejs",
20
20
  "javascript"
21
21
  ],
22
- "homepage": "https://m4se.com/yini-lang.org/",
22
+ "homepage": "https://github.com/YINI-lang/yini-parser-typescript",
23
23
  "license": "Apache-2.0",
24
24
  "files": [
25
25
  "dist/",