@cbortech/cbor 0.26.5 → 0.26.7
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 +239 -34
- package/README.md +242 -38
- package/dist/ast/CborByteString.d.ts +14 -0
- package/dist/ast/CborEllipsis.d.ts +94 -2
- package/dist/ast/CborFloat.d.ts +10 -0
- package/dist/ast/CborItem.d.ts +93 -4
- package/dist/ast/CborNint.d.ts +9 -0
- package/dist/ast/CborSimple.d.ts +11 -2
- package/dist/ast/CborTag.d.ts +8 -0
- package/dist/ast/CborTextString.d.ts +20 -0
- package/dist/ast/CborUint.d.ts +8 -0
- package/dist/ast/index.cjs +1 -1
- package/dist/ast/index.js +2 -2
- package/dist/cbor.d.ts +8 -0
- package/dist/cddl/ast.d.ts +196 -0
- package/dist/cddl/controls.d.ts +28 -0
- package/dist/cddl/equal.d.ts +19 -0
- package/dist/cddl/errors.d.ts +91 -0
- package/dist/cddl/index.cjs +3 -0
- package/dist/cddl/index.cjs.map +1 -0
- package/dist/cddl/index.d.ts +52 -0
- package/dist/cddl/index.js +67 -0
- package/dist/cddl/index.js.map +1 -0
- package/dist/cddl/parser.d.ts +13 -0
- package/dist/cddl/position.d.ts +13 -0
- package/dist/cddl/prelude.d.ts +5 -0
- package/dist/cddl/schema.d.ts +90 -0
- package/dist/cddl/tokenizer.d.ts +138 -0
- package/dist/cddl/validator.d.ts +30 -0
- package/dist/cddl/writer.d.ts +23 -0
- package/dist/cdn/serialize-utils.d.ts +186 -8
- package/dist/extensions/dt.d.ts +3 -0
- package/dist/extensions/types.d.ts +31 -9
- package/dist/index.cjs +4 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +97 -107
- package/dist/index.js.map +1 -1
- package/dist/mapEntries-D2NyeCX3.cjs +17 -0
- package/dist/mapEntries-D2NyeCX3.cjs.map +1 -0
- package/dist/{mapEntries-Clr-oNtQ.js → mapEntries-DxrDre2P.js} +1498 -991
- package/dist/mapEntries-DxrDre2P.js.map +1 -0
- package/dist/schema-Bofmsptw.js +1977 -0
- package/dist/schema-Bofmsptw.js.map +1 -0
- package/dist/schema-t_bdPk8_.cjs +63 -0
- package/dist/schema-t_bdPk8_.cjs.map +1 -0
- package/dist/types.d.ts +258 -7
- package/dist/utils/base64.d.ts +12 -0
- package/package.json +24 -7
- package/dist/mapEntries-6hy7UgeN.cjs +0 -15
- package/dist/mapEntries-6hy7UgeN.cjs.map +0 -1
- package/dist/mapEntries-Clr-oNtQ.js.map +0 -1
package/README.ja.md
CHANGED
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
[](./LICENSE)
|
|
7
7
|

