@arkadia/data 0.1.9 → 0.1.11
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 +54 -10
- package/dist/core/Decoder.d.ts +6 -1
- package/dist/core/Decoder.d.ts.map +1 -1
- package/dist/core/Decoder.js +51 -31
- package/dist/core/Decoder.js.map +1 -1
- package/dist/core/Encoder.d.ts +5 -2
- package/dist/core/Encoder.d.ts.map +1 -1
- package/dist/core/Encoder.js +114 -53
- package/dist/core/Encoder.js.map +1 -1
- package/dist/models/Meta.d.ts +2 -2
- package/dist/models/Meta.js +3 -3
- package/dist/models/Schema.js +1 -1
- package/package.json +1 -1
- package/src/core/Decoder.ts +58 -30
- package/src/core/Encoder.ts +120 -60
- package/src/models/Meta.ts +3 -3
- package/src/models/Schema.ts +1 -1
- package/tests/00.meta.test.ts +2 -2
- package/tests/00.primitive.test.ts +38 -0
- package/tests/00.schema.test.ts +2 -2
- package/tests/04.list.test.ts +25 -2
- package/tests/06.meta.test.ts +57 -251
- package/tests/07.prompt-output.test.ts +117 -0
package/src/core/Encoder.ts
CHANGED
|
@@ -12,7 +12,7 @@ class Colors {
|
|
|
12
12
|
static TYPE = '\x1b[96m'; // cyan
|
|
13
13
|
static KEY = '\x1b[93m'; // yellow
|
|
14
14
|
static SCHEMA = '\x1b[91m'; // red (for @TypeName)
|
|
15
|
-
static TAG = '\x1b[
|
|
15
|
+
static TAG = '\x1b[35m';
|
|
16
16
|
static ATTR = '\x1b[93m';
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -78,7 +78,8 @@ export class Encoder {
|
|
|
78
78
|
|
|
79
79
|
// Avoid printing internal/default type names
|
|
80
80
|
if (schema.typeName && schema.isRecord && !schema.isAny) {
|
|
81
|
-
|
|
81
|
+
const escapedName = this.escapeIdent(schema.typeName);
|
|
82
|
+
prefix = this.c(`@${escapedName}`, Colors.SCHEMA);
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
// Przygotowanie meta (ale jeszcze nie użycie, bo w liście może się zmienić)
|
|
@@ -90,7 +91,8 @@ export class Encoder {
|
|
|
90
91
|
const metaPrefix = includeMeta ? this.metaInline(schema) : '';
|
|
91
92
|
// Python: return ind + ((meta_prefix + " ") if meta_prefix else "") + self._c(...)
|
|
92
93
|
const metaStr = metaPrefix ? metaPrefix + ' ' : '';
|
|
93
|
-
|
|
94
|
+
const escapedType = this.escapeIdent(schema.typeName);
|
|
95
|
+
return ind + metaStr + this.c(escapedType, Colors.TYPE);
|
|
94
96
|
}
|
|
95
97
|
|
|
96
98
|
// --- LIST ---
|
|
@@ -156,7 +158,7 @@ export class Encoder {
|
|
|
156
158
|
}
|
|
157
159
|
|
|
158
160
|
// 3. Field Name
|
|
159
|
-
str += this.c(field.name, Colors.KEY);
|
|
161
|
+
str += this.c(this.escapeIdent(field.name), Colors.KEY);
|
|
160
162
|
|
|
161
163
|
// 4. Field Type
|
|
162
164
|
const fieldType = this.encodeSchema(field, 0, false).trim();
|
|
@@ -196,13 +198,13 @@ export class Encoder {
|
|
|
196
198
|
}
|
|
197
199
|
|
|
198
200
|
private getTypeLabel(schema: Schema): string {
|
|
199
|
-
if (schema.isPrimitive) return schema.typeName || 'any';
|
|
201
|
+
if (schema.isPrimitive) return this.escapeIdent(schema.typeName || 'any');
|
|
200
202
|
if (schema.isList) {
|
|
201
203
|
const inner = schema.element ? this.getTypeLabel(schema.element) : 'any';
|
|
202
204
|
return `[${inner}]`;
|
|
203
205
|
}
|
|
204
206
|
if (schema.isRecord && schema.typeName && schema.typeName !== 'any') {
|
|
205
|
-
return schema.typeName;
|
|
207
|
+
return this.escapeIdent(schema.typeName);
|
|
206
208
|
}
|
|
207
209
|
return 'any';
|
|
208
210
|
}
|
|
@@ -240,15 +242,20 @@ export class Encoder {
|
|
|
240
242
|
|
|
241
243
|
// 2. Modifiers
|
|
242
244
|
if ((obj as Schema).required) {
|
|
243
|
-
items.push(this.c('
|
|
245
|
+
items.push(this.c('$required', Colors.TAG));
|
|
244
246
|
}
|
|
245
247
|
|
|
246
248
|
// 3. Attributes & Tags
|
|
247
249
|
if (this.config.includeMeta) {
|
|
248
250
|
const currentAttr = obj.attr || {};
|
|
249
251
|
for (const [k, v] of Object.entries(currentAttr)) {
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
+
const escapedKey = this.escapeIdent(k);
|
|
253
|
+
if (typeof v === 'boolean' && v === true) {
|
|
254
|
+
items.push(this.c(`$${escapedKey}`, Colors.ATTR));
|
|
255
|
+
} else {
|
|
256
|
+
const valStr = this.primitiveValue(v);
|
|
257
|
+
items.push(this.c(`$${escapedKey}=`, Colors.ATTR) + valStr);
|
|
258
|
+
}
|
|
252
259
|
}
|
|
253
260
|
|
|
254
261
|
const currentTags = obj.tags || [];
|
|
@@ -265,7 +272,7 @@ export class Encoder {
|
|
|
265
272
|
|
|
266
273
|
if (wrapped) {
|
|
267
274
|
const wrappedContent =
|
|
268
|
-
this.c(
|
|
275
|
+
this.c(`//${pad}`, Colors.SCHEMA) + content + this.c(`${pad}//`, Colors.SCHEMA);
|
|
269
276
|
return this.config.compact ? wrappedContent + ' ' : ' ' + wrappedContent + ' ';
|
|
270
277
|
}
|
|
271
278
|
|
|
@@ -321,92 +328,111 @@ export class Encoder {
|
|
|
321
328
|
return this.c(`"${content}"`, Colors.STRING);
|
|
322
329
|
}
|
|
323
330
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
331
|
+
/**
|
|
332
|
+
* Wraps identifier in backticks if it contains spaces or special characters.
|
|
333
|
+
* Regex: [a-zA-Z_][a-zA-Z0-9_]*
|
|
334
|
+
*/
|
|
335
|
+
private escapeIdent(name: string): string {
|
|
336
|
+
if (!name) return '';
|
|
327
337
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
338
|
+
// Standard identifier pattern
|
|
339
|
+
const pattern = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
340
|
+
|
|
341
|
+
if (pattern.test(name)) {
|
|
342
|
+
return name;
|
|
333
343
|
}
|
|
334
|
-
return header;
|
|
335
|
-
}
|
|
336
344
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
if (sep === '\n') return items.join(sep);
|
|
340
|
-
return items.join(`${sep} `);
|
|
345
|
+
// If it doesn't match, wrap it in backticks
|
|
346
|
+
return `\`${name}\``;
|
|
341
347
|
}
|
|
342
348
|
|
|
349
|
+
// -------------------------------------------------------------
|
|
350
|
+
// LIST
|
|
351
|
+
// -------------------------------------------------------------
|
|
343
352
|
private encodeList(node: Node, indent: number, includeSchema: boolean = false): string {
|
|
344
353
|
const ind = ' '.repeat(indent);
|
|
345
354
|
const childIndent = indent + this.config.indent;
|
|
355
|
+
const isPrompt = this.config.promptOutput;
|
|
346
356
|
|
|
357
|
+
if (this.config.includeArraySize) {
|
|
358
|
+
node.attr['size'] = node.elements.length;
|
|
359
|
+
}
|
|
347
360
|
const innerMeta = this.metaWrapped(node);
|
|
348
361
|
|
|
349
|
-
// 1. Generate Header Schema (
|
|
362
|
+
// 1. Generate Header Schema (Standard only)
|
|
350
363
|
let schemaHeader = '';
|
|
351
|
-
if (includeSchema && node.schema && node.schema.element) {
|
|
364
|
+
if (!isPrompt && includeSchema && node.schema && node.schema.element) {
|
|
352
365
|
schemaHeader = this.encodeSchema(node.schema.element, 0).trim();
|
|
353
|
-
|
|
354
|
-
if (schemaHeader) {
|
|
355
|
-
schemaHeader = schemaHeader + ' ';
|
|
366
|
+
if (schemaHeader) schemaHeader += ' ';
|
|
356
367
|
}
|
|
357
368
|
|
|
358
369
|
const expectedChild = node.schema ? node.schema.element : null;
|
|
359
370
|
|
|
371
|
+
// --- PROMPT MODE (Full Structural Expansion) ---
|
|
372
|
+
if (isPrompt) {
|
|
373
|
+
let res = ind + '[\n';
|
|
374
|
+
if (innerMeta) {
|
|
375
|
+
res += ' '.repeat(childIndent) + innerMeta.trim() + '\n';
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (node.schema && node.schema.element) {
|
|
379
|
+
// Force recursion into the element's structure using a Dummy Node
|
|
380
|
+
const dummy = new Node(node.schema.element, { value: null });
|
|
381
|
+
|
|
382
|
+
// We trim() the blueprint because we manually handle child indentation
|
|
383
|
+
const blueprint = this.encode(dummy, childIndent, false).trim();
|
|
384
|
+
|
|
385
|
+
res += ' '.repeat(childIndent) + blueprint + ',\n';
|
|
386
|
+
res += ' '.repeat(childIndent) + '... /* repeat pattern for additional items */\n';
|
|
387
|
+
} else {
|
|
388
|
+
res += ' '.repeat(childIndent) + '/* any content */\n';
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
res += ind + ']';
|
|
392
|
+
return res;
|
|
393
|
+
}
|
|
394
|
+
|
|
360
395
|
// --- COMPACT MODE ---
|
|
361
396
|
if (this.config.compact) {
|
|
362
397
|
const items: string[] = [];
|
|
363
|
-
|
|
364
398
|
for (const el of node.elements) {
|
|
365
|
-
// IMPORTANT: We disable schema inclusion for elements to avoid duplication <...>
|
|
366
|
-
// unless types mismatch drastically.
|
|
367
399
|
let val = this.encode(el, 0, false).trim();
|
|
368
|
-
|
|
369
|
-
// Check compatibility & Inject override if needed
|
|
370
400
|
if (!this.schemasAreCompatible(el.schema, expectedChild)) {
|
|
371
401
|
const label = el.schema ? this.getTypeLabel(el.schema) : 'any';
|
|
372
402
|
const tag = this.c(`<${label}>`, Colors.SCHEMA);
|
|
373
403
|
val = `${tag} ${val}`;
|
|
374
404
|
}
|
|
375
|
-
|
|
376
405
|
items.push(val);
|
|
377
406
|
}
|
|
378
|
-
|
|
379
407
|
return ind + '[' + innerMeta + schemaHeader + items.join(',') + ']';
|
|
380
408
|
}
|
|
381
409
|
|
|
382
410
|
// --- PRETTY MODE ---
|
|
383
|
-
|
|
384
|
-
const out: string[] = [ind + header];
|
|
385
|
-
|
|
411
|
+
let res = ind + '[\n';
|
|
386
412
|
if (innerMeta) {
|
|
387
|
-
|
|
413
|
+
res += ' '.repeat(childIndent) + innerMeta.trim() + '\n';
|
|
388
414
|
}
|
|
389
|
-
|
|
390
415
|
if (schemaHeader) {
|
|
391
|
-
|
|
416
|
+
res += ' '.repeat(childIndent) + schemaHeader.trim() + '\n';
|
|
392
417
|
}
|
|
393
418
|
|
|
419
|
+
const elementLines: string[] = [];
|
|
394
420
|
for (const el of node.elements) {
|
|
395
|
-
|
|
396
|
-
let val = this.encode(el, childIndent - this.config.startIndent, false).trim();
|
|
397
|
-
|
|
398
|
-
// Check compatibility & Inject override if needed
|
|
421
|
+
let val = this.encode(el, 0, false).trim();
|
|
399
422
|
if (!this.schemasAreCompatible(el.schema, expectedChild)) {
|
|
400
423
|
const label = el.schema ? this.getTypeLabel(el.schema) : 'any';
|
|
401
424
|
const tag = this.c(`<${label}>`, Colors.SCHEMA);
|
|
402
425
|
val = `${tag} ${val}`;
|
|
403
426
|
}
|
|
427
|
+
elementLines.push(' '.repeat(childIndent) + val);
|
|
428
|
+
}
|
|
404
429
|
|
|
405
|
-
|
|
430
|
+
if (elementLines.length > 0) {
|
|
431
|
+
res += elementLines.join(',\n') + '\n';
|
|
406
432
|
}
|
|
407
433
|
|
|
408
|
-
|
|
409
|
-
return
|
|
434
|
+
res += ind + ']';
|
|
435
|
+
return res;
|
|
410
436
|
}
|
|
411
437
|
|
|
412
438
|
// -------------------------------------------------------------
|
|
@@ -414,23 +440,57 @@ export class Encoder {
|
|
|
414
440
|
// -------------------------------------------------------------
|
|
415
441
|
private encodeRecord(node: Node, indent: number): string {
|
|
416
442
|
const innerMeta = this.metaWrapped(node);
|
|
417
|
-
|
|
418
443
|
const parts: string[] = [];
|
|
419
|
-
|
|
444
|
+
const isPrompt = this.config.promptOutput;
|
|
445
|
+
const baseInd = ' '.repeat(indent);
|
|
446
|
+
const childInd = ' '.repeat(indent + this.config.indent);
|
|
447
|
+
|
|
448
|
+
if (node.schema && node.schema.fields && node.schema.fields.length > 0) {
|
|
420
449
|
for (const fieldDef of node.schema.fields) {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
450
|
+
if (isPrompt) {
|
|
451
|
+
// --- PROMPT MODE: Type Label or Structural Expansion ---
|
|
452
|
+
const fieldName = this.escapeIdent(fieldDef.name);
|
|
453
|
+
let fieldValStructure: string;
|
|
454
|
+
|
|
455
|
+
if (fieldDef.isPrimitive) {
|
|
456
|
+
// For primitives, use the type name (e.g., "number")
|
|
457
|
+
fieldValStructure = this.c(this.getTypeLabel(fieldDef), Colors.TYPE);
|
|
458
|
+
} else {
|
|
459
|
+
// For structures (Records/Lists), recurse to get { } or [ ]
|
|
460
|
+
const dummyField = new Node(fieldDef, { value: null });
|
|
461
|
+
fieldValStructure = this.encode(dummyField, indent + this.config.indent, false).trim();
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
let line = `${this.c(fieldName, Colors.KEY)}: ${fieldValStructure}`;
|
|
465
|
+
|
|
466
|
+
if (fieldDef.comments && fieldDef.comments.length > 0) {
|
|
467
|
+
const comment = fieldDef.comments[0].trim();
|
|
468
|
+
line += ` ${this.c(`/* ${comment} */`, Colors.NULL)}`;
|
|
469
|
+
}
|
|
470
|
+
parts.push(line);
|
|
426
471
|
} else {
|
|
427
|
-
|
|
472
|
+
// --- STANDARD MODE (Data values) ---
|
|
473
|
+
const fieldNode = node.fields[fieldDef.name];
|
|
474
|
+
if (fieldNode) {
|
|
475
|
+
let val = this.encode(fieldNode, 0, false).trim();
|
|
476
|
+
val = this.applyTypeTag(val, fieldNode.schema, fieldDef);
|
|
477
|
+
parts.push(val);
|
|
478
|
+
} else {
|
|
479
|
+
parts.push(this.c('null', Colors.NULL));
|
|
480
|
+
}
|
|
428
481
|
}
|
|
429
482
|
}
|
|
430
|
-
const sep = this.config.compact ? ',' : ', ';
|
|
431
|
-
return '(' + innerMeta + parts.join(sep) + ')';
|
|
432
483
|
} else {
|
|
433
|
-
|
|
484
|
+
parts.push(this.c('null', Colors.NULL));
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
if (isPrompt) {
|
|
488
|
+
const body = parts.join(',\n' + childInd);
|
|
489
|
+
const metaStr = innerMeta ? childInd + innerMeta.trim() + '\n' : '';
|
|
490
|
+
return '{\n' + metaStr + childInd + body + '\n' + baseInd + '}';
|
|
434
491
|
}
|
|
492
|
+
|
|
493
|
+
const sep = this.config.compact ? ',' : ', ';
|
|
494
|
+
return '(' + innerMeta + parts.join(sep) + ')';
|
|
435
495
|
}
|
|
436
496
|
}
|
package/src/models/Meta.ts
CHANGED
|
@@ -53,7 +53,7 @@ export class Meta {
|
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
55
|
* A temporary container (DTO) holding parsed metadata from a / ... / block.
|
|
56
|
-
* It contains BOTH Schema constraints (
|
|
56
|
+
* It contains BOTH Schema constraints ($required) and Node attributes ($key=val).
|
|
57
57
|
*/
|
|
58
58
|
export class MetaInfo extends Meta {
|
|
59
59
|
required: boolean;
|
|
@@ -91,14 +91,14 @@ export class MetaInfo extends Meta {
|
|
|
91
91
|
|
|
92
92
|
/**
|
|
93
93
|
* Debug representation mimicking the actual ADF format style.
|
|
94
|
-
* Example: <MetaInfo
|
|
94
|
+
* Example: <MetaInfo $required #tag $key=val >
|
|
95
95
|
*/
|
|
96
96
|
toString(): string {
|
|
97
97
|
const parts: string[] = [];
|
|
98
98
|
|
|
99
99
|
// 1. Flags
|
|
100
100
|
if (this.required) {
|
|
101
|
-
parts.push('
|
|
101
|
+
parts.push('$required');
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
// 2. Tags
|
package/src/models/Schema.ts
CHANGED
|
@@ -192,7 +192,7 @@ export class Schema extends Meta {
|
|
|
192
192
|
// 3. Details
|
|
193
193
|
const details: string[] = [];
|
|
194
194
|
|
|
195
|
-
if (this.required) details.push('
|
|
195
|
+
if (this.required) details.push('$required');
|
|
196
196
|
|
|
197
197
|
const attrKeys = Object.keys(this.attr);
|
|
198
198
|
if (attrKeys.length > 0)
|
package/tests/00.meta.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe,
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
2
|
import { MetaInfo } from '../src/index';
|
|
3
3
|
|
|
4
4
|
describe('AK Data Meta', () => {
|
|
@@ -9,7 +9,7 @@ describe('AK Data Meta', () => {
|
|
|
9
9
|
tags: ['tag1', 'tag2'],
|
|
10
10
|
required: true,
|
|
11
11
|
});
|
|
12
|
-
const expected = '<MetaInfo
|
|
12
|
+
const expected = '<MetaInfo $required #tag1 #tag2 $foo="bar" /* This is a comme.. */>';
|
|
13
13
|
// const expectedJSON
|
|
14
14
|
const expected_val = {
|
|
15
15
|
comments: ['This is a comment'],
|
|
@@ -131,4 +131,42 @@ describe('String Escaping', () => {
|
|
|
131
131
|
// Encoder must escape the backslash: "C:\\Program Files"
|
|
132
132
|
assertRoundtrip(node, '<path:string>("C:\\\\Program Files")', false);
|
|
133
133
|
});
|
|
134
|
+
|
|
135
|
+
it('should handle deeply nested escaped names and metadata keys', () => {
|
|
136
|
+
/**
|
|
137
|
+
* Validates that backticks work in nested schemas and metadata keys.
|
|
138
|
+
* This tests:
|
|
139
|
+
* 1. Schema name with spaces and symbols: @`User ID+`
|
|
140
|
+
* 2. Metadata keys with symbols: $`attributes*`
|
|
141
|
+
* 3. Field names with spaces and symbols: `ID of the user`
|
|
142
|
+
* 4. Standard identifiers: is_user (no backticks)
|
|
143
|
+
*/
|
|
144
|
+
const text = `
|
|
145
|
+
/* Use backticks for Schema names and Attributes with spaces */
|
|
146
|
+
@\`User ID+\` <
|
|
147
|
+
// $\`attributes*\`="32" //
|
|
148
|
+
\`Is User?\`: bool,
|
|
149
|
+
$\`Attribute Special*\` \`ID of the user\`: string,
|
|
150
|
+
\`is - special?\`: bool,
|
|
151
|
+
is_user: bool
|
|
152
|
+
>
|
|
153
|
+
|
|
154
|
+
{
|
|
155
|
+
// $\`numbers of ids\`=4 //
|
|
156
|
+
$\`attr*\`=52 \`Is User?\`: true,
|
|
157
|
+
\`ID of the user\`: "ID",
|
|
158
|
+
\`is - special?\`: false,
|
|
159
|
+
is_user: false
|
|
160
|
+
}`;
|
|
161
|
+
|
|
162
|
+
// The expected output follows the AK Data rules:
|
|
163
|
+
// - Metadata wrapped in // ... //
|
|
164
|
+
// - Record data in ( ... )
|
|
165
|
+
// - Booleans and Numbers as literals
|
|
166
|
+
// - Identifiers escaped only if necessary
|
|
167
|
+
const expected =
|
|
168
|
+
`@\`User ID+\`<///*Use backticks for Schema names and Attributes with spaces*/ $\`attributes*\`="32"// \`Is User?\`:bool,$\`Attribute Special*\` \`ID of the user\`:string,\`is - special?\`:bool,is_user:bool>(//$\`numbers of ids\`=4// $\`attr*\`=52 true,"ID",false,false)`.trim();
|
|
169
|
+
|
|
170
|
+
assertRoundtrip(text, expected, false);
|
|
171
|
+
});
|
|
134
172
|
});
|
package/tests/00.schema.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe,
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
2
|
import { Schema, SchemaKind } from '../src/index';
|
|
3
3
|
|
|
4
4
|
describe('AI Schema test', () => {
|
|
@@ -11,7 +11,7 @@ describe('AI Schema test', () => {
|
|
|
11
11
|
required: true,
|
|
12
12
|
});
|
|
13
13
|
const expected =
|
|
14
|
-
'<Schema(DICT) name="TestSchema"
|
|
14
|
+
'<Schema(DICT) name="TestSchema" $required attr=["foo"] tags=[tag1, tag2] comments=1>';
|
|
15
15
|
const expected_val = {
|
|
16
16
|
comments: ['This is a comment'],
|
|
17
17
|
attr: {
|
package/tests/04.list.test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { describe,
|
|
2
|
-
import {
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { decode, encode, parse, SchemaKind } from '../src/index';
|
|
3
3
|
import { assertRoundtrip } from './utils';
|
|
4
4
|
|
|
5
5
|
describe('AK List Handling', () => {
|
|
@@ -221,4 +221,27 @@ describe('AK List Handling', () => {
|
|
|
221
221
|
const expected = '<[[number]]>[[2,3,4],[5,6,7]]';
|
|
222
222
|
assertRoundtrip(node, expected, false);
|
|
223
223
|
});
|
|
224
|
+
|
|
225
|
+
it('should no compact with include_array_size', () => {
|
|
226
|
+
const akdText = `<[number]>[1,2,<string> "3"]`;
|
|
227
|
+
|
|
228
|
+
const result = decode(akdText, { debug: false });
|
|
229
|
+
const node = result.node;
|
|
230
|
+
expect(result.errors).toHaveLength(0);
|
|
231
|
+
|
|
232
|
+
// 'int' normalizes to 'number' in the TS implementation
|
|
233
|
+
const expected = `<[number]>
|
|
234
|
+
[
|
|
235
|
+
// $size=3 //
|
|
236
|
+
1,
|
|
237
|
+
2,
|
|
238
|
+
<string> "3"
|
|
239
|
+
]`;
|
|
240
|
+
const output = encode(node, {
|
|
241
|
+
includeArraySize: true,
|
|
242
|
+
compact: false,
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
expect(output).toBe(expected);
|
|
246
|
+
});
|
|
224
247
|
});
|