@cbortech/cbor 0.26.8 → 0.27.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.
Files changed (54) hide show
  1. package/README.ja.md +120 -28
  2. package/README.md +121 -29
  3. package/dist/ast/CborAppSeqResult.d.ts +22 -0
  4. package/dist/ast/CborByteString.d.ts +16 -0
  5. package/dist/ast/CborEmbeddedCBOR.d.ts +1 -1
  6. package/dist/ast/CborFloat.d.ts +1 -1
  7. package/dist/ast/CborIndefiniteByteString.d.ts +24 -0
  8. package/dist/ast/CborIndefiniteTextString.d.ts +16 -0
  9. package/dist/ast/CborItem.d.ts +44 -4
  10. package/dist/ast/CborTag.d.ts +27 -0
  11. package/dist/ast/CborTextString.d.ts +2 -1
  12. package/dist/ast/CborUnresolvedAppExt.d.ts +2 -2
  13. package/dist/ast/index.cjs +1 -1
  14. package/dist/ast/index.js +2 -2
  15. package/dist/cddl/index.cjs +1 -1
  16. package/dist/cddl/index.js +1 -1
  17. package/dist/cdn/index.cjs +2 -2
  18. package/dist/cdn/index.cjs.map +1 -1
  19. package/dist/cdn/index.js +18 -18
  20. package/dist/cdn/index.js.map +1 -1
  21. package/dist/cdn/serialize-utils.d.ts +207 -8
  22. package/dist/cdn/tokenizer.d.ts +12 -11
  23. package/dist/extensions/builtins.d.ts +5 -5
  24. package/dist/extensions/cri.d.ts +2 -2
  25. package/dist/extensions/ip.d.ts +1 -1
  26. package/dist/extensions/types.d.ts +4 -4
  27. package/dist/index.cjs +3 -3
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.js +158 -158
  30. package/dist/index.js.map +1 -1
  31. package/dist/mapEntries-C1f7G0AM.cjs +13 -0
  32. package/dist/mapEntries-C1f7G0AM.cjs.map +1 -0
  33. package/dist/{mapEntries-Ci_dppP6.js → mapEntries-CvLdiN0h.js} +1362 -1219
  34. package/dist/mapEntries-CvLdiN0h.js.map +1 -0
  35. package/dist/{schema-y8G5mDIS.js → schema-CNfrVRYp.js} +294 -294
  36. package/dist/{schema-y8G5mDIS.js.map → schema-CNfrVRYp.js.map} +1 -1
  37. package/dist/schema-iXpYtKQl.cjs +63 -0
  38. package/dist/{schema-DgnkH0P6.cjs.map → schema-iXpYtKQl.cjs.map} +1 -1
  39. package/dist/{tokenizer-N-vAvRdj.js → serialize-utils-BuIZPaUc.js} +626 -358
  40. package/dist/serialize-utils-BuIZPaUc.js.map +1 -0
  41. package/dist/serialize-utils-CjTqQivB.cjs +37 -0
  42. package/dist/serialize-utils-CjTqQivB.cjs.map +1 -0
  43. package/dist/types.d.ts +235 -58
  44. package/dist/utils/base64.d.ts +1 -1
  45. package/dist/utils/hexfloat.d.ts +1 -1
  46. package/dist/utils/strip-comments.d.ts +1 -1
  47. package/package.json +8 -6
  48. package/dist/mapEntries-BJzyBUH5.cjs +0 -13
  49. package/dist/mapEntries-BJzyBUH5.cjs.map +0 -1
  50. package/dist/mapEntries-Ci_dppP6.js.map +0 -1
  51. package/dist/schema-DgnkH0P6.cjs +0 -63
  52. package/dist/tokenizer-BD08xbyd.cjs +0 -36
  53. package/dist/tokenizer-BD08xbyd.cjs.map +0 -1
  54. package/dist/tokenizer-N-vAvRdj.js.map +0 -1
