@cbortech/cbor 0.26.4 → 0.26.6
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 +103 -38
- package/README.md +108 -42
- package/dist/ast/CborAppSeqResult.d.ts +3 -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 +3 -2
- package/dist/extensions/types.d.ts +3 -1
- package/dist/index.cjs +7 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +104 -77
- package/dist/index.js.map +1 -1
- package/dist/mapEntries-BhMlCwYo.cjs +15 -0
- package/dist/mapEntries-BhMlCwYo.cjs.map +1 -0
- package/dist/{mapEntries-hyNVtz5Z.js → mapEntries-Czxt-cmd.js} +458 -456
- package/dist/mapEntries-Czxt-cmd.js.map +1 -0
- package/dist/schema-BmGsaEaW.cjs +63 -0
- package/dist/schema-BmGsaEaW.cjs.map +1 -0
- package/dist/schema-BxkgvUY6.js +1977 -0
- package/dist/schema-BxkgvUY6.js.map +1 -0
- package/dist/types.d.ts +107 -4
- package/dist/utils/base64.d.ts +12 -0
- package/package.json +23 -6
- package/dist/mapEntries-DDJxbotH.cjs +0 -15
- package/dist/mapEntries-DDJxbotH.cjs.map +0 -1
- package/dist/mapEntries-hyNVtz5Z.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 します。
|
|
@@ -324,7 +338,8 @@ syntax を扱う場合のためのものです。
|
|
|
324
338
|
デフォルトでは、`CBOR.format()` は `+` による文字列連結を 1 つのリテラルに
|
|
325
339
|
結合します。`preserveConcatenation` を指定すると、テキスト文字列・バイト文字列とも
|
|
326
340
|
元の連結の区切りを保持します。`preserveByteString` を併用すると、バイト文字列の
|
|
327
|
-
|
|
341
|
+
各パートの元の表記も保持されます。分割オプションと同様に `indent` で整形出力が
|
|
342
|
+
有効な場合のみ効果があり、1 行出力では常に 1 つのリテラルに結合されます。
|
|
328
343
|
|
|
329
344
|
分割オプションとの関係: 文字列の中身が CDN としてパースできる場合は `splitCdn` が
|
|
330
345
|
`preserveConcatenation` より優先されます。`splitNewline` は共存し、保持した各パートに
|
|
@@ -336,14 +351,17 @@ import { CBOR } from '@cbortech/cbor';
|
|
|
336
351
|
CBOR.format('"a" + "b"');
|
|
337
352
|
// '"ab"'
|
|
338
353
|
|
|
339
|
-
CBOR.format('"a" + "b"', { preserveConcatenation: true });
|
|
340
|
-
//
|
|
354
|
+
CBOR.format('"a" + "b"', { indent: 2, preserveConcatenation: true });
|
|
355
|
+
// "a" +
|
|
356
|
+
// "b"
|
|
341
357
|
|
|
342
358
|
CBOR.format("h'68' + b64'aQ'", {
|
|
359
|
+
indent: 2,
|
|
343
360
|
preserveConcatenation: true,
|
|
344
361
|
preserveByteString: true,
|
|
345
362
|
});
|
|
346
|
-
//
|
|
363
|
+
// h'68' +
|
|
364
|
+
// b64'aQ'
|
|
347
365
|
```
|
|
348
366
|
|
|
349
367
|
### CBOR / CDN / hex dump のバリデーション
|
|
@@ -861,12 +879,63 @@ const lenient = tokenizeLenient('[1, "ab');
|
|
|
861
879
|
インスタンスで、`offset`・`line`・`column`、判明している場合は `endOffset` を
|
|
862
880
|
保持します。
|
|
863
881
|
|
|
882
|
+
## CDDL
|
|
883
|
+
|
|
884
|
+
`@cbortech/cbor/cddl` サブパスには、CDDL のパーサ・コンパイラ・バリデータが
|
|
885
|
+
入っています。CDDL は CBOR データ構造を記述するスキーマ言語です。
|
|
886
|
+
コンパイル済みスキーマで、CBOR バイト列・CDN テキスト・`CborItem` AST を
|
|
887
|
+
検証できます。
|
|
888
|
+
|
|
889
|
+
```ts
|
|
890
|
+
import { CDDL } from '@cbortech/cbor/cddl';
|
|
891
|
+
|
|
892
|
+
const schema = CDDL.compile('point = { x: int, y: int }');
|
|
893
|
+
|
|
894
|
+
console.log(schema.validate('{"x": 12, "y": -3}').valid);
|
|
895
|
+
// true
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
検証は throw せず結果オブジェクトを返し、失敗時は入力内のパスと入力・
|
|
899
|
+
スキーマ双方のソース位置を報告します。既定では最初のルールを使い、`rule`
|
|
900
|
+
で別の非 generic 型ルールを指定できます。このほか `features`、`maxDepth`、
|
|
901
|
+
`maxSteps` を指定できます。
|
|
902
|
+
|
|
903
|
+
[RFC 8610](https://www.rfc-editor.org/rfc/rfc8610) の全 control operator と、
|
|
904
|
+
[RFC 9165](https://www.rfc-editor.org/rfc/rfc9165) の `.plus`、`.cat`、
|
|
905
|
+
`.feature` を実装しています。`.feature` の許可名は `features` オプションで
|
|
906
|
+
指定します。`.abnf` などの未対応演算子は `result.warnings` に報告され、
|
|
907
|
+
制約なしで判定されます。
|
|
908
|
+
|
|
909
|
+
メインの `CBOR` facade でも、`cddl` オプションにコンパイル済みスキーマ
|
|
910
|
+
または CDDL ソーステキストを渡して検証できます。
|
|
911
|
+
|
|
912
|
+
```ts
|
|
913
|
+
import { CBOR } from '@cbortech/cbor';
|
|
914
|
+
|
|
915
|
+
const value = CBOR.parse('{"x": 12, "y": -3}', {
|
|
916
|
+
cddl: 'point = { x: int, y: int }',
|
|
917
|
+
});
|
|
918
|
+
// { x: 12, y: -3 }
|
|
919
|
+
```
|
|
920
|
+
|
|
921
|
+
`parse`・`decode`・`encode` などは不一致時に `CddlMismatchError` を throw
|
|
922
|
+
します。`CBOR.validate()` は代わりに `result.cddlErrors` へ収集します。
|
|
923
|
+
検証オプションは `cddlValidationOptions` で渡せます。`cddl` は
|
|
924
|
+
`new CBOR({ cddl: … })` のようにインスタンスのデフォルトにもできます。
|
|
925
|
+
|
|
926
|
+
`CDDL.compile()` は `CddlSyntaxError` または `CddlSemanticError` を throw
|
|
927
|
+
します。`{ strict: false }` を指定すると、意味上の問題を
|
|
928
|
+
`schema.warnings` に収集できます。コンパイル済みスキーマは
|
|
929
|
+
`schema.format()` で整形できます。同じサブパスから `tokenize`、
|
|
930
|
+
`tokenizeLenient`、`schema.ast`、`schema.rules` も利用できます。
|
|
931
|
+
|
|
864
932
|
## 公開 API
|
|
865
933
|
|
|
866
934
|
ドキュメント化している公開 export は次のとおりです。
|
|
867
935
|
|
|
868
936
|
- `CBOR`
|
|
869
937
|
- `CdnSyntaxError`
|
|
938
|
+
- `CddlMismatchError`(`cddl` オプションが throw。[CDDL](#cddl) 節を参照)
|
|
870
939
|
|
|
871
940
|
`CBOR` ファサードからは次にもアクセスできます。
|
|
872
941
|
|
|
@@ -880,38 +949,34 @@ const lenient = tokenizeLenient('[1, "ab');
|
|
|
880
949
|
(`tokenize`, `tokenizeLenient`, `Token`, `TokenType`, `EdnComment`)に、
|
|
881
950
|
AST ノードクラスは `@cbortech/cbor/ast` にあります。
|
|
882
951
|
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
- [CBOR, RFC 8949](https://www.rfc-editor.org/rfc/rfc8949)
|
|
888
|
-
- [Concise Diagnostic Notation (CDN), draft-ietf-cbor-edn-literals-25](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/25/)
|
|
952
|
+
CDDL コンパイラは `@cbortech/cbor/cddl`
|
|
953
|
+
(`CDDL`, `CddlSchema`, `CddlSyntaxError`, `CddlSemanticError`,
|
|
954
|
+
`CddlMismatchError`, `tokenize`, `tokenizeLenient`, CDDL AST 型)に
|
|
955
|
+
あります。
|
|
889
956
|
|
|
890
|
-
|
|
891
|
-
[draft -26](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/26/)
|
|
892
|
-
の一部仕様も先行して取り込んでいます。
|
|
893
|
-
|
|
894
|
-
- 文字列連結 extension `t1` / `b1`(§3.4)
|
|
895
|
-
- 不定長文字列 extension `ilbs` / `ilts`(§3.5)
|
|
896
|
-
- `float` extension のデフォルト有効化(§3.7)
|
|
897
|
-
- draft-26 の raw string 規則(§2.5.4): 終端デリミタは開始デリミタと
|
|
898
|
-
同数のバッククォートに限られ、スペース除去規則がすべてのデリミタ長に
|
|
899
|
-
適用されます
|
|
900
|
-
|
|
901
|
-
draft -26 で削除された `+` による文字列連結構文と、非推奨となった
|
|
902
|
-
`(_ ...)` streamstring 構文は、引き続き受理します。CDN は Internet-Draft
|
|
903
|
-
として策定中の仕様であり、今後も変更される可能性がある点に注意して
|
|
904
|
-
ください(たとえば extension 名 `t1` / `b1` は暫定とされています)。
|
|
905
|
-
|
|
906
|
-
CDN は、CBOR データを人間が読み書きしやすいテキストとして表現するための記法です。
|
|
907
|
-
サンプル、テストベクター、デバッグ、fixture、設定ファイルに近い用途など、CBOR のバイト列をそのまま扱うと読みにくい場面で役立ちます。
|
|
908
|
-
|
|
909
|
-
通常の配列、マップ、文字列、数値、真偽値、null は JSON に近い見た目で書けます。
|
|
910
|
-
一方で、CBOR 固有の byte string、tag、simple value、不定長 item、文字列以外の map key、
|
|
911
|
-
`dt'2026-05-06T00:00:00Z'` のような application literal も表現できます。
|
|
957
|
+
## 準拠している仕様
|
|
912
958
|
|
|
913
|
-
|
|
914
|
-
|
|
959
|
+
- CBOR
|
|
960
|
+
- [RFC 8949](https://www.rfc-editor.org/rfc/rfc8949)
|
|
961
|
+
- CDN (CBOR-EDN)
|
|
962
|
+
- [draft-ietf-cbor-edn-literals-25](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/25/)
|
|
963
|
+
- [draft-ietf-cbor-edn-literals-26](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/26/)
|
|
964
|
+
- CDDL
|
|
965
|
+
- [RFC 8610](https://www.rfc-editor.org/rfc/rfc8610)
|
|
966
|
+
- [RFC 9682](https://www.rfc-editor.org/rfc/rfc9682)
|
|
967
|
+
- [RFC 9165](https://www.rfc-editor.org/rfc/rfc9165)
|
|
968
|
+
|
|
969
|
+
補足:
|
|
970
|
+
|
|
971
|
+
- CDN は draft-26 に準拠しつつ、draft-25 の `(_ ...)` streamstring 構文と
|
|
972
|
+
`+` による文字列連結構文も引き続きサポートしています。
|
|
973
|
+
- CDDL は RFC 8610 のすべての control operator と、RFC 9165 の `.plus`、
|
|
974
|
+
`.cat`、`.feature` をサポートしています。
|
|
975
|
+
- RFC 9682 の更新内容である文字列リテラル文法(`\u{...}` を含む)、構文上の
|
|
976
|
+
空データモデル(ルールなしのモデルはコンパイル時に意味エラー)、非リテラルの
|
|
977
|
+
`#6.<type>` / `#7.<type>` head number に対応しています。コメントの `PCHAR`
|
|
978
|
+
検証、単独 CR の改行、EOF で終わるコメントは、collected ABNF よりも意図的に
|
|
979
|
+
寛容に受理します。
|
|
915
980
|
|
|
916
981
|
## ライセンス
|
|
917
982
|
|
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.
|
|
@@ -328,7 +344,9 @@ handling legacy syntax.
|
|
|
328
344
|
By default, `CBOR.format()` joins `+` string concatenation into a single
|
|
329
345
|
literal. `preserveConcatenation` keeps the original part boundaries for both
|
|
330
346
|
text strings and byte strings; add `preserveByteString` to also keep the
|
|
331
|
-
original spelling of byte string parts.
|
|
347
|
+
original spelling of byte string parts. Like the split options, it only
|
|
348
|
+
takes effect when `indent` enables pretty-printing — single-line output
|
|
349
|
+
always joins the parts.
|
|
332
350
|
|
|
333
351
|
`preserveConcatenation` interacts with the split options: `splitCdn` takes
|
|
334
352
|
precedence when the string content parses as CDN, while `splitNewline`
|
|
@@ -341,14 +359,17 @@ import { CBOR } from '@cbortech/cbor';
|
|
|
341
359
|
CBOR.format('"a" + "b"');
|
|
342
360
|
// '"ab"'
|
|
343
361
|
|
|
344
|
-
CBOR.format('"a" + "b"', { preserveConcatenation: true });
|
|
345
|
-
//
|
|
362
|
+
CBOR.format('"a" + "b"', { indent: 2, preserveConcatenation: true });
|
|
363
|
+
// "a" +
|
|
364
|
+
// "b"
|
|
346
365
|
|
|
347
366
|
CBOR.format("h'68' + b64'aQ'", {
|
|
367
|
+
indent: 2,
|
|
348
368
|
preserveConcatenation: true,
|
|
349
369
|
preserveByteString: true,
|
|
350
370
|
});
|
|
351
|
-
//
|
|
371
|
+
// h'68' +
|
|
372
|
+
// b64'aQ'
|
|
352
373
|
```
|
|
353
374
|
|
|
354
375
|
### Validate CBOR / CDN / hex dump
|
|
@@ -869,12 +890,63 @@ Syntax errors thrown by `fromCDN`/`parse`/`tokenize` are `CdnSyntaxError`
|
|
|
869
890
|
instances (a `SyntaxError` subclass, also exported from the main entry) and
|
|
870
891
|
carry `offset`, `line`, `column`, and — where known — `endOffset`.
|
|
871
892
|
|
|
893
|
+
## CDDL
|
|
894
|
+
|
|
895
|
+
The `@cbortech/cbor/cddl` subpath contains a parser, compiler, and validator for
|
|
896
|
+
CDDL, the schema language for describing CBOR data structures. A compiled schema
|
|
897
|
+
validates CBOR bytes, CDN text, or a `CborItem` AST:
|
|
898
|
+
|
|
899
|
+
```ts
|
|
900
|
+
import { CDDL } from '@cbortech/cbor/cddl';
|
|
901
|
+
|
|
902
|
+
const schema = CDDL.compile('point = { x: int, y: int }');
|
|
903
|
+
|
|
904
|
+
console.log(schema.validate('{"x": 12, "y": -3}').valid);
|
|
905
|
+
// true
|
|
906
|
+
```
|
|
907
|
+
|
|
908
|
+
Validation returns a result object rather than throwing. Failures include the
|
|
909
|
+
instance path and source offsets for both the input and schema. Validation uses
|
|
910
|
+
the first rule by default; pass `rule` to select another non-generic type rule.
|
|
911
|
+
Options also include `features`, `maxDepth`, and `maxSteps`.
|
|
912
|
+
|
|
913
|
+
All control operators from
|
|
914
|
+
[RFC 8610](https://www.rfc-editor.org/rfc/rfc8610) are implemented, along with
|
|
915
|
+
[RFC 9165](https://www.rfc-editor.org/rfc/rfc9165)'s `.plus`, `.cat`, and
|
|
916
|
+
`.feature`. Enable `.feature` names with the `features` validation option.
|
|
917
|
+
Unsupported operators such as `.abnf` are reported in `result.warnings` and
|
|
918
|
+
matched without their constraint.
|
|
919
|
+
|
|
920
|
+
The main `CBOR` facade also accepts a compiled schema or CDDL source text through
|
|
921
|
+
the `cddl` option:
|
|
922
|
+
|
|
923
|
+
```ts
|
|
924
|
+
import { CBOR } from '@cbortech/cbor';
|
|
925
|
+
|
|
926
|
+
const value = CBOR.parse('{"x": 12, "y": -3}', {
|
|
927
|
+
cddl: 'point = { x: int, y: int }',
|
|
928
|
+
});
|
|
929
|
+
// { x: 12, y: -3 }
|
|
930
|
+
```
|
|
931
|
+
|
|
932
|
+
Throwing methods such as `parse`, `decode`, and `encode` throw
|
|
933
|
+
`CddlMismatchError` on a mismatch; `CBOR.validate()` instead collects failures
|
|
934
|
+
in `result.cddlErrors`. Pass validator options through `cddlValidationOptions`,
|
|
935
|
+
or set `cddl` as an instance default with `new CBOR({ cddl: … })`.
|
|
936
|
+
|
|
937
|
+
`CDDL.compile()` throws `CddlSyntaxError` or `CddlSemanticError`; use
|
|
938
|
+
`{ strict: false }` to collect semantic issues in `schema.warnings` instead.
|
|
939
|
+
Compiled schemas can be formatted with `schema.format()`. The subpath also
|
|
940
|
+
exports `tokenize`, `tokenizeLenient`, and a typed rule AST through `schema.ast`
|
|
941
|
+
and `schema.rules`.
|
|
942
|
+
|
|
872
943
|
## Public API
|
|
873
944
|
|
|
874
945
|
The documented public exports are:
|
|
875
946
|
|
|
876
947
|
- `CBOR`
|
|
877
948
|
- `CdnSyntaxError`
|
|
949
|
+
- `CddlMismatchError` (thrown by the `cddl` option; see [CDDL](#cddl))
|
|
878
950
|
|
|
879
951
|
The `CBOR` facade also exposes:
|
|
880
952
|
|
|
@@ -888,41 +960,35 @@ Lower-level CDN tokenization lives in `@cbortech/cbor/cdn`
|
|
|
888
960
|
(`tokenize`, `tokenizeLenient`, `Token`, `TokenType`, `EdnComment`),
|
|
889
961
|
and AST node classes in `@cbortech/cbor/ast`.
|
|
890
962
|
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
- [CBOR, RFC 8949](https://www.rfc-editor.org/rfc/rfc8949)
|
|
896
|
-
- [Concise Diagnostic Notation (CDN), draft-ietf-cbor-edn-literals-25](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/25/)
|
|
963
|
+
The CDDL compiler lives in `@cbortech/cbor/cddl`
|
|
964
|
+
(`CDDL`, `CddlSchema`, `CddlSyntaxError`, `CddlSemanticError`,
|
|
965
|
+
`CddlMismatchError`, `tokenize`, `tokenizeLenient`, and the CDDL AST
|
|
966
|
+
types).
|
|
897
967
|
|
|
898
|
-
|
|
899
|
-
[draft -26](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/26/):
|
|
900
|
-
|
|
901
|
-
- the `t1` / `b1` string-concatenation extensions (§3.4)
|
|
902
|
-
- the `ilbs` / `ilts` indefinite-length string extensions (§3.5)
|
|
903
|
-
- the `float` extension as a default extension (§3.7)
|
|
904
|
-
- the draft-26 raw-string delimiter and trimming rules (§2.5.4): the closing
|
|
905
|
-
delimiter must have exactly as many backquotes as the opening one, and the
|
|
906
|
-
space-trimming rule applies to all delimiter lengths
|
|
907
|
-
|
|
908
|
-
The legacy `+` string-concatenation syntax (removed in draft -26) and the
|
|
909
|
-
`(_ ...)` streamstring syntax (deprecated in draft -26) are still accepted.
|
|
910
|
-
Note that the CDN specification is still an Internet-Draft and may continue
|
|
911
|
-
to change (for example, the extension names `t1` and `b1` are explicitly
|
|
912
|
-
provisional).
|
|
913
|
-
|
|
914
|
-
CDN is a human-readable text notation for CBOR data. It is useful for
|
|
915
|
-
examples, test vectors, debugging, fixtures, and configuration-like files where
|
|
916
|
-
raw CBOR bytes would be hard to read.
|
|
917
|
-
|
|
918
|
-
It looks similar to JSON for ordinary arrays, maps, strings, numbers, booleans,
|
|
919
|
-
and null values, but it can also represent CBOR-specific features such as byte
|
|
920
|
-
strings, tags, simple values, indefinite-length items, non-string map keys, and
|
|
921
|
-
application literals like `dt'2026-05-06T00:00:00Z'`.
|
|
968
|
+
## Specifications
|
|
922
969
|
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
970
|
+
- CBOR
|
|
971
|
+
- [RFC 8949](https://www.rfc-editor.org/rfc/rfc8949)
|
|
972
|
+
- CDN (CBOR-EDN)
|
|
973
|
+
- [draft-ietf-cbor-edn-literals-25](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/25/)
|
|
974
|
+
- [draft-ietf-cbor-edn-literals-26](https://datatracker.ietf.org/doc/draft-ietf-cbor-edn-literals/26/)
|
|
975
|
+
- CDDL
|
|
976
|
+
- [RFC 8610](https://www.rfc-editor.org/rfc/rfc8610)
|
|
977
|
+
- [RFC 9682](https://www.rfc-editor.org/rfc/rfc9682)
|
|
978
|
+
- [RFC 9165](https://www.rfc-editor.org/rfc/rfc9165)
|
|
979
|
+
|
|
980
|
+
Implementation notes:
|
|
981
|
+
|
|
982
|
+
- CDN follows draft-26 while retaining draft-25's `(_ ...)` streamstring syntax
|
|
983
|
+
and `+` string-concatenation syntax.
|
|
984
|
+
- CDDL implements every RFC 8610 control operator, plus RFC 9165's `.plus`,
|
|
985
|
+
`.cat`, and `.feature`.
|
|
986
|
+
- The RFC 9682 updates are implemented: its string-literal grammar (including
|
|
987
|
+
`\u{...}`), empty data models at the syntax layer (a model with no rules is
|
|
988
|
+
still a semantic error when compiled), and non-literal `#6.<type>` /
|
|
989
|
+
`#7.<type>` head numbers. Comment `PCHAR` validation, bare CR line endings,
|
|
990
|
+
and comments ending at EOF are intentionally accepted more leniently than the
|
|
991
|
+
collected ABNF.
|
|
926
992
|
|
|
927
993
|
## License
|
|
928
994
|
|
|
@@ -9,6 +9,9 @@ import { CborWriter } from '../cbor/encode';
|
|
|
9
9
|
* stored source text verbatim. For `'always'` and `'never'`, it delegates to
|
|
10
10
|
* the resolved item so the option is applied recursively to every data item;
|
|
11
11
|
* preserving the source verbatim would leave nested indicators unchanged.
|
|
12
|
+
* In single-line output (no `indent`), a source spelling that spans multiple
|
|
13
|
+
* lines also delegates to the inner item, since it cannot be re-emitted
|
|
14
|
+
* without breaking the single-line guarantee.
|
|
12
15
|
*
|
|
13
16
|
* CBOR encoding and JS conversion always delegate to the inner item so the
|
|
14
17
|
* wrapper is fully transparent for those operations.
|
package/dist/ast/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../mapEntries-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../mapEntries-BhMlCwYo.cjs");exports.CborArray=e.E,exports.CborBigNint=e.v,exports.CborBigUint=e.y,exports.CborByteString=e.k,exports.CborEmbeddedCBOR=e.C,exports.CborFloat=e.j,exports.CborIndefiniteByteString=e.O,exports.CborIndefiniteTextString=e.D,exports.CborItem=e.F,exports.CborMap=e.T,exports.CborNint=e.N,exports.CborSimple=e.w,exports.CborTag=e.A,exports.CborTextString=e.g,exports.CborUint=e.P;
|
package/dist/ast/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as e, C as t, D as n, E as r,
|
|
2
|
-
export {
|
|
1
|
+
import { A as e, C as t, D as n, E as r, F as i, N as a, O as o, P as s, T as c, g as l, j as u, k as d, v as f, w as p, y as m } from "../mapEntries-Czxt-cmd.js";
|
|
2
|
+
export { r as CborArray, f as CborBigNint, m as CborBigUint, d as CborByteString, t as CborEmbeddedCBOR, u as CborFloat, o as CborIndefiniteByteString, n as CborIndefiniteTextString, i as CborItem, c as CborMap, a as CborNint, p as CborSimple, e as CborTag, l as CborTextString, s as CborUint };
|
package/dist/cbor.d.ts
CHANGED
|
@@ -177,6 +177,14 @@ export declare class CBOR {
|
|
|
177
177
|
* @example
|
|
178
178
|
* // CDN text input
|
|
179
179
|
* CBOR.validate('{"a": 1}', { type: 'cdn' });
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* // Schema validation with a compiled CDDL schema
|
|
183
|
+
* import { CDDL } from '@cbortech/cbor/cddl';
|
|
184
|
+
* const schema = CDDL.compile('person = { name: tstr, ? age: uint }');
|
|
185
|
+
* const result = CBOR.validate('{"name": "kudo"}', { type: 'cdn', cddl: schema });
|
|
186
|
+
* result.valid; // true
|
|
187
|
+
* result.cddlErrors; // []
|
|
180
188
|
*/
|
|
181
189
|
static validate(input: ArrayBufferView | ArrayBufferLike | string, options?: ValidateOptions): ValidateResult;
|
|
182
190
|
/**
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CDDL AST node definitions.
|
|
3
|
+
*
|
|
4
|
+
* Unlike the CBOR side (class-based CborItem nodes), the CDDL AST is a plain
|
|
5
|
+
* discriminated-union structure: nodes are produced by the parser, consumed
|
|
6
|
+
* by the compiler/writer (and, in a later phase, the validator), and never
|
|
7
|
+
* carry behavior of their own.
|
|
8
|
+
*
|
|
9
|
+
* All nodes carry `start`/`end` character offsets into the parsed source so
|
|
10
|
+
* diagnostics and editor tooling can point at exact ranges.
|
|
11
|
+
*/
|
|
12
|
+
export interface CddlNodeBase {
|
|
13
|
+
/** Character offset of the first character of this node in the source. */
|
|
14
|
+
start: number;
|
|
15
|
+
/** Character offset just past the last character of this node. */
|
|
16
|
+
end: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* rule = typename [genericparm] S assignt S type
|
|
20
|
+
* / groupname [genericparm] S assigng S grpent
|
|
21
|
+
*
|
|
22
|
+
* Both forms are parsed into the same shape: `body` is a group entry, which
|
|
23
|
+
* subsumes a plain type (an entry with no occurrence and no member key).
|
|
24
|
+
* Whether a rule is used as a type or as a group is resolved semantically at
|
|
25
|
+
* validation time, not at parse time.
|
|
26
|
+
*/
|
|
27
|
+
export interface CddlRule extends CddlNodeBase {
|
|
28
|
+
kind: 'rule';
|
|
29
|
+
name: string;
|
|
30
|
+
/** Generic parameter names from `name<A, B> = …`, if any. */
|
|
31
|
+
generics?: string[];
|
|
32
|
+
/** '=' defines; '/=' extends a type choice; '//=' extends a group choice. */
|
|
33
|
+
assign: '=' | '/=' | '//=';
|
|
34
|
+
body: CddlGroupEntry;
|
|
35
|
+
}
|
|
36
|
+
/** type = type1 *(S "/" S type1) — always wrapped, even for one alternative. */
|
|
37
|
+
export interface CddlType extends CddlNodeBase {
|
|
38
|
+
kind: 'type';
|
|
39
|
+
alternatives: CddlType1[];
|
|
40
|
+
}
|
|
41
|
+
/** type1 = type2 [S (rangeop / ctlop) S type2] */
|
|
42
|
+
export interface CddlType1 extends CddlNodeBase {
|
|
43
|
+
kind: 'type1';
|
|
44
|
+
target: CddlType2;
|
|
45
|
+
/** Present when a range or control operator follows the target. */
|
|
46
|
+
op?: {
|
|
47
|
+
kind: 'range';
|
|
48
|
+
inclusive: boolean;
|
|
49
|
+
} | {
|
|
50
|
+
kind: 'ctl';
|
|
51
|
+
name: string;
|
|
52
|
+
};
|
|
53
|
+
/** The right-hand operand; present exactly when `op` is present. */
|
|
54
|
+
controller?: CddlType2;
|
|
55
|
+
}
|
|
56
|
+
export type CddlType2 = CddlValue | CddlRef | CddlParenType | CddlMapType | CddlArrayType | CddlUnwrap | CddlEnum | CddlTagged | CddlMajor | CddlAny;
|
|
57
|
+
/** A literal value: number, text string, or byte string. */
|
|
58
|
+
export type CddlValue = CddlNodeBase & {
|
|
59
|
+
kind: 'value';
|
|
60
|
+
raw: string;
|
|
61
|
+
} & ({
|
|
62
|
+
type: 'int';
|
|
63
|
+
value: number | bigint;
|
|
64
|
+
} | {
|
|
65
|
+
type: 'float';
|
|
66
|
+
value: number;
|
|
67
|
+
} | {
|
|
68
|
+
type: 'text';
|
|
69
|
+
value: string;
|
|
70
|
+
} | {
|
|
71
|
+
type: 'bytes';
|
|
72
|
+
value: Uint8Array;
|
|
73
|
+
qualifier: '' | 'h' | 'b64';
|
|
74
|
+
});
|
|
75
|
+
/** typename [genericarg] — also used for groupname references. */
|
|
76
|
+
export interface CddlRef extends CddlNodeBase {
|
|
77
|
+
kind: 'ref';
|
|
78
|
+
name: string;
|
|
79
|
+
genericArgs?: CddlType1[];
|
|
80
|
+
}
|
|
81
|
+
/** "(" S type S ")" */
|
|
82
|
+
export interface CddlParenType extends CddlNodeBase {
|
|
83
|
+
kind: 'paren';
|
|
84
|
+
type: CddlType;
|
|
85
|
+
}
|
|
86
|
+
/** "{" S group S "}" */
|
|
87
|
+
export interface CddlMapType extends CddlNodeBase {
|
|
88
|
+
kind: 'map';
|
|
89
|
+
group: CddlGroup;
|
|
90
|
+
}
|
|
91
|
+
/** "[" S group S "]" */
|
|
92
|
+
export interface CddlArrayType extends CddlNodeBase {
|
|
93
|
+
kind: 'array';
|
|
94
|
+
group: CddlGroup;
|
|
95
|
+
}
|
|
96
|
+
/** "~" S typename [genericarg] */
|
|
97
|
+
export interface CddlUnwrap extends CddlNodeBase {
|
|
98
|
+
kind: 'unwrap';
|
|
99
|
+
ref: CddlRef;
|
|
100
|
+
}
|
|
101
|
+
/** "&" S "(" S group S ")" / "&" S groupname [genericarg] */
|
|
102
|
+
export interface CddlEnum extends CddlNodeBase {
|
|
103
|
+
kind: 'enum';
|
|
104
|
+
group: CddlGroup | CddlRef;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* "#" "6" ["." head-number] "(" S type S ")" — a tagged item.
|
|
108
|
+
* `tag` is a literal tag number, a `<type>` head-number expression
|
|
109
|
+
* (RFC 9682 §3.2), or absent for `#6(…)` (any tag number).
|
|
110
|
+
*/
|
|
111
|
+
export interface CddlTagged extends CddlNodeBase {
|
|
112
|
+
kind: 'tagged';
|
|
113
|
+
tag?: bigint | CddlType;
|
|
114
|
+
item: CddlType;
|
|
115
|
+
/**
|
|
116
|
+
* Source text of the '#6[.head]' part (e.g. '#6.0x10') when the tag number
|
|
117
|
+
* is literal or absent; lets the formatter preserve the number base.
|
|
118
|
+
*/
|
|
119
|
+
raw?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* "#" DIGIT ["." uint] and "#" "7" ["." head-number] — a major type,
|
|
123
|
+
* optionally constrained by additional information (or, for major 7, the
|
|
124
|
+
* simple value / float head-number, which may be a `<type>` expression).
|
|
125
|
+
*/
|
|
126
|
+
export interface CddlMajor extends CddlNodeBase {
|
|
127
|
+
kind: 'major';
|
|
128
|
+
major: number;
|
|
129
|
+
ai?: bigint | CddlType;
|
|
130
|
+
/**
|
|
131
|
+
* Source text of the '#N[.ai]' expression (e.g. '#7.0b11001') when the
|
|
132
|
+
* head-number is literal or absent; lets the formatter preserve the
|
|
133
|
+
* number base.
|
|
134
|
+
*/
|
|
135
|
+
raw?: string;
|
|
136
|
+
}
|
|
137
|
+
/** "#" — any data item. */
|
|
138
|
+
export interface CddlAny extends CddlNodeBase {
|
|
139
|
+
kind: 'any';
|
|
140
|
+
}
|
|
141
|
+
/** group = grpchoice *(S "//" S grpchoice); each choice is an entry list. */
|
|
142
|
+
export interface CddlGroup extends CddlNodeBase {
|
|
143
|
+
kind: 'group';
|
|
144
|
+
choices: CddlGroupEntry[][];
|
|
145
|
+
/**
|
|
146
|
+
* True when the final entry is followed by a comma (optcom). Commas
|
|
147
|
+
* between entries are cosmetic and not recorded, but the trailing comma is
|
|
148
|
+
* syntactically significant: `(int,)` is a group, never a parenthesized
|
|
149
|
+
* type, so e.g. it cannot be the root of a data model.
|
|
150
|
+
*/
|
|
151
|
+
trailingComma?: boolean;
|
|
152
|
+
}
|
|
153
|
+
export type CddlGroupEntry = CddlEntryValue | CddlEntryGroup;
|
|
154
|
+
/** grpent = [occur S] [memberkey S] type — also covers bare group references. */
|
|
155
|
+
export interface CddlEntryValue extends CddlNodeBase {
|
|
156
|
+
kind: 'entry';
|
|
157
|
+
occur?: CddlOccur;
|
|
158
|
+
memberKey?: CddlMemberKey;
|
|
159
|
+
value: CddlType;
|
|
160
|
+
}
|
|
161
|
+
/** grpent = [occur S] "(" S group S ")" — an inline parenthesized group. */
|
|
162
|
+
export interface CddlEntryGroup extends CddlNodeBase {
|
|
163
|
+
kind: 'entry-group';
|
|
164
|
+
occur?: CddlOccur;
|
|
165
|
+
group: CddlGroup;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* occur = [uint] "*" [uint] / "+" / "?"
|
|
169
|
+
* marker '*' covers `*`, `n*`, `*m`, and `n*m` via min/max.
|
|
170
|
+
*/
|
|
171
|
+
export interface CddlOccur extends CddlNodeBase {
|
|
172
|
+
kind: 'occur';
|
|
173
|
+
marker: '?' | '+' | '*';
|
|
174
|
+
min?: number;
|
|
175
|
+
max?: number;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* memberkey = type1 S ["^" S] "=>"
|
|
179
|
+
* / bareword S ":"
|
|
180
|
+
* / value S ":"
|
|
181
|
+
*
|
|
182
|
+
* `cut` is true for the ':' forms (implicit cut, RFC 8610 §3.5.4) and for
|
|
183
|
+
* the explicit `^ =>` form.
|
|
184
|
+
*/
|
|
185
|
+
export type CddlMemberKey = CddlNodeBase & {
|
|
186
|
+
cut: boolean;
|
|
187
|
+
} & ({
|
|
188
|
+
kind: 'type1';
|
|
189
|
+
key: CddlType1;
|
|
190
|
+
} | {
|
|
191
|
+
kind: 'bareword';
|
|
192
|
+
key: string;
|
|
193
|
+
} | {
|
|
194
|
+
kind: 'value';
|
|
195
|
+
key: CddlValue;
|
|
196
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { CborItem } from '../ast/CborItem';
|
|
2
|
+
import { CddlNodeBase, CddlType2, CddlValue } from './ast';
|
|
3
|
+
type Path = readonly (string | number)[];
|
|
4
|
+
/** Matching primitives provided by the validator (closed over env/ctx). */
|
|
5
|
+
export interface ControlDeps {
|
|
6
|
+
matchType2(item: CborItem, t2: CddlType2, path: Path): boolean;
|
|
7
|
+
/** Like matchType2, but suppresses instance offsets in recorded errors —
|
|
8
|
+
* the item was decoded out of an embedded byte string, so its offsets
|
|
9
|
+
* are relative to the embedded bytes, not the outer document. */
|
|
10
|
+
matchEmbedded(item: CborItem, t2: CddlType2, path: Path): boolean;
|
|
11
|
+
resolveValue(t2: CddlType2): CddlValue | undefined;
|
|
12
|
+
/** Whether some integer ≥ min matches the type; undefined = unanalyzable. */
|
|
13
|
+
existsIntGE(t2: CddlType2, min: bigint): boolean | undefined;
|
|
14
|
+
matchesLiteral(item: CborItem, v: CddlValue): boolean;
|
|
15
|
+
fail(path: Path, item: CborItem | undefined, node: CddlNodeBase | undefined, message: string): false;
|
|
16
|
+
warnOnce(message: string, node?: CddlNodeBase): void;
|
|
17
|
+
features: ReadonlySet<string>;
|
|
18
|
+
uint(n: number | bigint): CborItem;
|
|
19
|
+
}
|
|
20
|
+
export type ControlHandler = (deps: ControlDeps, item: CborItem, target: CddlType2, controller: CddlType2, path: Path, node: CddlNodeBase) => boolean;
|
|
21
|
+
/**
|
|
22
|
+
* The .feature controller is a feature name, or an array whose first
|
|
23
|
+
* element is the feature name and whose rest is detail (RFC 9165 §5) —
|
|
24
|
+
* either form may be parenthesized, e.g. `.feature (["x", "detail"])`.
|
|
25
|
+
*/
|
|
26
|
+
export declare const featureName: (deps: ControlDeps, controller: CddlType2) => string | undefined;
|
|
27
|
+
export declare function getControl(name: string): ControlHandler | undefined;
|
|
28
|
+
export {};
|