@cbortech/cbor 0.26.7 → 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.
- package/README.ja.md +120 -47
- package/README.md +121 -48
- package/dist/ast/CborAppSeqResult.d.ts +22 -0
- package/dist/ast/CborByteString.d.ts +27 -0
- package/dist/ast/CborEmbeddedCBOR.d.ts +1 -1
- package/dist/ast/CborFloat.d.ts +1 -1
- package/dist/ast/CborIndefiniteByteString.d.ts +24 -0
- package/dist/ast/CborIndefiniteTextString.d.ts +16 -0
- package/dist/ast/CborItem.d.ts +44 -4
- package/dist/ast/CborTag.d.ts +27 -0
- package/dist/ast/CborTextString.d.ts +18 -1
- package/dist/ast/CborUnresolvedAppExt.d.ts +2 -2
- package/dist/ast/index.cjs +1 -1
- package/dist/ast/index.d.ts +1 -0
- package/dist/ast/index.js +2 -2
- package/dist/cddl/index.cjs +1 -1
- package/dist/cddl/index.js +1 -1
- package/dist/cdn/index.cjs +2 -2
- package/dist/cdn/index.cjs.map +1 -1
- package/dist/cdn/index.d.ts +2 -0
- package/dist/cdn/index.js +15 -15
- package/dist/cdn/index.js.map +1 -1
- package/dist/cdn/serialize-utils.d.ts +241 -21
- package/dist/cdn/tokenizer.d.ts +12 -11
- package/dist/extensions/builtins.d.ts +5 -5
- package/dist/extensions/cri.d.ts +2 -2
- package/dist/extensions/ip.d.ts +1 -1
- package/dist/extensions/types.d.ts +4 -4
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +158 -158
- package/dist/index.js.map +1 -1
- package/dist/mapEntries-C1f7G0AM.cjs +13 -0
- package/dist/mapEntries-C1f7G0AM.cjs.map +1 -0
- package/dist/{mapEntries-DxrDre2P.js → mapEntries-CvLdiN0h.js} +1479 -1558
- package/dist/mapEntries-CvLdiN0h.js.map +1 -0
- package/dist/{schema-Bofmsptw.js → schema-CNfrVRYp.js} +294 -294
- package/dist/{schema-Bofmsptw.js.map → schema-CNfrVRYp.js.map} +1 -1
- package/dist/schema-iXpYtKQl.cjs +63 -0
- package/dist/{schema-t_bdPk8_.cjs.map → schema-iXpYtKQl.cjs.map} +1 -1
- package/dist/{tokenizer-CeuixxXi.js → serialize-utils-BuIZPaUc.js} +634 -30
- package/dist/serialize-utils-BuIZPaUc.js.map +1 -0
- package/dist/serialize-utils-CjTqQivB.cjs +37 -0
- package/dist/serialize-utils-CjTqQivB.cjs.map +1 -0
- package/dist/types.d.ts +248 -64
- package/dist/utils/base64.d.ts +1 -1
- package/dist/utils/hexfloat.d.ts +1 -1
- package/dist/utils/strip-comments.d.ts +1 -1
- package/package.json +8 -7
- package/dist/mapEntries-D2NyeCX3.cjs +0 -17
- package/dist/mapEntries-D2NyeCX3.cjs.map +0 -1
- package/dist/mapEntries-DxrDre2P.js.map +0 -1
- package/dist/schema-t_bdPk8_.cjs +0 -63
- package/dist/tokenizer-CeuixxXi.js.map +0 -1
- package/dist/tokenizer-EciPlN0n.cjs +0 -30
- package/dist/tokenizer-EciPlN0n.cjs.map +0 -1
package/README.ja.md
CHANGED
|
@@ -330,25 +330,6 @@ CBOR.format('`\\d+`', { preserveRawString: true });
|
|
|
330
330
|
// '`\\d+`'
|
|
331
331
|
```
|
|
332
332
|
|
|
333
|
-
### ダブルクォート文字列の表記を保持する
|
|
334
|
-
|
|
335
|
-
デフォルトでは、`CBOR.format()` はダブルクォートのテキスト文字列をデコード後の
|
|
336
|
-
値から再エスケープします。そのため `\uXXXX` エスケープはリテラル文字に変換され
|
|
337
|
-
ます。`preserveTextString` を指定すると、連結されていない `"..."` リテラルを
|
|
338
|
-
元のソース表記のまま再出力します。(バッククォートの raw 文字列(`` `...` ``)
|
|
339
|
-
はこのオプションではなく `preserveRawString` の対象です。`+` 連結を経由した
|
|
340
|
-
文字列は、このオプションを指定していても通常どおり正規化されます。)
|
|
341
|
-
|
|
342
|
-
```ts
|
|
343
|
-
import { CBOR } from '@cbortech/cbor';
|
|
344
|
-
|
|
345
|
-
CBOR.format('"caf\\u00e9"');
|
|
346
|
-
// '"café"'
|
|
347
|
-
|
|
348
|
-
CBOR.format('"caf\\u00e9"', { preserveTextString: true });
|
|
349
|
-
// '"caf\\u00e9"'
|
|
350
|
-
```
|
|
351
|
-
|
|
352
333
|
### 数値リテラルの表記を保持する
|
|
353
334
|
|
|
354
335
|
デフォルトでは、`CBOR.format()` は整数・浮動小数点数リテラルを正規化します。
|
|
@@ -404,18 +385,22 @@ CBOR.format("h'68' + b64'aQ'", {
|
|
|
404
385
|
// b64'aQ'
|
|
405
386
|
```
|
|
406
387
|
|
|
407
|
-
|
|
388
|
+
保持した連結を `+` ではなく draft-27 の `t1<<...>>` / `b1<<...>>` 記法で
|
|
389
|
+
出力するには、[文字列連結と不定長文字列](#文字列連結と不定長文字列) の
|
|
390
|
+
`modernConcat` を参照してください。
|
|
391
|
+
|
|
392
|
+
### app-string / -sequence 記法を保持する
|
|
408
393
|
|
|
409
394
|
一部の組み込み拡張(`dt`/`DT`、`ip`/`IP`)は同じ値に対して `prefix'...'`
|
|
410
|
-
(
|
|
411
|
-
`prefix<<...>>`(
|
|
395
|
+
(app-string)、`` prefix`...` ``(backtick app-string)、
|
|
396
|
+
`prefix<<...>>`(app-sequence)、生のタグリテラル(`N(...)`)の
|
|
412
397
|
いずれの記法もサポートしていますが、デフォルトでは `CBOR.format()` を呼ぶ
|
|
413
398
|
たびに解決済みの値から `prefix'...'` を再生成します。そのため
|
|
414
399
|
`` DT`1969-07-21T02:56:16Z` `` も `DT<<'1969-07-21T02:56:16Z'>>` も、生の
|
|
415
400
|
タグ記法 `1(1749772800)` さえも、すべて `DT'...'` 記法に正規化され、さら
|
|
416
401
|
に非正規な `DT'...'` の表記(例えば `Z` の代わりに `+00:00` を使った場合
|
|
417
|
-
など)も書き換えられます。`
|
|
418
|
-
れていた表記のまま保持します。`
|
|
402
|
+
など)も書き換えられます。`preserveAppPrefix` を指定すると、実際に使わ
|
|
403
|
+
れていた表記のまま保持します。`appPrefix: false` を同時に指定した場合は
|
|
419
404
|
効果がありません(どちらにせよ元の表記に関わらず生のタグ記法になるため)。
|
|
420
405
|
これらの記法からパースされていない値にも効果はありません。
|
|
421
406
|
|
|
@@ -425,16 +410,50 @@ import { CBOR } from '@cbortech/cbor';
|
|
|
425
410
|
CBOR.format('1(1749772800)');
|
|
426
411
|
// "DT'2025-06-13T00:00:00Z'"
|
|
427
412
|
|
|
428
|
-
CBOR.format('1(1749772800)', {
|
|
413
|
+
CBOR.format('1(1749772800)', { preserveAppPrefix: true });
|
|
429
414
|
// "1(1749772800)"
|
|
430
415
|
|
|
431
|
-
CBOR.format("DT<<'1969-07-21T02:56:16Z'>>", {
|
|
416
|
+
CBOR.format("DT<<'1969-07-21T02:56:16Z'>>", { preserveAppPrefix: true });
|
|
432
417
|
// "DT<<'1969-07-21T02:56:16Z'>>"
|
|
433
418
|
|
|
434
|
-
CBOR.format('DT`1969-07-21T02:56:16Z`', {
|
|
419
|
+
CBOR.format('DT`1969-07-21T02:56:16Z`', { preserveAppPrefix: true });
|
|
435
420
|
// "DT`1969-07-21T02:56:16Z`"
|
|
436
421
|
```
|
|
437
422
|
|
|
423
|
+
### コメントを保持する
|
|
424
|
+
|
|
425
|
+
デフォルトでは、`CBOR.fromCDN()` はコメントを破棄し、`CBOR.format()` も
|
|
426
|
+
コメントを出力しません。`preserveComments: true` を指定すると、パース時に
|
|
427
|
+
コメントを取り込み、元々書かれていたマーカー(`#`・`//`・`/* */`・`/ /`)の
|
|
428
|
+
まま再出力します。
|
|
429
|
+
|
|
430
|
+
```ts
|
|
431
|
+
import { CBOR } from '@cbortech/cbor';
|
|
432
|
+
|
|
433
|
+
const text = '{ "a": 1 } # trailing comment';
|
|
434
|
+
|
|
435
|
+
CBOR.format(text, { indent: 2 });
|
|
436
|
+
// '{\n "a": 1\n}'
|
|
437
|
+
|
|
438
|
+
CBOR.format(text, { indent: 2, preserveComments: true });
|
|
439
|
+
// '{\n "a": 1\n} # trailing comment'
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
書かれていたマーカーを混在させたまま保持するのではなく、すべてのコメントの
|
|
443
|
+
マーカーを正規化したい場合は `comments` を使います — `'c-style'` は
|
|
444
|
+
`//` と `/* */`、`'cdn-style'` は `#` と `/ /` に正規化します。
|
|
445
|
+
`preserveComments: true` が指定されている場合は効果がありません(verbatim
|
|
446
|
+
が優先されます)。コメントを完全に削除するには `comments: 'strip'` を
|
|
447
|
+
明示的に指定するか(あるいは両方とも未指定のままにするか)します。
|
|
448
|
+
|
|
449
|
+
```ts
|
|
450
|
+
CBOR.format(text, { indent: 2, comments: 'c-style' });
|
|
451
|
+
// '{\n "a": 1\n} // trailing comment'
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
`indent` を指定して整形出力する場合のみ効果があります。1 行出力では改行で
|
|
455
|
+
終端する必要がある行コメントの性質上、コメントは常に取り除かれます。
|
|
456
|
+
|
|
438
457
|
### 空行を保持する
|
|
439
458
|
|
|
440
459
|
デフォルトでは、`CBOR.format()` は配列・マップの要素間(および `(_ ...)`
|
|
@@ -691,7 +710,7 @@ console.log(text);
|
|
|
691
710
|
|
|
692
711
|
## 文字列連結と不定長文字列
|
|
693
712
|
|
|
694
|
-
draft-ietf-cbor-edn-literals-
|
|
713
|
+
draft-ietf-cbor-edn-literals-27(§3.5 / §3.6)の app-extension
|
|
695
714
|
`t1` / `b1` / `ilbs` / `ilts` は、デフォルトで有効です。
|
|
696
715
|
|
|
697
716
|
`t1<<...>>` と `b1<<...>>` は、(テキストまたはバイト)文字列の引数を左から
|
|
@@ -702,11 +721,11 @@ draft-ietf-cbor-edn-literals-26(§3.4 / §3.5)の application extension
|
|
|
702
721
|
import { CBOR } from '@cbortech/cbor';
|
|
703
722
|
|
|
704
723
|
const text = CBOR.fromCDN('t1<<"Hello ", "world">>');
|
|
705
|
-
console.log(text.toCDN({
|
|
724
|
+
console.log(text.toCDN({ appPrefix: false }));
|
|
706
725
|
// "Hello world"
|
|
707
726
|
|
|
708
727
|
const bytes = CBOR.fromCDN("b1<<'Hello ', h'776f726c64'>>");
|
|
709
|
-
console.log(bytes.toCDN({
|
|
728
|
+
console.log(bytes.toCDN({ appPrefix: false }));
|
|
710
729
|
// 'Hello world'
|
|
711
730
|
```
|
|
712
731
|
|
|
@@ -720,29 +739,82 @@ streamstring 構文の置き換えですが、本ライブラリは従来構文
|
|
|
720
739
|
import { CBOR } from '@cbortech/cbor';
|
|
721
740
|
|
|
722
741
|
const v = CBOR.fromCDN("ilbs<<'Hello ', 'world'>>");
|
|
723
|
-
console.log(v.toCDN({
|
|
742
|
+
console.log(v.toCDN({ appPrefix: false }));
|
|
724
743
|
// (_ 'Hello ','world')
|
|
725
744
|
```
|
|
726
745
|
|
|
746
|
+
### `t1`/`b1`/`ilbs`/`ilts` 記法を出力する
|
|
747
|
+
|
|
748
|
+
パース側はすでに `t1`/`b1`/`ilbs`/`ilts` 記法を受理しますが、`toCDN()` /
|
|
749
|
+
`CBOR.format()` はデフォルトではこれらを自ら出力しません。保持した連結
|
|
750
|
+
(`preserveConcatenation`)は従来どおり `+` で、不定長文字列は従来どおり
|
|
751
|
+
`(_ ...)` streamstring 形式でレンダリングされます。`modernConcat` と
|
|
752
|
+
`modernStreamSyntax` を `true` にすると draft-27 の記法での出力を選択でき
|
|
753
|
+
ます。どちらもデフォルトは `false`(従来構文)で、`appPrefix` が `false`
|
|
754
|
+
の場合は従来構文にフォールバックします。
|
|
755
|
+
|
|
756
|
+
```ts
|
|
757
|
+
import { CBOR } from '@cbortech/cbor';
|
|
758
|
+
|
|
759
|
+
CBOR.format('"a" + "b"', {
|
|
760
|
+
indent: 2,
|
|
761
|
+
preserveConcatenation: true,
|
|
762
|
+
modernConcat: true,
|
|
763
|
+
});
|
|
764
|
+
// t1<<"a", "b">>
|
|
765
|
+
|
|
766
|
+
CBOR.format('(_ "a", "b")', { modernStreamSyntax: true });
|
|
767
|
+
// ilts<<"a","b">>
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
`modernConcat` は `...` による省略連結(§5.2)にも適用され、
|
|
771
|
+
`"a" + ... + "b"` は `t1<<"a", ..., "b">>` としてレンダリングされます。
|
|
772
|
+
通常の連結と異なり、これは `preserveConcatenation` の値に関わらず適用され
|
|
773
|
+
ます — 省略連結にはそもそも1つのリテラルに畳み込んだ状態が存在しないため
|
|
774
|
+
です。
|
|
775
|
+
|
|
776
|
+
> [!NOTE]
|
|
777
|
+
> どちらのオプションも `t1`/`b1`/`ilbs`/`ilts` のソースを従来記法に
|
|
778
|
+
> 変換するものではありません。`t1<<...>>`(や `ilbs<<...>>` など)
|
|
779
|
+
> からパースされた値は、`appPrefix` が `false` でなく、
|
|
780
|
+
> `encodingIndicators` が `'auto'`(どちらもデフォルト)であり、かつ
|
|
781
|
+
> ソースが単一行、または `indent` 指定時であれば、`modernConcat` /
|
|
782
|
+
> `modernStreamSyntax` の値に関わらずそのままの記法で出力されます。
|
|
783
|
+
> `encodingIndicators: 'always'`/`'never'` や `appPrefix: false` を指定
|
|
784
|
+
> した場合は、他の app-string 値と同様に正規化されます(例:
|
|
785
|
+
> `encodingIndicators: 'always'` では `t1<<"a", "b">>` が `"ab"_i` に
|
|
786
|
+
> なります)。また、複数行のソースは `indent` 未指定(1行出力)の場合、
|
|
787
|
+
> そのレイアウトを再現できないため正規化されます:
|
|
788
|
+
>
|
|
789
|
+
> ```ts
|
|
790
|
+
> CBOR.format('t1<<\n "a",\n "b"\n>>');
|
|
791
|
+
> // '"ab"' — indent未指定のため正規化される
|
|
792
|
+
> CBOR.format('t1<<\n "a",\n "b"\n>>', { indent: 2 });
|
|
793
|
+
> // 't1<<\n "a",\n "b"\n>>' — そのまま保持される
|
|
794
|
+
> ```
|
|
795
|
+
>
|
|
796
|
+
> 両オプションが影響するのは `+` チェーンや `(_ ...)` チャンク列から
|
|
797
|
+
> 再構築された値の出力のみです。
|
|
798
|
+
|
|
727
799
|
> [!NOTE]
|
|
728
|
-
> `t1` / `b1` という識別子は draft-
|
|
800
|
+
> `t1` / `b1` という識別子は draft-27 でも暫定(provisional)と明記されて
|
|
729
801
|
> おり、CBOR ワーキンググループにより改名される可能性があります。
|
|
730
802
|
|
|
731
803
|
## float
|
|
732
804
|
|
|
733
805
|
16 進数のビットパターンを IEEE 754 浮動小数点値として解釈します
|
|
734
|
-
(draft-ietf-cbor-edn-literals-
|
|
806
|
+
(draft-ietf-cbor-edn-literals-27 §3.8)。デフォルトで有効です。
|
|
735
807
|
|
|
736
808
|
```ts
|
|
737
809
|
import { CBOR } from '@cbortech/cbor';
|
|
738
810
|
|
|
739
811
|
const v = CBOR.fromCDN("float'7e00'");
|
|
740
|
-
console.log(v.toCDN({
|
|
812
|
+
console.log(v.toCDN({ appPrefix: false }));
|
|
741
813
|
// NaN
|
|
742
814
|
|
|
743
815
|
// バイト列から解釈する場合
|
|
744
816
|
const v2 = CBOR.fromCDN("float<<h'3f800000'>>");
|
|
745
|
-
console.log(v2.toCDN({
|
|
817
|
+
console.log(v2.toCDN({ appPrefix: false }));
|
|
746
818
|
// 1.0_2
|
|
747
819
|
```
|
|
748
820
|
|
|
@@ -755,7 +827,7 @@ extension があります。必要なものを `import` し、
|
|
|
755
827
|
### b32 / h32
|
|
756
828
|
|
|
757
829
|
[RFC 4648](https://www.rfc-editor.org/rfc/rfc4648) の Base32 エンコードによるバイト列リテラルです。
|
|
758
|
-
[RFC 8949](https://www.rfc-editor.org/rfc/rfc8949) §8 に記載があり、[draft-ietf-cbor-edn-literals](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/
|
|
830
|
+
[RFC 8949](https://www.rfc-editor.org/rfc/rfc8949) §8 に記載があり、[draft-ietf-cbor-edn-literals](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/27/) でも触れられています。
|
|
759
831
|
|
|
760
832
|
- `b32` — §6 Base32(`A–Z 2–7` アルファベット)
|
|
761
833
|
- `h32` — §7 Base32Hex(`0–9 A–V` アルファベット)
|
|
@@ -764,11 +836,11 @@ extension があります。必要なものを `import` し、
|
|
|
764
836
|
import { CBOR, b32, h32 } from '@cbortech/cbor';
|
|
765
837
|
|
|
766
838
|
const v1 = CBOR.fromCDN("b32'AEBAGBA'", { extensions: [b32] });
|
|
767
|
-
console.log(v1.toCDN({
|
|
839
|
+
console.log(v1.toCDN({ appPrefix: false }));
|
|
768
840
|
// h'01020304'
|
|
769
841
|
|
|
770
842
|
const v2 = CBOR.fromCDN("h32'00P00'", { extensions: [h32] });
|
|
771
|
-
console.log(v2.toCDN({
|
|
843
|
+
console.log(v2.toCDN({ appPrefix: false }));
|
|
772
844
|
// h'003200'
|
|
773
845
|
```
|
|
774
846
|
|
|
@@ -782,25 +854,24 @@ console.log(v2.toCDN({ appStrings: false }));
|
|
|
782
854
|
```ts
|
|
783
855
|
import { CBOR, same } from '@cbortech/cbor';
|
|
784
856
|
|
|
785
|
-
// すべての要素が同じバイト列かを検証し、最初の要素を返す
|
|
786
857
|
const v = CBOR.fromCDN("same<<h'0102', h'0102'>>", { extensions: [same] });
|
|
787
|
-
console.log(v.toCDN({
|
|
858
|
+
console.log(v.toCDN({ appPrefix: false }));
|
|
788
859
|
// h'0102'
|
|
789
860
|
|
|
790
861
|
// 要素が 1 つでも有効(常にパスする)
|
|
791
862
|
const v2 = CBOR.fromCDN('same<<42>>', { extensions: [same] });
|
|
792
|
-
console.log(v2.toCDN({
|
|
863
|
+
console.log(v2.toCDN({ appPrefix: false }));
|
|
793
864
|
// 42
|
|
794
865
|
```
|
|
795
866
|
|
|
796
867
|
---
|
|
797
868
|
|
|
798
|
-
追加の
|
|
869
|
+
追加の app-extension は別パッケージとして公開されています。必要なものを
|
|
799
870
|
インストールし、`extensions` オプションに渡して使います。
|
|
800
871
|
|
|
801
872
|
### hash
|
|
802
873
|
|
|
803
|
-
`hash` は [draft-ietf-cbor-edn-literals](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/
|
|
874
|
+
`hash` は [draft-ietf-cbor-edn-literals](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/27/) §3.4 で定義された標準の app-extension です。
|
|
804
875
|
ハッシュアルゴリズムと値を `hash'algorithm:value'` の形式で表現します。
|
|
805
876
|
実装には外部の暗号ライブラリが必要なため、[@cbortech/hash-extension](https://www.npmjs.com/package/@cbortech/hash-extension) として
|
|
806
877
|
別パッケージで提供しています。
|
|
@@ -825,7 +896,7 @@ const digest = cbor.parse(
|
|
|
825
896
|
|
|
826
897
|
### uuid
|
|
827
898
|
|
|
828
|
-
`uuid` はこのライブラリ独自の
|
|
899
|
+
`uuid` はこのライブラリ独自の app-extension です。
|
|
829
900
|
[@cbortech/uuid-extension](https://www.npmjs.com/package/@cbortech/uuid-extension) として別パッケージで提供しています。
|
|
830
901
|
|
|
831
902
|
```bash
|
|
@@ -845,7 +916,7 @@ const id = cbor.parse("uuid'550e8400-e29b-41d4-a716-446655440000'");
|
|
|
845
916
|
### set / map
|
|
846
917
|
|
|
847
918
|
`SET` と `MAP` は、タグ付きの Set / Map 値を扱うための、このライブラリ独自の
|
|
848
|
-
|
|
919
|
+
app-extension です。
|
|
849
920
|
[@cbortech/set-map-extensions](https://www.npmjs.com/package/@cbortech/set-map-extensions)
|
|
850
921
|
としてまとめて別パッケージで提供しています。`SET<<[...]>>` は配列に CBOR tag
|
|
851
922
|
258 を付けた値、`MAP<<{...}>>` は map に CBOR tag 259 を付けた値を生成します。
|
|
@@ -1102,9 +1173,11 @@ CDDL コンパイラは `@cbortech/cbor/cddl`
|
|
|
1102
1173
|
|
|
1103
1174
|
- CBOR
|
|
1104
1175
|
- [RFC 8949](https://www.rfc-editor.org/rfc/rfc8949)
|
|
1176
|
+
- CBOR Sequences
|
|
1177
|
+
- [RFC 8742](https://www.rfc-editor.org/rfc/rfc8742)
|
|
1105
1178
|
- CDN (CBOR-EDN)
|
|
1106
1179
|
- [draft-ietf-cbor-edn-literals-25](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/25/)
|
|
1107
|
-
- [draft-ietf-cbor-edn-literals-
|
|
1180
|
+
- [draft-ietf-cbor-edn-literals-27](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/27/)
|
|
1108
1181
|
- CDDL
|
|
1109
1182
|
- [RFC 8610](https://www.rfc-editor.org/rfc/rfc8610)
|
|
1110
1183
|
- [RFC 9682](https://www.rfc-editor.org/rfc/rfc9682)
|
|
@@ -1112,7 +1185,7 @@ CDDL コンパイラは `@cbortech/cbor/cddl`
|
|
|
1112
1185
|
|
|
1113
1186
|
補足:
|
|
1114
1187
|
|
|
1115
|
-
- CDN は draft-
|
|
1188
|
+
- CDN は draft-27 に準拠しつつ、draft-25 の `(_ ...)` streamstring 構文と
|
|
1116
1189
|
`+` による文字列連結構文も引き続きサポートしています。
|
|
1117
1190
|
- CDDL は RFC 8610 のすべての control operator と、RFC 9165 の `.plus`、
|
|
1118
1191
|
`.cat`、`.feature` をサポートしています。
|
package/README.md
CHANGED
|
@@ -336,25 +336,6 @@ CBOR.format('`\\d+`', { preserveRawString: true });
|
|
|
336
336
|
// '`\\d+`'
|
|
337
337
|
```
|
|
338
338
|
|
|
339
|
-
### Preserve double-quoted string spelling
|
|
340
|
-
|
|
341
|
-
By default, `CBOR.format()` re-escapes double-quoted text strings from their
|
|
342
|
-
decoded value, so e.g. a `\uXXXX` escape becomes the literal character.
|
|
343
|
-
`preserveTextString` re-emits a non-concatenated `"..."` literal using its
|
|
344
|
-
original source spelling instead. (Raw backtick literals such as `` `...` ``
|
|
345
|
-
are covered by `preserveRawString`, not this option; a string reached via
|
|
346
|
-
`+` concatenation is normalised as usual regardless of this option.)
|
|
347
|
-
|
|
348
|
-
```ts
|
|
349
|
-
import { CBOR } from '@cbortech/cbor';
|
|
350
|
-
|
|
351
|
-
CBOR.format('"caf\\u00e9"');
|
|
352
|
-
// '"café"'
|
|
353
|
-
|
|
354
|
-
CBOR.format('"caf\\u00e9"', { preserveTextString: true });
|
|
355
|
-
// '"caf\\u00e9"'
|
|
356
|
-
```
|
|
357
|
-
|
|
358
339
|
### Preserve number literal spelling
|
|
359
340
|
|
|
360
341
|
By default, `CBOR.format()` normalizes integer and floating-point literals:
|
|
@@ -411,19 +392,23 @@ CBOR.format("h'68' + b64'aQ'", {
|
|
|
411
392
|
// b64'aQ'
|
|
412
393
|
```
|
|
413
394
|
|
|
414
|
-
|
|
395
|
+
To render the preserved concatenation using draft-27's `t1<<...>>` /
|
|
396
|
+
`b1<<...>>` notation instead of `+`, see `modernConcat` in
|
|
397
|
+
[String Concatenation and Indefinite-Length Strings](#string-concatenation-and-indefinite-length-strings).
|
|
398
|
+
|
|
399
|
+
### Preserve app-string/-sequence notation
|
|
415
400
|
|
|
416
401
|
Some built-in extensions (`dt`/`DT`, `ip`/`IP`) support `prefix'...'`
|
|
417
|
-
(
|
|
418
|
-
`prefix<<...>>` (
|
|
402
|
+
(app-string), `` prefix`...` `` (backtick app-string),
|
|
403
|
+
`prefix<<...>>` (app-sequence), and a raw tag literal (`N(...)`)
|
|
419
404
|
notation for the same value, and by default regenerate `prefix'...'` from
|
|
420
405
|
the resolved value on every `CBOR.format()` call — so
|
|
421
406
|
`` DT`1969-07-21T02:56:16Z` ``, `DT<<'1969-07-21T02:56:16Z'>>`, and even the
|
|
422
407
|
raw tag form `1(1749772800)` all normalize to `DT'...'` notation, and a
|
|
423
408
|
non-canonical `DT'...'` spelling (e.g. a `+00:00` offset instead of `Z`)
|
|
424
|
-
gets rewritten too. `
|
|
409
|
+
gets rewritten too. `preserveAppPrefix` keeps the original spelling
|
|
425
410
|
instead — whichever form was used. It has no effect when
|
|
426
|
-
`
|
|
411
|
+
`appPrefix: false` is also set (raw tag notation is used either way
|
|
427
412
|
regardless of the original spelling), or on values not parsed from one of
|
|
428
413
|
these forms.
|
|
429
414
|
|
|
@@ -433,16 +418,50 @@ import { CBOR } from '@cbortech/cbor';
|
|
|
433
418
|
CBOR.format('1(1749772800)');
|
|
434
419
|
// "DT'2025-06-13T00:00:00Z'"
|
|
435
420
|
|
|
436
|
-
CBOR.format('1(1749772800)', {
|
|
421
|
+
CBOR.format('1(1749772800)', { preserveAppPrefix: true });
|
|
437
422
|
// "1(1749772800)"
|
|
438
423
|
|
|
439
|
-
CBOR.format("DT<<'1969-07-21T02:56:16Z'>>", {
|
|
424
|
+
CBOR.format("DT<<'1969-07-21T02:56:16Z'>>", { preserveAppPrefix: true });
|
|
440
425
|
// "DT<<'1969-07-21T02:56:16Z'>>"
|
|
441
426
|
|
|
442
|
-
CBOR.format('DT`1969-07-21T02:56:16Z`', {
|
|
427
|
+
CBOR.format('DT`1969-07-21T02:56:16Z`', { preserveAppPrefix: true });
|
|
443
428
|
// "DT`1969-07-21T02:56:16Z`"
|
|
444
429
|
```
|
|
445
430
|
|
|
431
|
+
### Preserve comments
|
|
432
|
+
|
|
433
|
+
By default, `CBOR.fromCDN()` discards comments and `CBOR.format()` emits
|
|
434
|
+
none. `preserveComments: true` captures them while parsing and re-emits each
|
|
435
|
+
comment verbatim, with whichever marker (`#`, `//`, `/* */`, `/ /`) it was
|
|
436
|
+
originally written with.
|
|
437
|
+
|
|
438
|
+
```ts
|
|
439
|
+
import { CBOR } from '@cbortech/cbor';
|
|
440
|
+
|
|
441
|
+
const text = '{ "a": 1 } # trailing comment';
|
|
442
|
+
|
|
443
|
+
CBOR.format(text, { indent: 2 });
|
|
444
|
+
// '{\n "a": 1\n}'
|
|
445
|
+
|
|
446
|
+
CBOR.format(text, { indent: 2, preserveComments: true });
|
|
447
|
+
// '{\n "a": 1\n} # trailing comment'
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
To normalize every comment's marker instead of keeping the mix as originally
|
|
451
|
+
written, use `comments` — `'c-style'` for `//` and `/* */`, or
|
|
452
|
+
`'cdn-style'` for `#` and `/ /`. It has no effect when `preserveComments` is
|
|
453
|
+
`true` (verbatim wins); explicitly set `comments: 'strip'` (or leave
|
|
454
|
+
both options unset) to drop comments entirely.
|
|
455
|
+
|
|
456
|
+
```ts
|
|
457
|
+
CBOR.format(text, { indent: 2, comments: 'c-style' });
|
|
458
|
+
// '{\n "a": 1\n} // trailing comment'
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
Only effective when `indent` enables pretty-printing: single-line output
|
|
462
|
+
strips all comments regardless, since line comments can only be terminated
|
|
463
|
+
by a newline.
|
|
464
|
+
|
|
446
465
|
### Preserve blank lines
|
|
447
466
|
|
|
448
467
|
By default, `CBOR.format()` drops blank lines between array/map entries (and
|
|
@@ -702,8 +721,8 @@ console.log(text);
|
|
|
702
721
|
|
|
703
722
|
## String Concatenation and Indefinite-Length Strings
|
|
704
723
|
|
|
705
|
-
The `t1` / `b1` / `ilbs` / `ilts`
|
|
706
|
-
draft-ietf-cbor-edn-literals-
|
|
724
|
+
The `t1` / `b1` / `ilbs` / `ilts` app-extensions from
|
|
725
|
+
draft-ietf-cbor-edn-literals-27 (§3.5 / §3.6) are enabled by default.
|
|
707
726
|
|
|
708
727
|
`t1<<...>>` and `b1<<...>>` join (text or byte) string arguments from left to
|
|
709
728
|
right into a single text string (`t1`) or byte string (`b1`). Arguments may
|
|
@@ -713,11 +732,11 @@ also be ellipses (`...`) to elide parts of a string.
|
|
|
713
732
|
import { CBOR } from '@cbortech/cbor';
|
|
714
733
|
|
|
715
734
|
const text = CBOR.fromCDN('t1<<"Hello ", "world">>');
|
|
716
|
-
console.log(text.toCDN({
|
|
735
|
+
console.log(text.toCDN({ appPrefix: false }));
|
|
717
736
|
// "Hello world"
|
|
718
737
|
|
|
719
738
|
const bytes = CBOR.fromCDN("b1<<'Hello ', h'776f726c64'>>");
|
|
720
|
-
console.log(bytes.toCDN({
|
|
739
|
+
console.log(bytes.toCDN({ appPrefix: false }));
|
|
721
740
|
// 'Hello world'
|
|
722
741
|
```
|
|
723
742
|
|
|
@@ -730,29 +749,81 @@ documents; this library keeps accepting the legacy syntax on input.
|
|
|
730
749
|
import { CBOR } from '@cbortech/cbor';
|
|
731
750
|
|
|
732
751
|
const v = CBOR.fromCDN("ilbs<<'Hello ', 'world'>>");
|
|
733
|
-
console.log(v.toCDN({
|
|
752
|
+
console.log(v.toCDN({ appPrefix: false }));
|
|
734
753
|
// (_ 'Hello ','world')
|
|
735
754
|
```
|
|
736
755
|
|
|
756
|
+
### Emitting `t1`/`b1`/`ilbs`/`ilts` notation
|
|
757
|
+
|
|
758
|
+
Parsing already accepts `t1`/`b1`/`ilbs`/`ilts` notation, but by default
|
|
759
|
+
`toCDN()`/`CBOR.format()` never emit it on their own: a preserved
|
|
760
|
+
concatenation (`preserveConcatenation`) still renders as `+`, and an
|
|
761
|
+
indefinite-length string still renders as the legacy `(_ ...)` streamstring
|
|
762
|
+
form. `modernConcat` and `modernStreamSyntax` opt into emitting the draft-27
|
|
763
|
+
notation instead — both default to `false` (the legacy syntax), and both fall
|
|
764
|
+
back to it when `appPrefix` is `false`.
|
|
765
|
+
|
|
766
|
+
```ts
|
|
767
|
+
import { CBOR } from '@cbortech/cbor';
|
|
768
|
+
|
|
769
|
+
CBOR.format('"a" + "b"', {
|
|
770
|
+
indent: 2,
|
|
771
|
+
preserveConcatenation: true,
|
|
772
|
+
modernConcat: true,
|
|
773
|
+
});
|
|
774
|
+
// t1<<"a", "b">>
|
|
775
|
+
|
|
776
|
+
CBOR.format('(_ "a", "b")', { modernStreamSyntax: true });
|
|
777
|
+
// ilts<<"a","b">>
|
|
778
|
+
```
|
|
779
|
+
|
|
780
|
+
`modernConcat` also applies within a `...` elision chain (§5.2), rendering
|
|
781
|
+
`"a" + ... + "b"` as `t1<<"a", ..., "b">>` — unlike plain concatenation, this
|
|
782
|
+
happens regardless of `preserveConcatenation`, since an elision chain has no
|
|
783
|
+
single-literal collapsed form to fall back to in the first place.
|
|
784
|
+
|
|
785
|
+
> [!NOTE]
|
|
786
|
+
> Neither option converts `t1`/`b1`/`ilbs`/`ilts` source back to the
|
|
787
|
+
> legacy notation: a value parsed from `t1<<...>>` (or `ilbs<<...>>`, etc.)
|
|
788
|
+
> keeps that exact spelling on output regardless of `modernConcat` /
|
|
789
|
+
> `modernStreamSyntax` — as long as `appPrefix` is not `false`,
|
|
790
|
+
> `encodingIndicators` is `'auto'` (both defaults), and the source is either
|
|
791
|
+
> single-line or being rendered with `indent` enabled. `encodingIndicators:
|
|
792
|
+
'always'`/`'never'` or `appPrefix: false` still normalize it like any
|
|
793
|
+
> other app-string value (e.g. `t1<<"a", "b">>` becomes `"ab"_i`
|
|
794
|
+
> under `encodingIndicators: 'always'`), and a multi-line source falls back
|
|
795
|
+
> to normalized output in single-line mode (that layout can't be reproduced
|
|
796
|
+
> without `indent`):
|
|
797
|
+
>
|
|
798
|
+
> ```ts
|
|
799
|
+
> CBOR.format('t1<<\n "a",\n "b"\n>>');
|
|
800
|
+
> // '"ab"' — falls back: multi-line source, no `indent`
|
|
801
|
+
> CBOR.format('t1<<\n "a",\n "b"\n>>', { indent: 2 });
|
|
802
|
+
> // 't1<<\n "a",\n "b"\n>>' — kept verbatim
|
|
803
|
+
> ```
|
|
804
|
+
>
|
|
805
|
+
> Both options only affect how a value reconstructed from a `+` chain or a
|
|
806
|
+
> `(_ ...)` chunk list is _newly_ rendered.
|
|
807
|
+
|
|
737
808
|
> [!NOTE]
|
|
738
|
-
> The identifiers `t1` and `b1` are explicitly provisional in draft-
|
|
809
|
+
> The identifiers `t1` and `b1` are explicitly provisional in draft-27 and
|
|
739
810
|
> may be renamed by the CBOR working group.
|
|
740
811
|
|
|
741
812
|
## float
|
|
742
813
|
|
|
743
814
|
Interprets a hex bit-pattern as an IEEE 754 floating-point value
|
|
744
|
-
(draft-ietf-cbor-edn-literals-
|
|
815
|
+
(draft-ietf-cbor-edn-literals-27 §3.8). Enabled by default.
|
|
745
816
|
|
|
746
817
|
```ts
|
|
747
818
|
import { CBOR } from '@cbortech/cbor';
|
|
748
819
|
|
|
749
820
|
const v = CBOR.fromCDN("float'7e00'");
|
|
750
|
-
console.log(v.toCDN({
|
|
821
|
+
console.log(v.toCDN({ appPrefix: false }));
|
|
751
822
|
// NaN
|
|
752
823
|
|
|
753
824
|
// Interpret bytes as float bits
|
|
754
825
|
const v2 = CBOR.fromCDN("float<<h'3f800000'>>");
|
|
755
|
-
console.log(v2.toCDN({
|
|
826
|
+
console.log(v2.toCDN({ appPrefix: false }));
|
|
756
827
|
// 1.0_2
|
|
757
828
|
```
|
|
758
829
|
|
|
@@ -766,7 +837,7 @@ default. Import what you need and pass it through the `extensions` option.
|
|
|
766
837
|
Byte-string literals using [RFC 4648](https://www.rfc-editor.org/rfc/rfc4648)
|
|
767
838
|
Base32 encoding. These prefixes are described in §8 of
|
|
768
839
|
[RFC 8949](https://www.rfc-editor.org/rfc/rfc8949) and also mentioned in
|
|
769
|
-
[draft-ietf-cbor-edn-literals](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/
|
|
840
|
+
[draft-ietf-cbor-edn-literals](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/27/).
|
|
770
841
|
|
|
771
842
|
- `b32` — §6 Base32 (`A–Z 2–7` alphabet)
|
|
772
843
|
- `h32` — §7 Base32Hex (`0–9 A–V` alphabet)
|
|
@@ -775,11 +846,11 @@ Base32 encoding. These prefixes are described in §8 of
|
|
|
775
846
|
import { CBOR, b32, h32 } from '@cbortech/cbor';
|
|
776
847
|
|
|
777
848
|
const v1 = CBOR.fromCDN("b32'AEBAGBA'", { extensions: [b32] });
|
|
778
|
-
console.log(v1.toCDN({
|
|
849
|
+
console.log(v1.toCDN({ appPrefix: false }));
|
|
779
850
|
// h'01020304'
|
|
780
851
|
|
|
781
852
|
const v2 = CBOR.fromCDN("h32'00P00'", { extensions: [h32] });
|
|
782
|
-
console.log(v2.toCDN({
|
|
853
|
+
console.log(v2.toCDN({ appPrefix: false }));
|
|
783
854
|
// h'003200'
|
|
784
855
|
```
|
|
785
856
|
|
|
@@ -793,24 +864,24 @@ identical CBOR bytes and returns the first item. This extension is described in
|
|
|
793
864
|
import { CBOR, same } from '@cbortech/cbor';
|
|
794
865
|
|
|
795
866
|
const v = CBOR.fromCDN("same<<h'0102', h'0102'>>", { extensions: [same] });
|
|
796
|
-
console.log(v.toCDN({
|
|
867
|
+
console.log(v.toCDN({ appPrefix: false }));
|
|
797
868
|
// h'0102'
|
|
798
869
|
|
|
799
870
|
// A single-item sequence always passes
|
|
800
871
|
const v2 = CBOR.fromCDN('same<<42>>', { extensions: [same] });
|
|
801
|
-
console.log(v2.toCDN({
|
|
872
|
+
console.log(v2.toCDN({ appPrefix: false }));
|
|
802
873
|
// 42
|
|
803
874
|
```
|
|
804
875
|
|
|
805
876
|
---
|
|
806
877
|
|
|
807
|
-
Additional
|
|
878
|
+
Additional app-extensions are published as separate packages. Install
|
|
808
879
|
the ones you need and pass them through the `extensions` option.
|
|
809
880
|
|
|
810
881
|
### hash
|
|
811
882
|
|
|
812
|
-
`hash` is an
|
|
813
|
-
[draft-ietf-cbor-edn-literals](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/
|
|
883
|
+
`hash` is an app-extension defined in §3.4 of
|
|
884
|
+
[draft-ietf-cbor-edn-literals](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/27/).
|
|
814
885
|
It represents cryptographic hash values in the form `hash'algorithm:value'`.
|
|
815
886
|
Because it requires an external cryptographic library, it is provided separately
|
|
816
887
|
as [@cbortech/hash-extension](https://www.npmjs.com/package/@cbortech/hash-extension).
|
|
@@ -835,7 +906,7 @@ const digest = cbor.parse(
|
|
|
835
906
|
|
|
836
907
|
### uuid
|
|
837
908
|
|
|
838
|
-
`uuid` is a library-specific
|
|
909
|
+
`uuid` is a library-specific app-extension, provided separately as
|
|
839
910
|
[@cbortech/uuid-extension](https://www.npmjs.com/package/@cbortech/uuid-extension).
|
|
840
911
|
|
|
841
912
|
```bash
|
|
@@ -854,7 +925,7 @@ const id = cbor.parse("uuid'550e8400-e29b-41d4-a716-446655440000'");
|
|
|
854
925
|
|
|
855
926
|
### set / map
|
|
856
927
|
|
|
857
|
-
`SET` and `MAP` are library-specific
|
|
928
|
+
`SET` and `MAP` are library-specific app-extensions for tagged Set and
|
|
858
929
|
Map values. They are provided together as
|
|
859
930
|
[@cbortech/set-map-extensions](https://www.npmjs.com/package/@cbortech/set-map-extensions).
|
|
860
931
|
`SET<<[...]>>` produces CBOR tag 258 over an array, and `MAP<<{...}>>` produces
|
|
@@ -1112,9 +1183,11 @@ types).
|
|
|
1112
1183
|
|
|
1113
1184
|
- CBOR
|
|
1114
1185
|
- [RFC 8949](https://www.rfc-editor.org/rfc/rfc8949)
|
|
1186
|
+
- CBOR Sequences
|
|
1187
|
+
- [RFC 8742](https://www.rfc-editor.org/rfc/rfc8742)
|
|
1115
1188
|
- CDN (CBOR-EDN)
|
|
1116
1189
|
- [draft-ietf-cbor-edn-literals-25](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/25/)
|
|
1117
|
-
- [draft-ietf-cbor-edn-literals-
|
|
1190
|
+
- [draft-ietf-cbor-edn-literals-27](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/27/)
|
|
1118
1191
|
- CDDL
|
|
1119
1192
|
- [RFC 8610](https://www.rfc-editor.org/rfc/rfc8610)
|
|
1120
1193
|
- [RFC 9682](https://www.rfc-editor.org/rfc/rfc9682)
|
|
@@ -1122,7 +1195,7 @@ types).
|
|
|
1122
1195
|
|
|
1123
1196
|
Implementation notes:
|
|
1124
1197
|
|
|
1125
|
-
- CDN follows draft-
|
|
1198
|
+
- CDN follows draft-27 while retaining draft-25's `(_ ...)` streamstring syntax
|
|
1126
1199
|
and `+` string-concatenation syntax.
|
|
1127
1200
|
- CDDL implements every RFC 8610 control operator, plus RFC 9165's `.plus`,
|
|
1128
1201
|
`.cat`, and `.feature`.
|
|
@@ -21,6 +21,28 @@ export declare class CborAppSeqResult extends CborItem {
|
|
|
21
21
|
readonly ednSource: string;
|
|
22
22
|
constructor(inner: CborItem, ednSource: string);
|
|
23
23
|
get _containsCdnContainer(): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Same approach as `CborTag`: tokenize this wrapper's own `_toCDN()`
|
|
26
|
+
* output rather than delegating to `this.inner._isMultiWordText()`.
|
|
27
|
+
* Delegating to `this.inner` was tried and found wrong: for
|
|
28
|
+
* `ilbs<<h'68656c6c6f20776f726c64'>>`, the chunk's raw bytes decode to
|
|
29
|
+
* printable "hello world", so `this.inner`'s own semantic check reports
|
|
30
|
+
* it as multi-word — but the *actual* rendering is the preserved
|
|
31
|
+
* `ilbs<<...>>` app-sequence spelling, where that chunk appears as a
|
|
32
|
+
* `h'...'` literal, never as decoded text; the semantic prediction and
|
|
33
|
+
* the real output disagree. Tokenizing `this._toCDN()` directly sees
|
|
34
|
+
* whichever one actually happens: the preserved `ednSource` verbatim
|
|
35
|
+
* (`isMultiWordRenderedLiteral` peels the `prefix<<...>>` wrapper and
|
|
36
|
+
* checks each item under the loose rule, same as `<<...>>` — a
|
|
37
|
+
* multi-word text item like `ilts<<"two words">>` still always counts,
|
|
38
|
+
* a prefixed-literal item like `ilbs<<h'00'>>` does not) or, in the
|
|
39
|
+
* 'always'/'never' `encodingIndicators` modes, a pure passthrough to
|
|
40
|
+
* `this.inner._toCDN()` with no extra wrapping (any node needing that to
|
|
41
|
+
* be caught, like a self-disqualifying `CborIndefiniteByteString`, has
|
|
42
|
+
* already produced a `\n` in that string, which the caller's own
|
|
43
|
+
* `s.includes('\n')` check picks up independently either way).
|
|
44
|
+
*/
|
|
45
|
+
_isMultiWordText(options: ToCDNOptions | undefined, strict?: boolean): boolean;
|
|
24
46
|
_encodeTo(writer: CborWriter, options?: ToCBOROptions): void;
|
|
25
47
|
_toCDN(options: ToCDNOptions | undefined, depth: number): string;
|
|
26
48
|
_toJS(options?: ToJSOptions): unknown;
|