package/dist/types.d.ts CHANGED
@@ -43,7 +43,7 @@ export interface ToJSOptions {
43
43
  * - `'object'`: always `Record<string, unknown>` — non-string keys are
44
44
  * converted via `String()`. Duplicate keys are overwritten (last wins).
45
45
  * - `'entries'`: always `MapEntries` (a typed `Array` subclass) — preserves all
46
- * entries including duplicate keys (§2.6.3 of draft-ietf-cbor-edn-literals-25).
46
+ * entries including duplicate keys (§2.4.2 of draft-ietf-cbor-edn-literals-27).
47
47
  * `fromJS()` recognises `MapEntries` instances and converts them back to `CborMap`.
48
48
  * @default 'auto'
49
49
  */
@@ -165,7 +165,7 @@ export interface FromCBOROptions {
165
165
  */
166
166
  extensions?: CborExtension[];
167
167
  /**
168
- * Override the default set of bundled application-oriented extensions
168
+ * Override the default set of bundled app-extensions
169
169
  * (`dt`, `ip`, `cri`, `t1`, `b1`, `ilbs`, `ilts`, `float`).
170
170
  *
171
171
  * - omitted (default): use the standard bundled set.
@@ -173,13 +173,13 @@ export interface FromCBOROptions {
173
173
  * - `false`: disable all of them.
174
174
  *
175
175
  * `bignum` (tags 2/3) and embedded-CBOR (tag 24) support are core RFC 8949
176
- * representation features, not application-oriented extensions, and are
177
- * always active regardless of this option.
176
+ * representation features, not app-extensions, and are always active
177
+ * regardless of this option.
178
178
  *
179
- * `dt`, `ip`, `t1`, and `b1` are mandatory-to-implement per §2.1 of
180
- * draft-ietf-cbor-edn-literals-26; disabling them produces a decoder that
179
+ * `dt`, `ip`, `t1`, and `b1` are mandatory-to-implement per §3 of
180
+ * draft-ietf-cbor-edn-literals-27; disabling them produces a decoder that
181
181
  * no longer conforms to that recommendation. This is intended for
182
- * allowlisting scenarios (see §7 Security considerations of the same
182
+ * allowlisting scenarios (see §8 Security considerations of the same
183
183
  * draft) where an application wants explicit control over which
184
184
  * extensions it accepts.
185
185
  */
@@ -254,7 +254,7 @@ export interface FromHexDumpOptions {
254
254
  */
255
255
  extensions?: CborExtension[];
256
256
  /**
257
- * Override the default set of bundled application-oriented extensions.
257
+ * Override the default set of bundled app-extensions.
258
258
  * Mirrors `FromCBOROptions.builtinExtensions`.
259
259
  */
260
260
  builtinExtensions?: CborExtension[] | false;
@@ -332,7 +332,7 @@ export interface FromCDNOptions {
332
332
  */
333
333
  extensions?: CborExtension[];
334
334
  /**
335
- * Override the default set of bundled application-oriented extensions
335
+ * Override the default set of bundled app-extensions
336
336
  * (`dt`, `ip`, `cri`, `t1`, `b1`, `ilbs`, `ilts`, `float`).
337
337
  *
338
338
  * - omitted (default): use the standard bundled set.
@@ -340,10 +340,10 @@ export interface FromCDNOptions {
340
340
  * - `false`: disable all of them; app-string literals using their
341
341
  * prefixes then fall through to `unresolvedExtension` handling.
342
342
  *
343
- * `dt`, `ip`, `t1`, and `b1` are mandatory-to-implement per §2.1 of
344
- * draft-ietf-cbor-edn-literals-26; disabling them produces a parser that
343
+ * `dt`, `ip`, `t1`, and `b1` are mandatory-to-implement per §3 of
344
+ * draft-ietf-cbor-edn-literals-27; disabling them produces a parser that
345
345
  * no longer conforms to that recommendation. This is intended for
346
- * allowlisting scenarios (see §7 Security considerations of the same
346
+ * allowlisting scenarios (see §8 Security considerations of the same
347
347
  * draft) where an application wants explicit control over which
348
348
  * extensions it accepts from untrusted CDN input.
349
349
  *
@@ -354,8 +354,8 @@ export interface FromCDNOptions {
354
354
  */
355
355
  builtinExtensions?: CborExtension[] | false;
356
356
  /**
357
- * How to handle unrecognised application-extension identifiers
358
- * (§4.1 of draft-ietf-cbor-edn-literals-25).
357
+ * How to handle unrecognised app-extension identifiers
358
+ * (§5.1 of draft-ietf-cbor-edn-literals-27).
359
359
  *
360
360
  * - `'cpa999'`: wrap the literal in a `CPA999` tag
361
361
  * (`CborUnresolvedAppExt`) instead of failing. The resulting node
@@ -381,14 +381,28 @@ export interface FromCDNOptions {
381
381
  *
382
382
  * Comments are metadata only: they are ignored by CBOR binary encoding and
383
383
  * JavaScript conversion. Use together with `ToCDNOptions.preserveComments`
384
- * to include them when formatting back to CDN.
384
+ * (or `comments`) to include them when formatting back to CDN.
385
385
  *
386
- * The string values `'c-style'` and `'cdn-style'` are treated as `true`
387
- * for parsing purposes; they become meaningful when passed to `toCDN()`.
386
+ * Passing `'c-style'`/`'cdn-style'` directly is a deprecated shorthand for
387
+ * `true` plus the equivalent `comments` still accepted, but prefer
388
+ * `comments` for the output style going forward.
388
389
  *
389
390
  * @default false
390
391
  */
391
392
  preserveComments?: boolean | 'c-style' | 'cdn-style';
393
+ /**
394
+ * Companion to `preserveComments` for a single options object shared with
395
+ * `toCDN()` (as `CBOR.format()` does internally) — see
396
+ * `ToCDNOptions.comments` for what each value means there. On the
397
+ * parse side, only *whether* a style other than `'strip'` was requested
398
+ * matters: comments are captured when `preserveComments` is `true`, or
399
+ * when `comments` is set to anything other than `'strip'`. Left
400
+ * unset alongside an unset/`false` `preserveComments`, nothing is
401
+ * captured.
402
+ *
403
+ * @default undefined
404
+ */
405
+ comments?: 'strip' | 'c-style' | 'cdn-style';
392
406
  /**
393
407
  * Shorthand for `ToCDNOptions.preserveAll`, so a single option enables
394
408
  * round-tripping through both `fromCDN()` and `toCDN()` (as
@@ -457,10 +471,10 @@ export interface FromJSOptions {
457
471
  */
458
472
  extensions?: CborExtension[];
459
473
  /**
460
- * Override the default set of bundled application-oriented extensions.
474
+ * Override the default set of bundled app-extensions.
461
475
  * Mirrors `FromCDNOptions.builtinExtensions`. Only affects builtins that
462
- * implement `fromJS()` / `parseTag()` (none of the bundled application
463
- * extensions implement `fromJS()` by default — use `dt_as_Date` via
476
+ * implement `fromJS()` / `parseTag()` (none of the bundled app-extensions
477
+ * implement `fromJS()` by default — use `dt_as_Date` via
464
478
  * `extensions` for `Date` round-tripping).
465
479
  */
466
480
  builtinExtensions?: CborExtension[] | false;
@@ -530,7 +544,7 @@ export interface ToCDNOptions {
530
544
  * Master switch that turns on every `preserve*` option below at once,
531
545
  * except the deprecated `preserveTextString` — `preserveComments`,
532
546
  * `preserveByteString`, `preserveRawString`, `preserveConcatenation`,
533
- * `preserveNumberFormat`, `preserveAppSequence`, and
547
+ * `preserveNumberFormat`, `preserveAppPrefix`, and
534
548
  * `preserveBlankLines` — for reformatting CDN text (e.g. on save in an
535
549
  * editor) with minimal changes: only whitespace/indentation, plus
536
550
  * anything an explicitly-set individual option overrides.
@@ -538,7 +552,11 @@ export interface ToCDNOptions {
538
552
  * An option explicitly set to a value (including `false`) is left as-is;
539
553
  * `preserveAll` only fills in the ones left `undefined`. So
540
554
  * `{ preserveAll: true, preserveNumberFormat: false }` preserves
541
- * everything except number literal spelling.
555
+ * everything except number literal spelling. `preserveComments` is filled
556
+ * in with `true` only when `comments` is *also* left unset — an
557
+ * explicit `comments` with no `preserveComments` still normalizes
558
+ * comments to that style under `preserveAll`, instead of being overridden
559
+ * by the verbatim fill-in.
542
560
  *
543
561
  * When parsing via `CBOR.fromCDN()` separately from `toCDN()` (rather
544
562
  * than through `CBOR.format()`, which passes the same options to both),
@@ -551,24 +569,45 @@ export interface ToCDNOptions {
551
569
  */
552
570
  preserveAll?: boolean;
553
571
  /**
554
- * Emit comments previously captured by `FromCDNOptions.preserveComments`.
572
+ * Emit comments previously captured by `FromCDNOptions.preserveComments`,
573
+ * with their original markers kept as-is (no normalization) — takes
574
+ * precedence over `comments` when `true`.
575
+ *
576
+ * - `true`: emit comments verbatim, with whichever marker each one was
577
+ * originally written with.
578
+ * - `false` / omitted: defer to `comments` (see below) — `'strip'` (the
579
+ * default when that's also unset) or unset means no comments are
580
+ * emitted.
581
+ * - `'c-style'` / `'cdn-style'`: deprecated shorthand for `false` plus the
582
+ * equivalent `comments`; still accepted, but prefer setting
583
+ * `comments` directly.
555
584
  *
556
- * - `true`: emit comments with their original markers.
585
+ * Only effective when `indent` enables pretty-printing: single-line
586
+ * output strips all comments regardless, since line comments (`#`, `//`)
587
+ * can only be terminated by a newline.
588
+ *
589
+ * @default false
590
+ */
591
+ preserveComments?: boolean | 'c-style' | 'cdn-style';
592
+ /**
593
+ * Style to normalize comment markers to when emitting comments previously
594
+ * captured by `FromCDNOptions.preserveComments` — only consulted when
595
+ * `preserveComments` is not `true` (see there).
596
+ *
597
+ * - `'strip'` / omitted: don't emit comments at all.
557
598
  * - `'c-style'`: emit comments, normalising line comments to `//` and block
558
599
  * comments to `/* … *\/`.
559
600
  * - `'cdn-style'`: emit comments, normalising line comments to `#` and block
560
601
  * comments to `/ … /`. When a `/* … *\/` comment's content contains `/`
561
602
  * (which cannot be represented inside `/ … /`), the `/* … *\/` form is
562
603
  * kept as-is.
563
- * - `false` / omitted: strip all comments from the output.
564
604
  *
565
- * Only effective when `indent` enables pretty-printing: single-line
566
- * output strips all comments, since line comments (`#`, `//`) can only
567
- * be terminated by a newline.
605
+ * Only effective when `indent` enables pretty-printing; see
606
+ * `preserveComments`.
568
607
  *
569
- * @default false
608
+ * @default 'strip'
570
609
  */
571
- preserveComments?: boolean | 'c-style' | 'cdn-style';
610
+ comments?: 'strip' | 'c-style' | 'cdn-style';
572
611
  /**
573
612
  * Re-emit a blank line above an array/map entry (or indefinite-length
574
613
  * string chunk) that had one before it anywhere in the parsed CDN source,
@@ -594,7 +633,7 @@ export interface ToCDNOptions {
594
633
  * This preserves the spelling and interior layout of non-concatenated
595
634
  * `h'...'`, `b64'...'`, `b32'...'`, `h32'...'`, raw-backtick byte strings,
596
635
  * and single-quoted byte strings — including a `h'xx...yy'`-family elided
597
- * literal (§4.2), whose spelling is kept independently of
636
+ * literal (§5.2), whose spelling is kept independently of
598
637
  * `preserveConcatenation` when it has no `+` of its own (see that
599
638
  * option). Byte strings produced by `+` concatenation are normalised as
600
639
  * usual; combine with `preserveConcatenation` to keep both the part
@@ -710,16 +749,29 @@ export interface ToCDNOptions {
710
749
  */
711
750
  sqstr?: 'printable-string' | 'string' | 'none';
712
751
  /**
713
- * Whether to use application-string / app-sequence notation for built-in
714
- * extensions (e.g. `dt'...'`, `DT'...'`, `ip'...'`, `IP'...'`).
752
+ * Whether to use app-prefix notation app-string (`dt'...'`, `` dt`...` ``)
753
+ * or app-sequence (`dt<<...>>`) for built-in extensions.
715
754
  * - `true`: emit extension notation (`DT'2023-01-01T12:00:00Z'`)
716
755
  * - `false`: emit raw CBOR notation (`1(-14159024)`, `52(h'c000022a')`)
756
+ *
757
+ * Named after `app-prefix` (§6.1 of draft-ietf-cbor-edn-literals-27), the
758
+ * identifier both notations are built from — not just the app-string form,
759
+ * despite the old `appStrings` name (`false` also falls back to raw tag
760
+ * notation for a preserved app-sequence spelling; see `preserveAppPrefix`).
761
+ *
717
762
  * @default true
718
763
  */
764
+ appPrefix?: boolean;
765
+ /**
766
+ * @deprecated Renamed to `appPrefix` — the old name only described the
767
+ * app-string form even though this option also gates app-sequence
768
+ * (`<<...>>`) notation. Still honoured when `appPrefix` is left unset,
769
+ * but `appPrefix` wins if both are set.
770
+ */
719
771
  appStrings?: boolean;
720
772
  /**
721
- * For built-in extensions that support application-string notation
722
- * (`prefix'...'` or `` prefix`...` ``), application-sequence notation
773
+ * For built-in extensions that support app-string notation
774
+ * (`prefix'...'` or `` prefix`...` ``), app-sequence notation
723
775
  * (`prefix<<...>>`), and/or a raw tag literal (`N(...)`), re-emit a value
724
776
  * using its exact original spelling instead of normalizing it to the
725
777
  * regenerated `prefix'...'` form.
@@ -729,10 +781,10 @@ export interface ToCDNOptions {
729
781
  * `` DT`1969-07-21T02:56:16Z` ``, `DT<<'1969-07-21T02:56:16Z'>>`, and even
730
782
  * the raw tag form `1(1749772800)` all become
731
783
  * `DT'2025-06-13T00:00:00Z'`-style `prefix'...'` notation, even though all
732
- * of these denote the same value. `preserveAppSequence` keeps the
784
+ * of these denote the same value. `preserveAppPrefix` keeps the
733
785
  * original spelling instead — whichever quoting (`'...'` vs `` `...` ``),
734
786
  * bracketing (`<<...>>`), or raw tag form was used. Has no effect when
735
- * `appStrings` is `false` (raw tag notation is used either way regardless
787
+ * `appPrefix` is `false` (raw tag notation is used either way regardless
736
788
  * of the original spelling), or on values not parsed from one of these
737
789
  * forms.
738
790
  *
@@ -740,13 +792,34 @@ export interface ToCDNOptions {
740
792
  * lines falls back to normal (regenerated) notation; single-line
741
793
  * spellings are kept.
742
794
  *
743
- * An explicit `preserveComments` setting is still applied to comments
744
- * inside a preserved application-sequence spelling: marker styles are
745
- * normalised without changing the notation family, and `false` removes
746
- * the comments while retaining the surrounding source spelling.
795
+ * An explicit `preserveComments`/`comments` setting is still applied
796
+ * to comments inside a preserved app-sequence spelling: marker styles are
797
+ * normalised without changing the notation family, and stripping comments
798
+ * (`preserveComments: false` with `comments` unset or `'strip'`)
799
+ * removes them while retaining the surrounding source spelling. Leaving
800
+ * *both* unset keeps the spelling's comments exactly as originally
801
+ * written, since nothing was explicitly requested.
802
+ *
803
+ * Named after `app-prefix` (§6.1 of draft-ietf-cbor-edn-literals-27; e.g.
804
+ * `dt`, `DT`, `ip`, `IP`), the identifier that `app-string`/`app-sequence`
805
+ * notation is built from. The raw tag literal case is still covered: it's
806
+ * the source spelling that used *no* app-prefix at all, and this option
807
+ * preserves that choice too, not just spellings that did use one.
808
+ * `preserveAppSequence` was the old, narrower name for this same option,
809
+ * since it also preserves app-string and raw-tag spellings, not just
810
+ * `<<...>>` sequences.
747
811
  *
748
812
  * @default false
749
813
  */
814
+ preserveAppPrefix?: boolean;
815
+ /**
816
+ * @deprecated Renamed to `preserveAppPrefix` — the old name only
817
+ * described the `<<...>>` form even though this option also preserves
818
+ * `prefix'...'` / `` prefix`...` `` and raw tag (`N(...)`) spellings.
819
+ * Still honoured when `preserveAppPrefix` is left unset, but
820
+ * `preserveAppPrefix` wins if both are set, and it no longer
821
+ * participates in `preserveAll` (use `preserveAppPrefix` for that).
822
+ */
750
823
  preserveAppSequence?: boolean;
751
824
  /**
752
825
  * Numeric format for integer values in CDN output.
@@ -761,9 +834,25 @@ export interface ToCDNOptions {
761
834
  * Numeric format for floating-point values in CDN output.
762
835
  * - `'decimal'`: standard decimal notation (e.g. `1.5`, `145544.0_3`)
763
836
  * - `'hex'`: C99-style hex float notation (e.g. `0x1.8p+0`, `0x1.1c54p+17_3`)
837
+ * - `'app-extension'`: `float'...'` app-string notation carrying the
838
+ * value's exact IEEE 754 bit pattern (e.g. `float'3fc00000'`), per §3.8
839
+ * of draft-ietf-cbor-edn-literals-27. Unlike `'decimal'`/`'hex'`, this
840
+ * is derived from the value's actual encoded bytes rather than its
841
+ * numeric text, so it losslessly represents NaN payloads and
842
+ * ±Infinity too (not just finite values). Falls back to `'decimal'`
843
+ * when `appPrefix` is `false`, matching how other built-in extensions
844
+ * fall back to raw notation.
845
+ *
846
+ * A value originally parsed from a `float'...'`/`float<<...>>` literal
847
+ * normally re-emits that exact source spelling regardless of this option
848
+ * (so its own encoding-width choice, or a non-canonical bit pattern, isn't
849
+ * silently normalized away) — leaving `floatFormat` unset, or setting it
850
+ * to `'app-extension'`, keeps that round-trip. Explicitly requesting
851
+ * `'decimal'` or `'hex'` opts out of it and reformats the value like any
852
+ * other float, since that's the point of asking for a different format.
764
853
  * @default 'decimal'
765
854
  */
766
- floatFormat?: 'decimal' | 'hex';
855
+ floatFormat?: 'decimal' | 'hex' | 'app-extension';
767
856
  /**
768
857
  * Split long text strings using CDN string concatenation syntax (`"a" + "b"`).
769
858
  * Only effective when `indent` enables pretty-printing.
@@ -790,6 +879,11 @@ export interface ToCDNOptions {
790
879
  * `preserveConcatenation`; when it does not, the original concatenation
791
880
  * is preserved as usual.
792
881
  *
882
+ * `inlineLeafContainers` applies to the embedded CDN structure too: an
883
+ * array/map/`<<...>>` in the string content that would stay on one line
884
+ * as a real value keeps its split points collapsed here as well (e.g.
885
+ * `"[1, 2, 3]"` stays a single literal instead of splitting per element).
886
+ *
793
887
  * Replaces the deprecated `textStringFormat: ['cdn']`.
794
888
  *
795
889
  * @default false
@@ -825,8 +919,8 @@ export interface ToCDNOptions {
825
919
  * concatenation, and only takes effect when `indent` enables
826
920
  * pretty-printing (single-line output joins the parts into one literal).
827
921
  *
828
- * Also applies within an elision (`...`, §4.2 of
829
- * draft-ietf-cbor-edn-literals-25): a `+`-joined fragment on either side of
922
+ * Also applies within an elision (`...`, §5.2 of
923
+ * draft-ietf-cbor-edn-literals-27): a `+`-joined fragment on either side of
830
924
  * an ellipsis keeps its own part boundaries too (e.g. `'test' +
831
925
  * h'1234...abcd' + ...` stays exactly as written instead of merging
832
926
  * `'test'` into the byte fragment before it), and byte-string elision
@@ -842,17 +936,100 @@ export interface ToCDNOptions {
842
936
  */
843
937
  preserveConcatenation?: boolean;
844
938
  /**
845
- * When pretty-printing with `indent`, keep a container on a single line
846
- * when none of its entries contains an array or map (even wrapped in a
847
- * tag) and every entry serializes without a line break (e.g. `[1, 2, 3]`,
848
- * `{"a": 1}`, `(_ "a", "b")`). Nested leaf containers still collapse
849
- * individually: `[[1, 2], [3, 4]]` renders with one inner array per line.
939
+ * Render preserved `+` string concatenation (see `preserveConcatenation`)
940
+ * or an elision chain (`...`, §5.2) using `t1<<...>>` / `b1<<...>>`
941
+ * app-sequence notation (draft-ietf-cbor-edn-literals-27 §3.5)
942
+ * instead of the legacy `+` operator.
943
+ *
944
+ * - `false` (default): `"a" + "b"` / `'test' + h'1234...abcd' + ...`.
945
+ * - `true`: `t1<<"a", "b">>` / `b1<<h'1234', h'..abcd'>>`. Falls back to
946
+ * `false`'s rendering when `appPrefix` is `false`, since this notation
947
+ * is itself an app-string form.
948
+ *
949
+ * For a plain (non-elision) concatenation, only changes the spelling used
950
+ * where `preserveConcatenation` already causes multi-part rendering; has
951
+ * no effect when concatenation collapses into a single merged literal
952
+ * (e.g. `preserveConcatenation` unset, or a text string whose content is
953
+ * reflowed by `splitCdn` instead). An elision chain is different: `...`
954
+ * denotes genuinely unknown content, so it always renders as multiple
955
+ * parts regardless of `preserveConcatenation` — `modernConcat` therefore
956
+ * also applies to it unconditionally (`preserveConcatenation` there only
957
+ * controls how much of a fragment's *own* internal boundary is shown, not
958
+ * whether the chain itself is shown as multiple parts).
959
+ *
960
+ * Has no effect on a value that was itself parsed from `t1<<...>>` /
961
+ * `b1<<...>>` source: when `appPrefix` is not `false`, `encodingIndicators`
962
+ * is `'auto'` (both defaults), and the source is either single-line or
963
+ * being rendered with `indent` enabled, that spelling is kept verbatim
964
+ * regardless of `modernConcat` (see `t1`/`b1` in
965
+ * [String Concatenation and Indefinite-Length Strings](../README.md#string-concatenation-and-indefinite-length-strings)).
966
+ * A multi-line source falls back to normalized (collapsed) output in
967
+ * single-line mode, since that layout can't be reproduced without
968
+ * `indent`. `modernConcat` only affects values reconstructed from a `+`
969
+ * chain.
850
970
  *
851
- * `<<...>>` (CBOR Sequence Literal / embedded CBOR) is the one exception:
852
- * since it's a flat sequence of encoded items rather than a
853
- * nested-structure display, an entry that is itself an array/map still
854
- * inlines there as long as its own rendering fits on one line — e.g.
855
- * `<<{1: -7}>>` stays on one line, even though `[{1: -7}]` would not.
971
+ * @default false
972
+ */
973
+ modernConcat?: boolean;
974
+ /**
975
+ * Render an indefinite-length string using `ilts<<...>>` / `ilbs<<...>>`
976
+ * app-sequence notation (draft-ietf-cbor-edn-literals-27 §3.6)
977
+ * instead of the legacy `(_ "a", "b")` streamstring form.
978
+ *
979
+ * - `false` (default): `(_ "a", "b")`.
980
+ * - `true`: `ilts<<"a", "b">>` / `ilbs<<h'..', h'..'>>`. Falls back to
981
+ * `false`'s rendering when `appPrefix` is `false`, since this notation
982
+ * is itself an app-string form.
983
+ *
984
+ * Applies whenever an indefinite-length string is rendered as chunks;
985
+ * unaffected by `encodingIndicators: 'never'`, which merges the chunks
986
+ * into a single definite-length literal regardless of this option.
987
+ *
988
+ * Has no effect on a value that was itself parsed from `ilts<<...>>` /
989
+ * `ilbs<<...>>` source: when `appPrefix` is not `false`, `encodingIndicators`
990
+ * is `'auto'` (both defaults), and the source is either single-line or
991
+ * being rendered with `indent` enabled, that spelling is kept verbatim
992
+ * regardless of `modernStreamSyntax`. A multi-line source falls back to
993
+ * normalized (collapsed) output in single-line mode, since that layout
994
+ * can't be reproduced without `indent`. `modernStreamSyntax` only affects
995
+ * values reconstructed from a legacy `(_ ...)` chunk list.
996
+ *
997
+ * @default false
998
+ */
999
+ modernStreamSyntax?: boolean;
1000
+ /**
1001
+ * When pretty-printing with `indent`, keep an array, map, or
1002
+ * indefinite-length string group (`(_ "a", "b")`) on a single line when
1003
+ * none of its entries contains an array or map (even wrapped in a tag),
1004
+ * none of its entries is a text string with two or more words (also even
1005
+ * wrapped in a tag), and every entry serializes without a line break
1006
+ * (e.g. `[1, 2, 3]`, `{"a": 1}`, `(_ "a", "b")`). Word boundaries follow
1007
+ * `Intl.Segmenter`'s word-break rules, so `["hello", "world"]` still
1008
+ * collapses to one line (each entry is a single word) while `["Hello,
1009
+ * World!", "This is the CBOR library."]` renders one entry per line (each
1010
+ * has two or more) — space-less scripts (Japanese, Chinese, ...) are still
1011
+ * split on their own dictionary-based word boundaries. Nested leaf
1012
+ * containers still collapse individually: `[[1, 2], [3, 4]]` renders with
1013
+ * one inner array per line.
1014
+ *
1015
+ * `<<...>>` (CBOR Sequence Literal / embedded CBOR) is not governed by
1016
+ * this option at all: its own parens never require an additional line
1017
+ * break by themselves, regardless of `inlineLeafContainers`'s value,
1018
+ * since (unlike an array, map, or indefinite-length string group) it has
1019
+ * no nested-structure display of its own to spread out — it's a flat
1020
+ * sequence of encoded items. Instead it stays on one line exactly when
1021
+ * every entry's own actual rendering already does — an entry that is
1022
+ * itself an array/map is not disqualified just for being one, unlike in
1023
+ * an outer array/map. Concretely: `<<{1: -7}>>` renders as `<<{1: -7}>>`
1024
+ * when `inlineLeafContainers` lets the inner map collapse to one line,
1025
+ * but as `<<\n {\n 1: -7\n }\n>>` when it doesn't (the map itself
1026
+ * still spreads one entry per line without the option, same as it would
1027
+ * anywhere else — `<<...>>` just doesn't add a break of its own on top
1028
+ * of that). `[{1: -7}]`, by contrast, always spreads its `{1: -7}` entry
1029
+ * onto its own line regardless of whether the map itself collapses,
1030
+ * since a nested array/map always disqualifies an outer array/map's
1031
+ * entry. A two-or-more-word text entry still forces a break inside
1032
+ * `<<...>>` either way, irrespective of `inlineLeafContainers`.
856
1033
  *
857
1034
  * Containers with preserved comments are always emitted in multi-line
858
1035
  * form. Has no effect when `indent` is omitted.
@@ -923,12 +1100,12 @@ export interface ValidateOptions {
923
1100
  */
924
1101
  extensions?: CborExtension[];
925
1102
  /**
926
- * Override the default set of bundled application-oriented extensions.
1103
+ * Override the default set of bundled app-extensions.
927
1104
  * Mirrors `FromCBOROptions.builtinExtensions`.
928
1105
  */
929
1106
  builtinExtensions?: CborExtension[] | false;
930
1107
  /**
931
- * How to handle unrecognised application-extension identifiers.
1108
+ * How to handle unrecognised app-extension identifiers.
932
1109
  * Only applies when `type` is `'cdn'`; mirrors `FromCDNOptions.unresolvedExtension`.
933
1110
  * @default 'cpa999'
934
1111
  */
@@ -1003,9 +1180,9 @@ export interface ValidateResult {
1003
1180
  */
1004
1181
  cddlWarnings?: CddlValidationWarning[];
1005
1182
  }
1006
- /** `fromCBORSeq()` の options(`offset`/`allowTrailing` はジェネレータが管理するため除外)。 */
1183
+ /** Options for `fromCBORSeq()` (`offset`/`allowTrailing` are excluded — the generator manages them). */
1007
1184
  export type FromCBORSeqOptions = Omit<FromCBOROptions, 'offset' | 'allowTrailing'>;
1008
- /** `fromCDNSeq()` の options(`offset`/`allowTrailing` はジェネレータが管理するため除外)。 */
1185
+ /** Options for `fromCDNSeq()` (`offset`/`allowTrailing` are excluded — the generator manages them). */
1009
1186
  export type FromCDNSeqOptions = Omit<FromCDNOptions, 'offset' | 'allowTrailing'>;
1010
1187
  /**
1011
1188
  * Combined options for the `CBOR` constructor.
@@ -2,7 +2,7 @@
2
2
  * Decode base64 text (classic or URL-safe alphabet, padding optional) into
3
3
  * bytes, with strict RFC 4648 validation.
4
4
  *
5
- * Used by the CDN parser (b64'…' literals, §5.3.4) and the CDDL tokenizer
5
+ * Used by the CDN parser (b64'…' literals, §6.2.2) and the CDDL tokenizer
6
6
  * (b64'…' byte strings, RFC 8610 §3.1).
7
7
  *
8
8
  * Recoverable deviations (padding-count mismatches, non-zero trailing bits)
@@ -4,7 +4,7 @@
4
4
  * Hex float format:
5
5
  * [-] 0x [hex digits] [. [hex digits]] p [+-] [decimal exponent]
6
6
  *
7
- * This notation appears in CDN (draft-ietf-cbor-edn-literals-25) as an
7
+ * This notation appears in CDN (draft-ietf-cbor-edn-literals-27) as an
8
8
  * alternative representation for floating-point values (major type 7).
9
9
  */
10
10
  /**
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Strip whitespace and EDN §2.2 comments from app-string content.
2
+ * Strip whitespace and EDN §2.1 comments from app-string content.
3
3
  *
4
4
  * Used by extensions whose content allows the same comment syntax as byte
5
5
  * string literals (b32, h32, float, …):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cbortech/cbor",
3
- "version": "0.26.8",
3
+ "version": "0.27.0",
4
4
  "description": "Convert between CBOR, CDN (CBOR-EDN), and JavaScript values with CDDL validation",
5
5
  "keywords": [
6
6
  "cbor",
@@ -89,12 +89,13 @@
89
89
  "build": "vite build",
90
90
  "prepack": "npm run build",
91
91
  "watch": "vite build --watch",
92
- "typecheck": "tsc --noEmit",
92
+ "typecheck": "node ./node_modules/typescript/bin/tsc --noEmit",
93
93
  "start": "node dist/index.js",
94
94
  "dev": "npm run build && npm start",
95
95
  "clean": "node -e \"['dist','coverage'].forEach(d=>require('fs').rmSync(d,{recursive:true,force:true}))\"",
96
96
  "test": "vitest run --exclude src/cdn/edn-test-vectors.test.ts --exclude src/cdn/edn-abnf-vectors.test.ts --exclude src/cddl/cddl-corpus.test.ts --exclude src/cddl/cddl-validation-vectors.test.ts --exclude site/src/playground.browser.test.ts",
97
97
  "test:exports": "npm run build && node scripts/check-package-exports.mjs",
98
+ "fetch-test-vectors": "node scripts/fetch-test-vectors.mjs",
98
99
  "test:node": "vitest run --exclude src/cdn/edn-test-vectors.test.ts --exclude src/cdn/edn-abnf-vectors.test.ts --exclude src/cddl/cddl-corpus.test.ts --exclude src/cddl/cddl-validation-vectors.test.ts --exclude site/src/playground.browser.test.ts",
99
100
  "test:edn-vectors": "vitest run src/cdn/edn-test-vectors.test.ts",
100
101
  "test:edn-abnf": "vitest run src/cdn/edn-abnf-vectors.test.ts",
@@ -119,16 +120,17 @@
119
120
  "devDependencies": {
120
121
  "@cbortech/hash-extension": "^0.2.3",
121
122
  "@types/node": "^24.13.3",
123
+ "@typescript/typescript6": "^6.0.2",
122
124
  "@vitest/browser": "^4.1.10",
123
125
  "@vitest/browser-playwright": "^4.1.10",
124
126
  "@vitest/coverage-v8": "^4.1.10",
125
127
  "@vitest/ui": "^4.1.10",
126
128
  "cross-env": "^10.1.0",
127
- "playwright": "^1.61.1",
129
+ "playwright": "^1.62.1",
128
130
  "prettier": "^3.9.6",
129
- "typescript": "^5.9.3",
130
- "vite": "^8.1.5",
131
- "vite-plugin-dts": "^4.5.4",
131
+ "typescript": "^7.0.2",
132
+ "vite": "^8.2.1",
133
+ "vite-plugin-dts": "^5.0.3",
132
134
  "vitest": "^4.1.10"
133
135
  }
134
136
  }