toon-formatter 1.0.2 → 1.1.0

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/src/validator.js CHANGED
@@ -1,28 +1,28 @@
1
1
  /**
2
- * TOON String Validator
2
+ * TOON String Validator (Enhanced)
3
3
  */
4
4
 
5
5
  import { splitByDelimiter } from './utils.js';
6
6
 
7
7
  /**
8
- * Validates a TOON string for syntax and structural correctness
8
+ * Validates a TOON string for syntax and structural correctness (Synchronous)
9
9
  * @param {string} toonString - TOON string to validate
10
10
  * @returns {{isValid: boolean, error: string|null}} Validation result
11
11
  */
12
- export function validateToonString(toonString) {
12
+ export function validateToonStringSync(toonString) {
13
13
  if (!toonString || typeof toonString !== 'string') {
14
14
  return { isValid: false, error: 'Input must be a non-empty string.' };
15
15
  }
16
16
 
17
17
  const lines = toonString.split('\n');
18
- // Stack of contexts: { indent, type: 'root'|'object'|'array', expected?, count? }
18
+ // Stack of contexts: { indent, type: 'root'|'object'|'array', expected?, count?, isTabular? }
19
19
  const contextStack = [{ indent: 0, type: 'root', count: 0 }];
20
20
  let lineNumber = 0;
21
21
 
22
22
  // Regex Definitions (based on TOON Rules)
23
23
  const REGEX = {
24
24
  mapKey: /^[^:\[]+:\s*$/,
25
- arrayKey: /^[^:]+\[(\d+)([\t|])?\](?:\{[^}]+\})?:\s*(.*)$/, // Capture N, delimiter, content
25
+ arrayKey: /^[^:\[]+\[(\d+)([\t|])?\](?:\{[^}]+\})?:\s*(.*)$/, // Capture N, delimiter, content
26
26
  rootArray: /^\[(\d+)([\t|])?\](?:\{[^}]+\})?:\s*(.*)$/, // Capture N, delimiter, content
27
27
  listItem: /^\-.*/,
28
28
  listItemEmpty: /^\-\s*$/,
@@ -54,9 +54,30 @@ export function validateToonString(toonString) {
54
54
 
55
55
  const trimmedLine = line.trim();
56
56
  const currentIndent = rawLine.search(/\S|$/);
57
- const currentContext = contextStack[contextStack.length - 1];
57
+ let currentContext = contextStack[contextStack.length - 1];
58
58
  const requiredIndent = currentContext.indent;
59
59
 
60
+ // --- Strict Check for Empty Blocks ---
61
+ // If the previous line opened a block (like an array) but we didn't indent,
62
+ // and it wasn't an inline array, then it's an empty block.
63
+ // If the array expects items (size > 0), this is an error.
64
+ if (lineNumber > 1) {
65
+ const prevLineRaw = lines[lineNumber - 2];
66
+ const prevLineTrimmed = prevLineRaw.trim();
67
+ const arrMatch = prevLineTrimmed.match(REGEX.arrayKey) || prevLineTrimmed.match(REGEX.rootArray);
68
+
69
+ if (arrMatch && currentIndent <= requiredIndent) {
70
+ // It was an array declaration, and we are NOT inside it (no indent increase).
71
+ const size = parseInt(arrMatch[1], 10);
72
+ const content = arrMatch[3];
73
+
74
+ // If no inline content and size > 0, it's a missing block.
75
+ if ((!content || content.trim() === '') && size > 0) {
76
+ return { isValid: false, error: `L${lineNumber - 1}: Array declared with size ${size} but has no items (expected indented block).` };
77
+ }
78
+ }
79
+ }
80
+
60
81
  // --- Inline Array Validation ---
61
82
  let arrayMatch = trimmedLine.match(REGEX.arrayKey) || trimmedLine.match(REGEX.rootArray);
62
83
  if (arrayMatch) {
@@ -78,6 +99,7 @@ export function validateToonString(toonString) {
78
99
  }
79
100
  } else {
80
101
  // Block Array start.
102
+ // If it's Root Array at indent 0, update root context.
81
103
  if (trimmedLine.match(REGEX.rootArray) && contextStack.length === 1) {
82
104
  contextStack[0].type = 'array';
83
105
  contextStack[0].expected = size;
@@ -88,14 +110,17 @@ export function validateToonString(toonString) {
88
110
 
89
111
  // --- State Management (Tabular) ---
90
112
  if (isInsideTabularArray) {
113
+ // For tabular arrays, accept any indent >= root indent after the header
91
114
  const rootContext = contextStack[0];
92
115
  if (currentIndent >= rootContext.indent || (rootContext.indent === 0 && currentIndent > 0)) {
93
116
  if (trimmedLine.includes(':') && !trimmedLine.startsWith('"')) {
94
117
  return { isValid: false, error: `L${lineNumber}: Tabular rows cannot contain a colon.` };
95
118
  }
119
+ // Count tabular row as item
96
120
  if (rootContext.type === 'array') {
97
121
  rootContext.count++;
98
122
  }
123
+ // Update root indent if this is first data row
99
124
  if (rootContext.indent === 0) {
100
125
  rootContext.indent = currentIndent;
101
126
  }
@@ -113,30 +138,43 @@ export function validateToonString(toonString) {
113
138
  return { isValid: false, error: `L${lineNumber}: Indentation error.` };
114
139
  }
115
140
 
141
+ // Determine context type
116
142
  let newContext = { indent: currentIndent, type: 'object' };
117
143
 
118
144
  const prevArrayMatch = prevLineTrimmed.match(REGEX.arrayKey) || prevLineTrimmed.match(REGEX.rootArray);
119
145
  if (prevArrayMatch) {
146
+ // Check if this is a root array that was already initialized
120
147
  const isRootArrayAlreadySet = prevLineTrimmed.match(REGEX.rootArray) &&
121
148
  contextStack.length === 1 &&
122
149
  contextStack[0].type === 'array';
123
150
 
151
+ const isTabular = prevLineTrimmed.includes('{') && prevLineTrimmed.includes('}');
152
+
124
153
  if (!isRootArrayAlreadySet) {
154
+ // Create new array context for non-root arrays
125
155
  const size = parseInt(prevArrayMatch[1], 10);
126
- newContext = { indent: currentIndent, type: 'array', expected: size, count: 0 };
156
+ newContext = { indent: currentIndent, type: 'array', expected: size, count: 0, isTabular: isTabular };
127
157
  contextStack.push(newContext);
158
+ } else {
159
+ // For root arrays, update the existing context
160
+ contextStack[0].isTabular = isTabular;
128
161
  }
129
162
  } else {
130
163
  contextStack.push(newContext);
131
164
  }
132
165
 
166
+ // Update root array indent if this is the first indented item
133
167
  if (contextStack.length === 1 && contextStack[0].type === 'array' && contextStack[0].indent === 0) {
134
168
  contextStack[0].indent = currentIndent;
135
169
  }
136
170
 
171
+ // Count the current line if it's a list item in an array
137
172
  const targetContext = contextStack[contextStack.length - 1];
138
173
  if (targetContext.type === 'array') {
139
- if (trimmedLine.match(REGEX.listItem)) {
174
+ if (targetContext.isTabular) {
175
+ // Tabular items don't need dash
176
+ targetContext.count++;
177
+ } else if (trimmedLine.match(REGEX.listItem)) {
140
178
  targetContext.count++;
141
179
  }
142
180
  }
@@ -145,9 +183,11 @@ export function validateToonString(toonString) {
145
183
  // Un-indentation
146
184
  let foundMatch = false;
147
185
 
186
+ // Pop and Validate
148
187
  while (contextStack.length > 1) {
149
188
  const popped = contextStack.pop();
150
189
 
190
+ // Validate Array Size on Close
151
191
  if (popped.type === 'array') {
152
192
  if (popped.count !== popped.expected) {
153
193
  return { isValid: false, error: `Array size mismatch. Declared ${popped.expected}, found ${popped.count} items (ending around L${lineNumber}).` };
@@ -164,28 +204,41 @@ export function validateToonString(toonString) {
164
204
  return { isValid: false, error: `L${lineNumber}: Invalid un-indentation.` };
165
205
  }
166
206
 
207
+ // After popping, count items in parent context if it's an array
167
208
  const parentContext = contextStack[contextStack.length - 1];
168
209
  if (parentContext.type === 'array') {
169
- if (trimmedLine.match(REGEX.listItem)) {
210
+ if (parentContext.isTabular) {
211
+ parentContext.count++;
212
+ } else if (trimmedLine.match(REGEX.listItem)) {
170
213
  parentContext.count++;
171
214
  }
172
215
  }
173
216
 
174
217
  } else {
175
218
  // Same Indent
219
+ // If array, count items
176
220
  if (currentContext.type === 'array') {
177
- if (trimmedLine.match(REGEX.listItem)) {
221
+ if (currentContext.isTabular) {
222
+ currentContext.count++;
223
+ } else if (trimmedLine.match(REGEX.listItem)) {
178
224
  currentContext.count++;
179
225
  }
180
226
  }
181
227
  }
182
228
 
229
+ // Update currentContext as it might have changed (push/pop)
230
+ currentContext = contextStack[contextStack.length - 1];
231
+
183
232
  // --- Syntax Check ---
184
233
  if (trimmedLine.match(REGEX.arrayKey) || trimmedLine.match(REGEX.rootArray)) {
185
234
  if (startsTabular(trimmedLine)) isInsideTabularArray = true;
186
235
  }
187
236
  else if (trimmedLine.match(REGEX.mapKey)) { }
188
- else if (trimmedLine.match(REGEX.listItem)) { }
237
+ else if (trimmedLine.match(REGEX.listItem)) {
238
+ if (currentContext.type !== 'array') {
239
+ return { isValid: false, error: `L${lineNumber}: List item found in non-array context.` };
240
+ }
241
+ }
189
242
  else if (trimmedLine.includes(':')) {
190
243
  if (!trimmedLine.match(REGEX.keyValue)) {
191
244
  return { isValid: false, error: `L${lineNumber}: Invalid Key-Value assignment.` };
@@ -216,3 +269,12 @@ export function validateToonString(toonString) {
216
269
 
217
270
  return { isValid: true, error: null };
218
271
  }
272
+
273
+ /**
274
+ * Validates a TOON string for syntax and structural correctness (Async)
275
+ * @param {string} toonString - TOON string to validate
276
+ * @returns {{isValid: boolean, error: string|null}} Validation result
277
+ */
278
+ export async function validateToonString(toonString) {
279
+ return validateToonStringSync(toonString);
280
+ }
package/src/xml.js CHANGED
@@ -3,8 +3,8 @@
3
3
  * Note: This module is designed for Node.js environments
4
4
  */
5
5
 
6
- import { jsonToToon, toonToJson } from './json.js';
7
- import { encodeXmlReservedChars } from './utils.js';
6
+ import { jsonToToonSync, toonToJsonSync } from './json.js';
7
+ import { encodeXmlReservedChars, extractXmlFromString } from './utils.js';
8
8
 
9
9
  /**
10
10
  * Converts XML DOM to JSON object
@@ -115,60 +115,112 @@ function jsonObjectToXml(obj) {
115
115
  }
116
116
 
117
117
  /**
118
- * Converts XML to TOON format (Browser environment)
119
- * @param {string} xmlString - XML formatted string
120
- * @returns {string} TOON formatted string
121
- * @throws {Error} If XML is invalid or DOMParser is not available
118
+ * Internal core function to convert pure XML string to TOON (Sync)
119
+ * @param {string} xmlString
120
+ * @returns {string}
122
121
  */
123
- export async function xmlToToon(xmlString) {
124
- if (!xmlString || typeof xmlString !== 'string') {
125
- throw new Error('Input must be a non-empty string');
126
- }
122
+ function parseXmlToToonSync(xmlString) {
123
+ let Parser;
127
124
 
128
- // Check if we're in a browser environment
129
125
  if (typeof DOMParser !== 'undefined') {
130
- const parser = new DOMParser();
131
- const xmlDoc = parser.parseFromString(
132
- encodeXmlReservedChars(xmlString),
133
- 'application/xml'
134
- );
126
+ Parser = DOMParser;
127
+ } else {
128
+ throw new Error('DOMParser is not available. For synchronous XML conversion in Node.js, please use the async version `xmlToToon` or polyfill global.DOMParser.');
129
+ }
130
+
131
+ const parser = new Parser();
132
+ const xmlDoc = parser.parseFromString(
133
+ encodeXmlReservedChars(xmlString),
134
+ 'application/xml'
135
+ );
135
136
 
137
+ // Check for parser errors (works in both browser and xmldom)
138
+ if (xmlDoc.querySelector) {
139
+ // Browser environment
136
140
  const parserError = xmlDoc.querySelector('parsererror');
137
141
  if (parserError) {
138
142
  throw new Error(parserError.textContent);
139
143
  }
144
+ } else {
145
+ // xmldom environment - check documentElement
146
+ if (xmlDoc.documentElement && xmlDoc.documentElement.nodeName === 'parsererror') {
147
+ throw new Error(xmlDoc.documentElement.textContent || 'XML parsing error');
148
+ }
149
+ }
150
+
151
+ const jsonObject = xmlToJsonObject(xmlDoc);
152
+ return jsonToToonSync(jsonObject);
153
+ }
154
+
155
+ /**
156
+ * Converts XML (or mixed text with XML) to TOON format (Synchronous)
157
+ * @param {string} xmlString - XML formatted string or mixed text
158
+ * @returns {string} TOON formatted string
159
+ * @throws {Error} If XML is invalid or DOMParser is not available
160
+ */
161
+ export function xmlToToonSync(xmlString) {
162
+ if (!xmlString || typeof xmlString !== 'string') {
163
+ throw new Error('Input must be a non-empty string');
164
+ }
140
165
 
141
- const jsonObject = xmlToJsonObject(xmlDoc);
142
- return jsonToToon(jsonObject);
166
+ let convertedText = xmlString;
167
+ let iterationCount = 0;
168
+ const maxIterations = 100;
169
+
170
+ while (iterationCount < maxIterations) {
171
+ const xmlBlock = extractXmlFromString(convertedText);
172
+ if (!xmlBlock) break;
173
+
174
+ try {
175
+ const toonString = parseXmlToToonSync(xmlBlock);
176
+ const toonOutput = toonString.trim();
177
+ convertedText = convertedText.replace(xmlBlock, toonOutput);
178
+ iterationCount++;
179
+ } catch (e) {
180
+ break;
181
+ }
143
182
  }
144
183
 
145
- // Node.js environment - require xmldom
146
- try {
147
- const { DOMParser: NodeDOMParser } = await import('xmldom');
148
- const parser = new NodeDOMParser();
149
- const xmlDoc = parser.parseFromString(
150
- encodeXmlReservedChars(xmlString),
151
- 'application/xml'
152
- );
153
-
154
- const jsonObject = xmlToJsonObject(xmlDoc);
155
- return jsonToToon(jsonObject);
156
- } catch (error) {
157
- throw new Error('XML parsing requires DOMParser (browser) or xmldom package (Node.js). Install xmldom: npm install xmldom');
184
+ return convertedText;
185
+ }
186
+
187
+ /**
188
+ * Converts XML (or mixed text with XML) to TOON format (Async)
189
+ * @param {string} xmlString - XML formatted string or mixed text
190
+ * @returns {Promise<string>} TOON formatted string
191
+ */
192
+ export async function xmlToToon(xmlString) {
193
+ if (typeof DOMParser === 'undefined') {
194
+ try {
195
+ const { DOMParser: NodeDOMParser } = await import('xmldom');
196
+ global.DOMParser = NodeDOMParser;
197
+ } catch (e) {
198
+ // Ignore if import fails, xmlToToonSync will throw appropriate error
199
+ }
158
200
  }
201
+ return xmlToToonSync(xmlString);
159
202
  }
160
203
 
161
204
  /**
162
- * Converts TOON to XML format
205
+ * Converts TOON to XML format (Synchronous)
163
206
  * @param {string} toonString - TOON formatted string
164
207
  * @returns {string} XML formatted string
165
208
  * @throws {Error} If TOON is invalid
166
209
  */
167
- export function toonToXml(toonString) {
210
+ export function toonToXmlSync(toonString) {
168
211
  if (!toonString || typeof toonString !== 'string') {
169
212
  throw new Error('Input must be a non-empty string');
170
213
  }
171
214
 
172
- const jsonObject = toonToJson(toonString);
215
+ const jsonObject = toonToJsonSync(toonString);
173
216
  return jsonObjectToXml(jsonObject);
174
217
  }
218
+
219
+ /**
220
+ * Converts TOON to XML format (Async)
221
+ * @param {string} toonString - TOON formatted string
222
+ * @returns {Promise<string>} XML formatted string
223
+ */
224
+ export async function toonToXml(toonString) {
225
+ return toonToXmlSync(toonString);
226
+ }
package/src/yaml.js CHANGED
@@ -3,15 +3,16 @@
3
3
  */
4
4
 
5
5
  import yaml from 'js-yaml';
6
- import { jsonToToon, toonToJson } from './json.js';
6
+ import { jsonToToonSync, toonToJsonSync } from './json.js';
7
+
7
8
 
8
9
  /**
9
- * Converts YAML to TOON format
10
- * @param {string} yamlString - YAML formatted string
10
+ * Converts YAML (or mixed text with YAML) to TOON format (Synchronous)
11
+ * @param {string} yamlString - YAML formatted string or mixed text
11
12
  * @returns {string} TOON formatted string
12
13
  * @throws {Error} If YAML is invalid
13
14
  */
14
- export function yamlToToon(yamlString) {
15
+ export function yamlToToonSync(yamlString) {
15
16
  if (!yamlString || typeof yamlString !== 'string') {
16
17
  throw new Error('Input must be a non-empty string');
17
18
  }
@@ -22,20 +23,38 @@ export function yamlToToon(yamlString) {
22
23
  throw new Error("YAML parsing failed — cannot convert.");
23
24
  }
24
25
 
25
- return jsonToToon(jsonObject);
26
+ return jsonToToonSync(jsonObject);
27
+ }
28
+
29
+ /**
30
+ * Converts YAML (or mixed text with YAML) to TOON format (Async)
31
+ * @param {string} yamlString - YAML formatted string or mixed text
32
+ * @returns {Promise<string>} TOON formatted string
33
+ */
34
+ export async function yamlToToon(yamlString) {
35
+ return yamlToToonSync(yamlString);
26
36
  }
27
37
 
28
38
  /**
29
- * Converts TOON to YAML format
39
+ * Converts TOON to YAML format (Synchronous)
30
40
  * @param {string} toonString - TOON formatted string
31
41
  * @returns {string} YAML formatted string
32
42
  * @throws {Error} If TOON is invalid
33
43
  */
34
- export function toonToYaml(toonString) {
44
+ export function toonToYamlSync(toonString) {
35
45
  if (!toonString || typeof toonString !== 'string') {
36
46
  throw new Error('Input must be a non-empty string');
37
47
  }
38
48
 
39
- const jsonObject = toonToJson(toonString);
49
+ const jsonObject = toonToJsonSync(toonString);
40
50
  return yaml.dump(jsonObject);
41
51
  }
52
+
53
+ /**
54
+ * Converts TOON to YAML format (Async)
55
+ * @param {string} toonString - TOON formatted string
56
+ * @returns {Promise<string>} YAML formatted string
57
+ */
58
+ export async function toonToYaml(toonString) {
59
+ return toonToYamlSync(toonString);
60
+ }
@@ -5,12 +5,12 @@
5
5
 
6
6
  import { test } from 'node:test';
7
7
  import assert from 'node:assert';
8
- import { jsonToToon, toonToJson } from '../src/json.js';
9
- import { validateToonString } from '../src/validator.js';
8
+ import { jsonToToonSync, toonToJsonSync } from '../src/json.js';
9
+ import { validateToonStringSync } from '../src/validator.js';
10
10
 
11
11
  test('JSON to TOON - Simple Object', () => {
12
12
  const input = { name: "Alice", age: 30, active: true };
13
- const result = jsonToToon(input);
13
+ const result = jsonToToonSync(input);
14
14
 
15
15
  assert.ok(result.includes('name: "Alice"'));
16
16
  assert.ok(result.includes('age: 30'));
@@ -19,7 +19,7 @@ test('JSON to TOON - Simple Object', () => {
19
19
 
20
20
  test('JSON to TOON - Array of Primitives', () => {
21
21
  const input = { numbers: [1, 2, 3, 4, 5] };
22
- const result = jsonToToon(input);
22
+ const result = jsonToToonSync(input);
23
23
 
24
24
  assert.ok(result.includes('numbers[5]: 1, 2, 3, 4, 5'));
25
25
  });
@@ -31,7 +31,7 @@ test('JSON to TOON - Tabular Array', () => {
31
31
  { id: 2, name: "Bob", active: false }
32
32
  ]
33
33
  };
34
- const result = jsonToToon(input);
34
+ const result = jsonToToonSync(input);
35
35
 
36
36
  assert.ok(result.includes('users[2]{id,name,active}:'));
37
37
  assert.ok(result.includes('1,"Alice",true'));
@@ -40,7 +40,7 @@ test('JSON to TOON - Tabular Array', () => {
40
40
 
41
41
  test('TOON to JSON - Simple Object', () => {
42
42
  const input = `name: "Alice"\nage: 30\nactive: true`;
43
- const result = toonToJson(input);
43
+ const result = toonToJsonSync(input);
44
44
 
45
45
  assert.strictEqual(result.name, "Alice");
46
46
  assert.strictEqual(result.age, 30);
@@ -49,7 +49,7 @@ test('TOON to JSON - Simple Object', () => {
49
49
 
50
50
  test('TOON to JSON - Array of Primitives', () => {
51
51
  const input = `numbers[5]: 1, 2, 3, 4, 5`;
52
- const result = toonToJson(input);
52
+ const result = toonToJsonSync(input);
53
53
 
54
54
  assert.ok(Array.isArray(result.numbers));
55
55
  assert.strictEqual(result.numbers.length, 5);
@@ -58,7 +58,7 @@ test('TOON to JSON - Array of Primitives', () => {
58
58
 
59
59
  test('TOON to JSON - Tabular Array', () => {
60
60
  const input = `users[2]{id,name,active}:\n 1,"Alice",true\n 2,"Bob",false`;
61
- const result = toonToJson(input);
61
+ const result = toonToJsonSync(input);
62
62
 
63
63
  assert.ok(Array.isArray(result.users));
64
64
  assert.strictEqual(result.users.length, 2);
@@ -79,15 +79,15 @@ test('Round-trip Conversion - Object', () => {
79
79
  ]
80
80
  };
81
81
 
82
- const toon = jsonToToon(original);
83
- const result = toonToJson(toon);
82
+ const toon = jsonToToonSync(original);
83
+ const result = toonToJsonSync(toon);
84
84
 
85
85
  assert.deepStrictEqual(result, original);
86
86
  });
87
87
 
88
88
  test('Validator - Valid TOON', () => {
89
89
  const input = `name: "Alice"\nage: 30`;
90
- const result = validateToonString(input);
90
+ const result = validateToonStringSync(input);
91
91
 
92
92
  assert.strictEqual(result.isValid, true);
93
93
  assert.strictEqual(result.error, null);
@@ -95,7 +95,7 @@ test('Validator - Valid TOON', () => {
95
95
 
96
96
  test('Validator - Invalid TOON (Array Size Mismatch)', () => {
97
97
  const input = `items[3]: 1, 2`; // Declared 3, but only 2 items
98
- const result = validateToonString(input);
98
+ const result = validateToonStringSync(input);
99
99
 
100
100
  assert.strictEqual(result.isValid, false);
101
101
  assert.ok(result.error.includes('Array size mismatch'));
@@ -103,7 +103,7 @@ test('Validator - Invalid TOON (Array Size Mismatch)', () => {
103
103
 
104
104
  test('Validator - Valid Tabular Array', () => {
105
105
  const input = `users[2]{id,name}:\n 1,"Alice"\n 2,"Bob"`;
106
- const result = validateToonString(input);
106
+ const result = validateToonStringSync(input);
107
107
 
108
108
  assert.strictEqual(result.isValid, true);
109
109
  assert.strictEqual(result.error, null);
@@ -111,14 +111,14 @@ test('Validator - Valid Tabular Array', () => {
111
111
 
112
112
  test('Edge Case - Empty Object', () => {
113
113
  const input = {};
114
- const result = jsonToToon(input);
114
+ const result = jsonToToonSync(input);
115
115
 
116
116
  assert.strictEqual(result.trim(), '');
117
117
  });
118
118
 
119
119
  test('Edge Case - Null Value', () => {
120
120
  const input = { value: null };
121
- const result = jsonToToon(input);
121
+ const result = jsonToToonSync(input);
122
122
 
123
123
  assert.ok(result.includes('value: null'));
124
124
  });
@@ -132,8 +132,8 @@ test('Edge Case - Nested Objects', () => {
132
132
  }
133
133
  };
134
134
 
135
- const toon = jsonToToon(input);
136
- const result = toonToJson(toon);
135
+ const toon = jsonToToonSync(input);
136
+ const result = toonToJsonSync(toon);
137
137
 
138
138
  assert.deepStrictEqual(result, input);
139
139
  });
@@ -5,9 +5,9 @@
5
5
 
6
6
  import { test } from 'node:test';
7
7
  import assert from 'node:assert';
8
- import { yamlToToon, toonToYaml } from '../src/yaml.js';
9
- import { xmlToToon, toonToXml } from '../src/xml.js';
10
- import { csvToToon, csvToToonSync, toonToCsv } from '../src/csv.js';
8
+ import { yamlToToonSync, toonToYamlSync } from '../src/yaml.js';
9
+ import { xmlToToon, toonToXmlSync } from '../src/xml.js';
10
+ import { csvToToon, csvToToonSync, toonToCsvSync } from '../src/csv.js';
11
11
 
12
12
  // --- YAML Tests ---
13
13
 
@@ -16,14 +16,14 @@ test('YAML to TOON - Simple Object', () => {
16
16
  name: Alice
17
17
  age: 30
18
18
  `;
19
- const toon = yamlToToon(yaml);
19
+ const toon = yamlToToonSync(yaml);
20
20
  assert.ok(toon.includes('name: "Alice"'));
21
21
  assert.ok(toon.includes('age: 30'));
22
22
  });
23
23
 
24
24
  test('TOON to YAML - Simple Object', () => {
25
25
  const toon = `name: "Alice"\nage: 30`;
26
- const yaml = toonToYaml(toon);
26
+ const yaml = toonToYamlSync(toon);
27
27
  assert.ok(yaml.includes('name: Alice'));
28
28
  assert.ok(yaml.includes('age: 30'));
29
29
  });
@@ -36,7 +36,7 @@ user:
36
36
  - admin
37
37
  - editor
38
38
  `;
39
- const toon = yamlToToon(yaml);
39
+ const toon = yamlToToonSync(yaml);
40
40
  assert.ok(toon.includes('user:'));
41
41
  assert.ok(toon.includes('name: "Alice"'));
42
42
  assert.ok(toon.includes('roles[2]:'));
@@ -56,7 +56,7 @@ test('XML to TOON - Simple Element', async () => {
56
56
 
57
57
  test('TOON to XML - Simple Element', () => {
58
58
  const toon = `user:\n name: "Alice"\n age: 30`;
59
- const xml = toonToXml(toon);
59
+ const xml = toonToXmlSync(toon);
60
60
 
61
61
  assert.ok(xml.includes('<user>'));
62
62
  assert.ok(xml.includes('<name>Alice</name>'));
@@ -111,7 +111,7 @@ test('TOON to CSV - Basic', () => {
111
111
  "Alice","Admin"
112
112
  "Bob","User"
113
113
  `;
114
- const csv = toonToCsv(toon);
114
+ const csv = toonToCsvSync(toon);
115
115
 
116
116
  assert.ok(csv.includes('name,role'));
117
117
  assert.ok(csv.includes('Alice,Admin'));
@@ -124,7 +124,7 @@ Alice,100
124
124
  Bob,95`;
125
125
 
126
126
  const toon = await csvToToon(originalCsv);
127
- const finalCsv = toonToCsv(toon);
127
+ const finalCsv = toonToCsvSync(toon);
128
128
 
129
129
  // Note: PapaParse might add/remove quotes or change spacing, so exact match isn't always guaranteed
130
130
  // But content should be same