|
|
8
8
|
|
|
9
|
-
[CBOR](#準拠している仕様)、[CDN (CBOR-EDN)](#準拠している仕様)、JavaScript
|
|
10
|
-
|
|
11
|
-

|
|
9
|
+
[CBOR](#準拠している仕様)、[CDN (CBOR-EDN)](#準拠している仕様)、JavaScript 値の相互変換に加え、[CDDL](#準拠している仕様) スキーマのパース・整形・検証に対応する TypeScript ライブラリです。
|
|
12
10
|
|
|
13
11
|
プレイグラウンドを **https://cbor.tech/cbor/** で公開しています。
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
このパッケージは CBOR ファサードに加えて、tooling や extension 向けに CDN、CDDL、AST の各 entrypoint を公開します。
|
|
16
16
|
低レベルのパーサー、エンコーダー内部は、ドキュメント上の公開 API には含めていません。
|
|
17
17
|
|
|
18
18
|
## インストール
|
|
@@ -72,6 +72,20 @@ console.log(value);
|
|
|
72
72
|
// { hello: 'world', n: 42 }
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
+
### CDDL で検証する
|
|
76
|
+
|
|
77
|
+
CDDLスキーマをコンパイルし、CBOR バイト列、CDN テキスト、`CborItem` AST を検証できます。
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import { CDDL } from '@cbortech/cbor/cddl';
|
|
81
|
+
|
|
82
|
+
const schema = CDDL.compile('point = { x: int, y: int }');
|
|
83
|
+
const result = schema.validate('{"x": 12, "y": -3}');
|
|
84
|
+
|
|
85
|
+
console.log(result.valid);
|
|
86
|
+
// true
|
|
87
|
+
```
|
|
88
|
+
|
|
75
89
|
### CBOR Sequence から JavaScript へ
|
|
76
90
|
|
|
77
91
|
`decodeSeq` は連結された CBOR item を CBOR Sequence として読み取り、各 item を JavaScript 値として yield します。
|
|
@@ -316,6 +330,46 @@ CBOR.format('`\\d+`', { preserveRawString: true });
|
|
|
316
330
|
// '`\\d+`'
|
|
317
331
|
```
|
|
318
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
|
+
### 数値リテラルの表記を保持する
|
|
353
|
+
|
|
354
|
+
デフォルトでは、`CBOR.format()` は整数・浮動小数点数リテラルを正規化します。
|
|
355
|
+
16進数・8進数・2進数の整数(`0xff`、`0o377`、`0b101`)は10進数に変換され、
|
|
356
|
+
末尾のゼロや冗長なエンコーディング指標のサフィックス(`1.50`、`1.5_1`)は
|
|
357
|
+
省略されます。`preserveNumberFormat` を指定すると、これらのリテラルを元の
|
|
358
|
+
CDN ソース表記のまま再出力します。`intFormat` / `floatFormat` より優先され
|
|
359
|
+
ます。CDN テキストからパースされたリテラルにのみ効果があり、`CBOR.from()`
|
|
360
|
+
で構築した値や CBOR バイト列からデコードした値には効果がありません(通常
|
|
361
|
+
どおりの整形になります)。
|
|
362
|
+
|
|
363
|
+
```ts
|
|
364
|
+
import { CBOR } from '@cbortech/cbor';
|
|
365
|
+
|
|
366
|
+
CBOR.format('{"a": 0xff, "b": 1.50}');
|
|
367
|
+
// '{"a":255,"b":1.5}'
|
|
368
|
+
|
|
369
|
+
CBOR.format('{"a": 0xff, "b": 1.50}', { preserveNumberFormat: true });
|
|
370
|
+
// '{"a":0xff,"b":1.50}'
|
|
371
|
+
```
|
|
372
|
+
|
|
319
373
|
### `+` による文字列連結を保持する
|
|
320
374
|
|
|
321
375
|
注意: `+` による文字列連結構文は draft-26 で削除されました。この節は legacy
|
|
@@ -350,6 +404,110 @@ CBOR.format("h'68' + b64'aQ'", {
|
|
|
350
404
|
// b64'aQ'
|
|
351
405
|
```
|
|
352
406
|
|
|
407
|
+
### application-string / -sequence 記法を保持する
|
|
408
|
+
|
|
409
|
+
一部の組み込み拡張(`dt`/`DT`、`ip`/`IP`)は同じ値に対して `prefix'...'`
|
|
410
|
+
(application string)、`` prefix`...` ``(backtick application string)、
|
|
411
|
+
`prefix<<...>>`(application sequence)、生のタグリテラル(`N(...)`)の
|
|
412
|
+
いずれの記法もサポートしていますが、デフォルトでは `CBOR.format()` を呼ぶ
|
|
413
|
+
たびに解決済みの値から `prefix'...'` を再生成します。そのため
|
|
414
|
+
`` DT`1969-07-21T02:56:16Z` `` も `DT<<'1969-07-21T02:56:16Z'>>` も、生の
|
|
415
|
+
タグ記法 `1(1749772800)` さえも、すべて `DT'...'` 記法に正規化され、さら
|
|
416
|
+
に非正規な `DT'...'` の表記(例えば `Z` の代わりに `+00:00` を使った場合
|
|
417
|
+
など)も書き換えられます。`preserveAppSequence` を指定すると、実際に使わ
|
|
418
|
+
れていた表記のまま保持します。`appStrings: false` を同時に指定した場合は
|
|
419
|
+
効果がありません(どちらにせよ元の表記に関わらず生のタグ記法になるため)。
|
|
420
|
+
これらの記法からパースされていない値にも効果はありません。
|
|
421
|
+
|
|
422
|
+
```ts
|
|
423
|
+
import { CBOR } from '@cbortech/cbor';
|
|
424
|
+
|
|
425
|
+
CBOR.format('1(1749772800)');
|
|
426
|
+
// "DT'2025-06-13T00:00:00Z'"
|
|
427
|
+
|
|
428
|
+
CBOR.format('1(1749772800)', { preserveAppSequence: true });
|
|
429
|
+
// "1(1749772800)"
|
|
430
|
+
|
|
431
|
+
CBOR.format("DT<<'1969-07-21T02:56:16Z'>>", { preserveAppSequence: true });
|
|
432
|
+
// "DT<<'1969-07-21T02:56:16Z'>>"
|
|
433
|
+
|
|
434
|
+
CBOR.format('DT`1969-07-21T02:56:16Z`', { preserveAppSequence: true });
|
|
435
|
+
// "DT`1969-07-21T02:56:16Z`"
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
### 空行を保持する
|
|
439
|
+
|
|
440
|
+
デフォルトでは、`CBOR.format()` は配列・マップの要素間(および `(_ ...)`
|
|
441
|
+
のチャンク間)の空行を再シリアライズ時に取り除きます。`preserveBlankLines`
|
|
442
|
+
を指定すると、元のソースでその要素の前のどこかに空行があった場合、要素の
|
|
443
|
+
直前に空行を 1 行だけ再出力します。要素をパラグラフのようにまとめる元の
|
|
444
|
+
見た目を、フォーマット後も保てます。元の空行が何行連続していても、出力
|
|
445
|
+
されるのは常に 1 行だけです。判定は要素の位置だけに基づいており、
|
|
446
|
+
`preserveComments` は不要で、コメントを出力するかどうかにも影響されません。
|
|
447
|
+
`indent` を指定して整形出力する場合のみ効果があり、空行を保持する
|
|
448
|
+
コンテナは `inlineLeafContainers` が有効でも常に 1 要素 1 行で出力されます。
|
|
449
|
+
`preserveAll` にも含まれます。
|
|
450
|
+
|
|
451
|
+
```ts
|
|
452
|
+
import { CBOR } from '@cbortech/cbor';
|
|
453
|
+
|
|
454
|
+
const src = `[
|
|
455
|
+
1,
|
|
456
|
+
2,
|
|
457
|
+
|
|
458
|
+
3
|
|
459
|
+
]`;
|
|
460
|
+
|
|
461
|
+
CBOR.format(src, { indent: 2 });
|
|
462
|
+
// [
|
|
463
|
+
// 1,
|
|
464
|
+
// 2,
|
|
465
|
+
// 3
|
|
466
|
+
// ]
|
|
467
|
+
|
|
468
|
+
CBOR.format(src, { indent: 2, preserveBlankLines: true });
|
|
469
|
+
// [
|
|
470
|
+
// 1,
|
|
471
|
+
// 2,
|
|
472
|
+
//
|
|
473
|
+
// 3
|
|
474
|
+
// ]
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### 変更を最小限にとどめてフォーマットする
|
|
478
|
+
|
|
479
|
+
`preserveAll` を指定すると、すべての `preserve*` 系オプションが一括で
|
|
480
|
+
有効になります。たとえばエディタの保存時フォーマットのように、空白・
|
|
481
|
+
インデントだけを変更し、ほとんどのリテラルの元の表記には手を加えずに
|
|
482
|
+
CDN テキストを整形できます(bignum だけは例外です。上記の
|
|
483
|
+
`preserveNumberFormat` の説明を参照してください)。個別のオプションを
|
|
484
|
+
明示的に指定した場合(`false` も含む)は、そちらが `preserveAll` より
|
|
485
|
+
優先されます。
|
|
486
|
+
|
|
487
|
+
```ts
|
|
488
|
+
import { CBOR } from '@cbortech/cbor';
|
|
489
|
+
|
|
490
|
+
CBOR.format('{"a":0xff,"b":1.5_1,"c":b64\'aGk=\'}', {
|
|
491
|
+
indent: 2,
|
|
492
|
+
preserveAll: true,
|
|
493
|
+
});
|
|
494
|
+
// {
|
|
495
|
+
// "a": 0xff,
|
|
496
|
+
// "b": 1.5_1,
|
|
497
|
+
// "c": b64'aGk='
|
|
498
|
+
// }
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
`CBOR.format()` は内部で `fromCDN()` と `toCDN()` の両方に同じオプション
|
|
502
|
+
を渡すため、このオプション一つで済みます。両者を別々に呼び出す場合は、
|
|
503
|
+
コメントはパース時に取り込んでおく必要があるため、`fromCDN()` 側にも
|
|
504
|
+
`preserveAll`(または `preserveComments`)を指定してください。
|
|
505
|
+
|
|
506
|
+
```ts
|
|
507
|
+
const item = CBOR.fromCDN(text, { preserveAll: true });
|
|
508
|
+
item.toCDN({ preserveAll: true, indent: 2 });
|
|
509
|
+
```
|
|
510
|
+
|
|
353
511
|
### CBOR / CDN / hex dump のバリデーション
|
|
354
512
|
|
|
355
513
|
`validate` は入力の well-formedness と validity を、例外を投げずにチェックします。
|
|
@@ -865,12 +1023,63 @@ const lenient = tokenizeLenient('[1, "ab');
|
|
|
865
1023
|
インスタンスで、`offset`・`line`・`column`、判明している場合は `endOffset` を
|
|
866
1024
|
保持します。
|
|
867
1025
|
|
|
1026
|
+
## CDDL
|
|
1027
|
+
|
|
1028
|
+
`@cbortech/cbor/cddl` サブパスには、CDDL のパーサ・コンパイラ・バリデータが
|
|
1029
|
+
入っています。CDDL は CBOR データ構造を記述するスキーマ言語です。
|
|
1030
|
+
コンパイル済みスキーマで、CBOR バイト列・CDN テキスト・`CborItem` AST を
|
|
1031
|
+
検証できます。
|
|
1032
|
+
|
|
1033
|
+
```ts
|
|
1034
|
+
import { CDDL } from '@cbortech/cbor/cddl';
|
|
1035
|
+
|
|
1036
|
+
const schema = CDDL.compile('point = { x: int, y: int }');
|
|
1037
|
+
|
|
1038
|
+
console.log(schema.validate('{"x": 12, "y": -3}').valid);
|
|
1039
|
+
// true
|
|
1040
|
+
```
|
|
1041
|
+
|
|
1042
|
+
検証は throw せず結果オブジェクトを返し、失敗時は入力内のパスと入力・
|
|
1043
|
+
スキーマ双方のソース位置を報告します。既定では最初のルールを使い、`rule`
|
|
1044
|
+
で別の非 generic 型ルールを指定できます。このほか `features`、`maxDepth`、
|
|
1045
|
+
`maxSteps` を指定できます。
|
|
1046
|
+
|
|
1047
|
+
[RFC 8610](https://www.rfc-editor.org/rfc/rfc8610) の全 control operator と、
|
|
1048
|
+
[RFC 9165](https://www.rfc-editor.org/rfc/rfc9165) の `.plus`、`.cat`、
|
|
1049
|
+
`.feature` を実装しています。`.feature` の許可名は `features` オプションで
|
|
1050
|
+
指定します。`.abnf` などの未対応演算子は `result.warnings` に報告され、
|
|
1051
|
+
制約なしで判定されます。
|
|
1052
|
+
|
|
1053
|
+
メインの `CBOR` facade でも、`cddl` オプションにコンパイル済みスキーマ
|
|
1054
|
+
または CDDL ソーステキストを渡して検証できます。
|
|
1055
|
+
|
|
1056
|
+
```ts
|
|
1057
|
+
import { CBOR } from '@cbortech/cbor';
|
|
1058
|
+
|
|
1059
|
+
const value = CBOR.parse('{"x": 12, "y": -3}', {
|
|
1060
|
+
cddl: 'point = { x: int, y: int }',
|
|
1061
|
+
});
|
|
1062
|
+
// { x: 12, y: -3 }
|
|
1063
|
+
```
|
|
1064
|
+
|
|
1065
|
+
`parse`・`decode`・`encode` などは不一致時に `CddlMismatchError` を throw
|
|
1066
|
+
します。`CBOR.validate()` は代わりに `result.cddlErrors` へ収集します。
|
|
1067
|
+
検証オプションは `cddlValidationOptions` で渡せます。`cddl` は
|
|
1068
|
+
`new CBOR({ cddl: … })` のようにインスタンスのデフォルトにもできます。
|
|
1069
|
+
|
|
1070
|
+
`CDDL.compile()` は `CddlSyntaxError` または `CddlSemanticError` を throw
|
|
1071
|
+
します。`{ strict: false }` を指定すると、意味上の問題を
|
|
1072
|
+
`schema.warnings` に収集できます。コンパイル済みスキーマは
|
|
1073
|
+
`schema.format()` で整形できます。同じサブパスから `tokenize`、
|
|
1074
|
+
`tokenizeLenient`、`schema.ast`、`schema.rules` も利用できます。
|
|
1075
|
+
|
|
868
1076
|
## 公開 API
|
|
869
1077
|
|
|
870
1078
|
ドキュメント化している公開 export は次のとおりです。
|
|
871
1079
|
|
|
872
1080
|
- `CBOR`
|
|
873
1081
|
- `CdnSyntaxError`
|
|
1082
|
+
- `CddlMismatchError`(`cddl` オプションが throw。[CDDL](#cddl) 節を参照)
|
|
874
1083
|
|
|
875
1084
|
`CBOR` ファサードからは次にもアクセスできます。
|
|
876
1085
|
|
|
@@ -884,38 +1093,34 @@ const lenient = tokenizeLenient('[1, "ab');
|
|
|
884
1093
|
(`tokenize`, `tokenizeLenient`, `Token`, `TokenType`, `EdnComment`)に、
|
|
885
1094
|
AST ノードクラスは `@cbortech/cbor/ast` にあります。
|
|
886
1095
|
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
- [CBOR, RFC 8949](https://www.rfc-editor.org/rfc/rfc8949)
|
|
892
|
-
- [Concise Diagnostic Notation (CDN), draft-ietf-cbor-edn-literals-25](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/25/)
|
|
1096
|
+
CDDL コンパイラは `@cbortech/cbor/cddl`
|
|
1097
|
+
(`CDDL`, `CddlSchema`, `CddlSyntaxError`, `CddlSemanticError`,
|
|
1098
|
+
`CddlMismatchError`, `tokenize`, `tokenizeLenient`, CDDL AST 型)に
|
|
1099
|
+
あります。
|
|
893
1100
|
|
|
894
|
-
|
|
895
|
-
[draft -26](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/26/)
|
|
896
|
-
の一部仕様も先行して取り込んでいます。
|
|
897
|
-
|
|
898
|
-
- 文字列連結 extension `t1` / `b1`(§3.4)
|
|
899
|
-
- 不定長文字列 extension `ilbs` / `ilts`(§3.5)
|
|
900
|
-
- `float` extension のデフォルト有効化(§3.7)
|
|
901
|
-
- draft-26 の raw string 規則(§2.5.4): 終端デリミタは開始デリミタと
|
|
902
|
-
同数のバッククォートに限られ、スペース除去規則がすべてのデリミタ長に
|
|
903
|
-
適用されます
|
|
904
|
-
|
|
905
|
-
draft -26 で削除された `+` による文字列連結構文と、非推奨となった
|
|
906
|
-
`(_ ...)` streamstring 構文は、引き続き受理します。CDN は Internet-Draft
|
|
907
|
-
として策定中の仕様であり、今後も変更される可能性がある点に注意して
|
|
908
|
-
ください(たとえば extension 名 `t1` / `b1` は暫定とされています)。
|
|
909
|
-
|
|
910
|
-
CDN は、CBOR データを人間が読み書きしやすいテキストとして表現するための記法です。
|
|
911
|
-
サンプル、テストベクター、デバッグ、fixture、設定ファイルに近い用途など、CBOR のバイト列をそのまま扱うと読みにくい場面で役立ちます。
|
|
912
|
-
|
|
913
|
-
通常の配列、マップ、文字列、数値、真偽値、null は JSON に近い見た目で書けます。
|
|
914
|
-
一方で、CBOR 固有の byte string、tag、simple value、不定長 item、文字列以外の map key、
|
|
915
|
-
`dt'2026-05-06T00:00:00Z'` のような application literal も表現できます。
|
|
1101
|
+
## 準拠している仕様
|
|
916
1102
|
|
|
917
|
-
|
|
918
|
-
|
|
1103
|
+
- CBOR
|
|
1104
|
+
- [RFC 8949](https://www.rfc-editor.org/rfc/rfc8949)
|
|
1105
|
+
- CDN (CBOR-EDN)
|
|
1106
|
+
- [draft-ietf-cbor-edn-literals-25](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/25/)
|
|
1107
|
+
- [draft-ietf-cbor-edn-literals-26](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/26/)
|
|
1108
|
+
- CDDL
|
|
1109
|
+
- [RFC 8610](https://www.rfc-editor.org/rfc/rfc8610)
|
|
1110
|
+
- [RFC 9682](https://www.rfc-editor.org/rfc/rfc9682)
|
|
1111
|
+
- [RFC 9165](https://www.rfc-editor.org/rfc/rfc9165)
|
|
1112
|
+
|
|
1113
|
+
補足:
|
|
1114
|
+
|
|
1115
|
+
- CDN は draft-26 に準拠しつつ、draft-25 の `(_ ...)` streamstring 構文と
|
|
1116
|
+
`+` による文字列連結構文も引き続きサポートしています。
|
|
1117
|
+
- CDDL は RFC 8610 のすべての control operator と、RFC 9165 の `.plus`、
|
|
1118
|
+
`.cat`、`.feature` をサポートしています。
|
|
1119
|
+
- RFC 9682 の更新内容である文字列リテラル文法(`\u{...}` を含む)、構文上の
|
|
1120
|
+
空データモデル(ルールなしのモデルはコンパイル時に意味エラー)、非リテラルの
|
|
1121
|
+
`#6.<type>` / `#7.<type>` head number に対応しています。コメントの `PCHAR`
|
|
1122
|
+
検証、単独 CR の改行、EOF で終わるコメントは、collected ABNF よりも意図的に
|
|
1123
|
+
寛容に受理します。
|
|
919
1124
|
|
|
920
1125
|
## ライセンス
|
|
921
1126
|
|
package/README.md
CHANGED
|
@@ -7,14 +7,15 @@
|
|
|
7
7
|

|
|
8
8
|
|
|
9
9
|
TypeScript library for converting between [CBOR](#specifications),
|
|
10
|
-
[CDN (CBOR-EDN)](#specifications), and JavaScript values
|
|
11
|
-
|
|
12
|
-

|
|
10
|
+
[CDN (CBOR-EDN)](#specifications), and JavaScript values, plus parsing,
|
|
11
|
+
formatting, and validation for [CDDL](#specifications) schemas.
|
|
13
12
|
|
|
14
13
|
A live playground is available at **https://cbor.tech/cbor/**.
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+

|
|
16
|
+
|
|
17
|
+
This package exposes the CBOR facade plus separate CDN, CDDL, and AST
|
|
18
|
+
entrypoints for tooling and extensions. Lower-level parser and encoder internals
|
|
18
19
|
are not part of the documented public API.
|
|
19
20
|
|
|
20
21
|
## Install
|
|
@@ -75,6 +76,21 @@ console.log(value);
|
|
|
75
76
|
// { hello: 'world', n: 42 }
|
|
76
77
|
```
|
|
77
78
|
|
|
79
|
+
### Validate with CDDL
|
|
80
|
+
|
|
81
|
+
Compile a CDDL schema and validate CBOR bytes, CDN text, or a `CborItem` AST
|
|
82
|
+
against it:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import { CDDL } from '@cbortech/cbor/cddl';
|
|
86
|
+
|
|
87
|
+
const schema = CDDL.compile('point = { x: int, y: int }');
|
|
88
|
+
const result = schema.validate('{"x": 12, "y": -3}');
|
|
89
|
+
|
|
90
|
+
console.log(result.valid);
|
|
91
|
+
// true
|
|
92
|
+
```
|
|
93
|
+
|
|
78
94
|
### CBOR Sequence to JavaScript values
|
|
79
95
|
|
|
80
96
|
`decodeSeq` reads concatenated CBOR items as a CBOR Sequence and yields each item as a JavaScript value.
|
|
@@ -320,6 +336,45 @@ CBOR.format('`\\d+`', { preserveRawString: true });
|
|
|
320
336
|
// '`\\d+`'
|
|
321
337
|
```
|
|
322
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
|
+
### Preserve number literal spelling
|
|
359
|
+
|
|
360
|
+
By default, `CBOR.format()` normalizes integer and floating-point literals:
|
|
361
|
+
hex/octal/binary integers (`0xff`, `0o377`, `0b101`) become decimal, trailing
|
|
362
|
+
zeros and redundant encoding-indicator suffixes (`1.50`, `1.5_1`) are
|
|
363
|
+
dropped. `preserveNumberFormat` re-emits these literals using their original
|
|
364
|
+
CDN source spelling instead, taking precedence over `intFormat` /
|
|
365
|
+
`floatFormat`. It only affects literals parsed from CDN text — values built
|
|
366
|
+
with `CBOR.from()` or decoded from CBOR bytes always use normal formatting.
|
|
367
|
+
|
|
368
|
+
```ts
|
|
369
|
+
import { CBOR } from '@cbortech/cbor';
|
|
370
|
+
|
|
371
|
+
CBOR.format('{"a": 0xff, "b": 1.50}');
|
|
372
|
+
// '{"a":255,"b":1.5}'
|
|
373
|
+
|
|
374
|
+
CBOR.format('{"a": 0xff, "b": 1.50}', { preserveNumberFormat: true });
|
|
375
|
+
// '{"a":0xff,"b":1.50}'
|
|
376
|
+
```
|
|
377
|
+
|
|
323
378
|
### Preserve `+` string concatenation
|
|
324
379
|
|
|
325
380
|
Note: `+` string concatenation was removed in draft-26. This section is for
|
|
@@ -356,6 +411,110 @@ CBOR.format("h'68' + b64'aQ'", {
|
|
|
356
411
|
// b64'aQ'
|
|
357
412
|
```
|
|
358
413
|
|
|
414
|
+
### Preserve application-string/-sequence notation
|
|
415
|
+
|
|
416
|
+
Some built-in extensions (`dt`/`DT`, `ip`/`IP`) support `prefix'...'`
|
|
417
|
+
(application string), `` prefix`...` `` (backtick application string),
|
|
418
|
+
`prefix<<...>>` (application sequence), and a raw tag literal (`N(...)`)
|
|
419
|
+
notation for the same value, and by default regenerate `prefix'...'` from
|
|
420
|
+
the resolved value on every `CBOR.format()` call — so
|
|
421
|
+
`` DT`1969-07-21T02:56:16Z` ``, `DT<<'1969-07-21T02:56:16Z'>>`, and even the
|
|
422
|
+
raw tag form `1(1749772800)` all normalize to `DT'...'` notation, and a
|
|
423
|
+
non-canonical `DT'...'` spelling (e.g. a `+00:00` offset instead of `Z`)
|
|
424
|
+
gets rewritten too. `preserveAppSequence` keeps the original spelling
|
|
425
|
+
instead — whichever form was used. It has no effect when
|
|
426
|
+
`appStrings: false` is also set (raw tag notation is used either way
|
|
427
|
+
regardless of the original spelling), or on values not parsed from one of
|
|
428
|
+
these forms.
|
|
429
|
+
|
|
430
|
+
```ts
|
|
431
|
+
import { CBOR } from '@cbortech/cbor';
|
|
432
|
+
|
|
433
|
+
CBOR.format('1(1749772800)');
|
|
434
|
+
// "DT'2025-06-13T00:00:00Z'"
|
|
435
|
+
|
|
436
|
+
CBOR.format('1(1749772800)', { preserveAppSequence: true });
|
|
437
|
+
// "1(1749772800)"
|
|
438
|
+
|
|
439
|
+
CBOR.format("DT<<'1969-07-21T02:56:16Z'>>", { preserveAppSequence: true });
|
|
440
|
+
// "DT<<'1969-07-21T02:56:16Z'>>"
|
|
441
|
+
|
|
442
|
+
CBOR.format('DT`1969-07-21T02:56:16Z`', { preserveAppSequence: true });
|
|
443
|
+
// "DT`1969-07-21T02:56:16Z`"
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
### Preserve blank lines
|
|
447
|
+
|
|
448
|
+
By default, `CBOR.format()` drops blank lines between array/map entries (and
|
|
449
|
+
`(_ ...)` chunks) when re-serializing. `preserveBlankLines` re-emits a single
|
|
450
|
+
blank line above an entry that had one anywhere before it in the source, so
|
|
451
|
+
paragraph-like groupings of entries survive a reformat — at most one blank
|
|
452
|
+
line per gap, regardless of how many were originally there. Detection is
|
|
453
|
+
based on entry positions alone: it does not require `preserveComments` and is
|
|
454
|
+
unaffected by whether comments are emitted. Only effective when `indent`
|
|
455
|
+
enables pretty-printing; a container with a preserved blank line is always
|
|
456
|
+
rendered one entry per line, even under `inlineLeafContainers`. Included in
|
|
457
|
+
`preserveAll`.
|
|
458
|
+
|
|
459
|
+
```ts
|
|
460
|
+
import { CBOR } from '@cbortech/cbor';
|
|
461
|
+
|
|
462
|
+
const src = `[
|
|
463
|
+
1,
|
|
464
|
+
2,
|
|
465
|
+
|
|
466
|
+
3
|
|
467
|
+
]`;
|
|
468
|
+
|
|
469
|
+
CBOR.format(src, { indent: 2 });
|
|
470
|
+
// [
|
|
471
|
+
// 1,
|
|
472
|
+
// 2,
|
|
473
|
+
// 3
|
|
474
|
+
// ]
|
|
475
|
+
|
|
476
|
+
CBOR.format(src, { indent: 2, preserveBlankLines: true });
|
|
477
|
+
// [
|
|
478
|
+
// 1,
|
|
479
|
+
// 2,
|
|
480
|
+
//
|
|
481
|
+
// 3
|
|
482
|
+
// ]
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### Format with minimal changes
|
|
486
|
+
|
|
487
|
+
`preserveAll` turns on every `preserve*` option at once, to reformat CDN
|
|
488
|
+
text — e.g. when reformatting on save in an editor — touching only
|
|
489
|
+
whitespace/indentation and leaving most literals' original spelling
|
|
490
|
+
untouched (bignums are the one exception; see `preserveNumberFormat`
|
|
491
|
+
above). An explicitly-set individual option (including `false`) still wins
|
|
492
|
+
over `preserveAll`.
|
|
493
|
+
|
|
494
|
+
```ts
|
|
495
|
+
import { CBOR } from '@cbortech/cbor';
|
|
496
|
+
|
|
497
|
+
CBOR.format('{"a":0xff,"b":1.5_1,"c":b64\'aGk=\'}', {
|
|
498
|
+
indent: 2,
|
|
499
|
+
preserveAll: true,
|
|
500
|
+
});
|
|
501
|
+
// {
|
|
502
|
+
// "a": 0xff,
|
|
503
|
+
// "b": 1.5_1,
|
|
504
|
+
// "c": b64'aGk='
|
|
505
|
+
// }
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
`CBOR.format()` passes the same options to both `fromCDN()` and `toCDN()`
|
|
509
|
+
internally, so this one option is enough. Calling them separately needs
|
|
510
|
+
`preserveAll` (or `preserveComments`) on the `fromCDN()` side too, since
|
|
511
|
+
comments must be captured while parsing to be re-emittable later:
|
|
512
|
+
|
|
513
|
+
```ts
|
|
514
|
+
const item = CBOR.fromCDN(text, { preserveAll: true });
|
|
515
|
+
item.toCDN({ preserveAll: true, indent: 2 });
|
|
516
|
+
```
|
|
517
|
+
|
|
359
518
|
### Validate CBOR / CDN / hex dump
|
|
360
519
|
|
|
361
520
|
`validate` checks input for well-formedness and validity without throwing.
|
|
@@ -874,12 +1033,63 @@ Syntax errors thrown by `fromCDN`/`parse`/`tokenize` are `CdnSyntaxError`
|
|
|
874
1033
|
instances (a `SyntaxError` subclass, also exported from the main entry) and
|
|
875
1034
|
carry `offset`, `line`, `column`, and — where known — `endOffset`.
|
|
876
1035
|
|
|
1036
|
+
## CDDL
|
|
1037
|
+
|
|
1038
|
+
The `@cbortech/cbor/cddl` subpath contains a parser, compiler, and validator for
|
|
1039
|
+
CDDL, the schema language for describing CBOR data structures. A compiled schema
|
|
1040
|
+
validates CBOR bytes, CDN text, or a `CborItem` AST:
|
|
1041
|
+
|
|
1042
|
+
```ts
|
|
1043
|
+
import { CDDL } from '@cbortech/cbor/cddl';
|
|
1044
|
+
|
|
1045
|
+
const schema = CDDL.compile('point = { x: int, y: int }');
|
|
1046
|
+
|
|
1047
|
+
console.log(schema.validate('{"x": 12, "y": -3}').valid);
|
|
1048
|
+
// true
|
|
1049
|
+
```
|
|
1050
|
+
|
|
1051
|
+
Validation returns a result object rather than throwing. Failures include the
|
|
1052
|
+
instance path and source offsets for both the input and schema. Validation uses
|
|
1053
|
+
the first rule by default; pass `rule` to select another non-generic type rule.
|
|
1054
|
+
Options also include `features`, `maxDepth`, and `maxSteps`.
|
|
1055
|
+
|
|
1056
|
+
All control operators from
|
|
1057
|
+
[RFC 8610](https://www.rfc-editor.org/rfc/rfc8610) are implemented, along with
|
|
1058
|
+
[RFC 9165](https://www.rfc-editor.org/rfc/rfc9165)'s `.plus`, `.cat`, and
|
|
1059
|
+
`.feature`. Enable `.feature` names with the `features` validation option.
|
|
1060
|
+
Unsupported operators such as `.abnf` are reported in `result.warnings` and
|
|
1061
|
+
matched without their constraint.
|
|
1062
|
+
|
|
1063
|
+
The main `CBOR` facade also accepts a compiled schema or CDDL source text through
|
|
1064
|
+
the `cddl` option:
|
|
1065
|
+
|
|
1066
|
+
```ts
|
|
1067
|
+
import { CBOR } from '@cbortech/cbor';
|
|
1068
|
+
|
|
1069
|
+
const value = CBOR.parse('{"x": 12, "y": -3}', {
|
|
1070
|
+
cddl: 'point = { x: int, y: int }',
|
|
1071
|
+
});
|
|
1072
|
+
// { x: 12, y: -3 }
|
|
1073
|
+
```
|
|
1074
|
+
|
|
1075
|
+
Throwing methods such as `parse`, `decode`, and `encode` throw
|
|
1076
|
+
`CddlMismatchError` on a mismatch; `CBOR.validate()` instead collects failures
|
|
1077
|
+
in `result.cddlErrors`. Pass validator options through `cddlValidationOptions`,
|
|
1078
|
+
or set `cddl` as an instance default with `new CBOR({ cddl: … })`.
|
|
1079
|
+
|
|
1080
|
+
`CDDL.compile()` throws `CddlSyntaxError` or `CddlSemanticError`; use
|
|
1081
|
+
`{ strict: false }` to collect semantic issues in `schema.warnings` instead.
|
|
1082
|
+
Compiled schemas can be formatted with `schema.format()`. The subpath also
|
|
1083
|
+
exports `tokenize`, `tokenizeLenient`, and a typed rule AST through `schema.ast`
|
|
1084
|
+
and `schema.rules`.
|
|
1085
|
+
|
|
877
1086
|
## Public API
|
|
878
1087
|
|
|
879
1088
|
The documented public exports are:
|
|
880
1089
|
|
|
881
1090
|
- `CBOR`
|
|
882
1091
|
- `CdnSyntaxError`
|
|
1092
|
+
- `CddlMismatchError` (thrown by the `cddl` option; see [CDDL](#cddl))
|
|
883
1093
|
|
|
884
1094
|
The `CBOR` facade also exposes:
|
|
885
1095
|
|
|
@@ -893,41 +1103,35 @@ Lower-level CDN tokenization lives in `@cbortech/cbor/cdn`
|
|
|
893
1103
|
(`tokenize`, `tokenizeLenient`, `Token`, `TokenType`, `EdnComment`),
|
|
894
1104
|
and AST node classes in `@cbortech/cbor/ast`.
|
|
895
1105
|
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
- [CBOR, RFC 8949](https://www.rfc-editor.org/rfc/rfc8949)
|
|
901
|
-
- [Concise Diagnostic Notation (CDN), draft-ietf-cbor-edn-literals-25](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/25/)
|
|
1106
|
+
The CDDL compiler lives in `@cbortech/cbor/cddl`
|
|
1107
|
+
(`CDDL`, `CddlSchema`, `CddlSyntaxError`, `CddlSemanticError`,
|
|
1108
|
+
`CddlMismatchError`, `tokenize`, `tokenizeLenient`, and the CDDL AST
|
|
1109
|
+
types).
|
|
902
1110
|
|
|
903
|
-
|
|
904
|
-
[draft -26](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/26/):
|
|
905
|
-
|
|
906
|
-
- the `t1` / `b1` string-concatenation extensions (§3.4)
|
|
907
|
-
- the `ilbs` / `ilts` indefinite-length string extensions (§3.5)
|
|
908
|
-
- the `float` extension as a default extension (§3.7)
|
|
909
|
-
- the draft-26 raw-string delimiter and trimming rules (§2.5.4): the closing
|
|
910
|
-
delimiter must have exactly as many backquotes as the opening one, and the
|
|
911
|
-
space-trimming rule applies to all delimiter lengths
|
|
912
|
-
|
|
913
|
-
The legacy `+` string-concatenation syntax (removed in draft -26) and the
|
|
914
|
-
`(_ ...)` streamstring syntax (deprecated in draft -26) are still accepted.
|
|
915
|
-
Note that the CDN specification is still an Internet-Draft and may continue
|
|
916
|
-
to change (for example, the extension names `t1` and `b1` are explicitly
|
|
917
|
-
provisional).
|
|
918
|
-
|
|
919
|
-
CDN is a human-readable text notation for CBOR data. It is useful for
|
|
920
|
-
examples, test vectors, debugging, fixtures, and configuration-like files where
|
|
921
|
-
raw CBOR bytes would be hard to read.
|
|
922
|
-
|
|
923
|
-
It looks similar to JSON for ordinary arrays, maps, strings, numbers, booleans,
|
|
924
|
-
and null values, but it can also represent CBOR-specific features such as byte
|
|
925
|
-
strings, tags, simple values, indefinite-length items, non-string map keys, and
|
|
926
|
-
application literals like `dt'2026-05-06T00:00:00Z'`.
|
|
1111
|
+
## Specifications
|
|
927
1112
|
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
1113
|
+
- CBOR
|
|
1114
|
+
- [RFC 8949](https://www.rfc-editor.org/rfc/rfc8949)
|
|
1115
|
+
- CDN (CBOR-EDN)
|
|
1116
|
+
- [draft-ietf-cbor-edn-literals-25](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/25/)
|
|
1117
|
+
- [draft-ietf-cbor-edn-literals-26](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/26/)
|
|
1118
|
+
- CDDL
|
|
1119
|
+
- [RFC 8610](https://www.rfc-editor.org/rfc/rfc8610)
|
|
1120
|
+
- [RFC 9682](https://www.rfc-editor.org/rfc/rfc9682)
|
|
1121
|
+
- [RFC 9165](https://www.rfc-editor.org/rfc/rfc9165)
|
|
1122
|
+
|
|
1123
|
+
Implementation notes:
|
|
1124
|
+
|
|
1125
|
+
- CDN follows draft-26 while retaining draft-25's `(_ ...)` streamstring syntax
|
|
1126
|
+
and `+` string-concatenation syntax.
|
|
1127
|
+
- CDDL implements every RFC 8610 control operator, plus RFC 9165's `.plus`,
|
|
1128
|
+
`.cat`, and `.feature`.
|
|
1129
|
+
- The RFC 9682 updates are implemented: its string-literal grammar (including
|
|
1130
|
+
`\u{...}`), empty data models at the syntax layer (a model with no rules is
|
|
1131
|
+
still a semantic error when compiled), and non-literal `#6.<type>` /
|
|
1132
|
+
`#7.<type>` head numbers. Comment `PCHAR` validation, bare CR line endings,
|
|
1133
|
+
and comments ending at EOF are intentionally accepted more leniently than the
|
|
1134
|
+
collected ABNF.
|
|
931
1135
|
|
|
932
1136
|
## License
|
|
933
1137
|
|