cddl 0.6.0 → 0.8.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/.editorconfig +18 -0
- package/README.md +17 -2
- package/build/ast.d.ts +14 -5
- package/build/ast.d.ts.map +1 -1
- package/build/ast.js +5 -0
- package/build/cli/commands/validate.d.ts.map +1 -1
- package/build/cli/commands/validate.js +2 -3
- package/build/constants.d.ts +0 -4
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +0 -5
- package/build/index.d.ts +3 -4
- package/build/index.d.ts.map +1 -1
- package/build/index.js +6 -16
- package/build/parser.d.ts.map +1 -1
- package/build/parser.js +70 -29
- package/examples/webdriver/remote.cddl +2 -2
- package/package.json +1 -4
- package/build/transform/ts.d.ts +0 -3
- package/build/transform/ts.d.ts.map +0 -1
- package/build/transform/ts.js +0 -113
- package/build/types.d.ts +0 -5
- package/build/types.d.ts.map +0 -1
- package/build/types.js +0 -1
package/.editorconfig
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# EditorConfig helps developers define and maintain consistent
|
|
2
|
+
# coding styles between different editors and IDEs
|
|
3
|
+
# editorconfig.org
|
|
4
|
+
|
|
5
|
+
root = true
|
|
6
|
+
|
|
7
|
+
[*]
|
|
8
|
+
|
|
9
|
+
indent_style = space
|
|
10
|
+
indent_size = 4
|
|
11
|
+
|
|
12
|
+
end_of_line = lf
|
|
13
|
+
charset = utf-8
|
|
14
|
+
trim_trailing_whitespace = true
|
|
15
|
+
insert_final_newline = true
|
|
16
|
+
|
|
17
|
+
[{.travis.yml,**/*.json,.github/**/*.yml}]
|
|
18
|
+
indent_size = 2
|
package/README.md
CHANGED
|
@@ -20,7 +20,20 @@ $ npm install cddl
|
|
|
20
20
|
|
|
21
21
|
## Using this package
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
This package exposes a CLI as well as a programmatic interface for parsing and transforming CDDL.
|
|
24
|
+
|
|
25
|
+
### CLI
|
|
26
|
+
|
|
27
|
+
The `cddl` CLI offers a `validate` command that helps identify invalid CDDL formats, e.g.:
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
npx cddl validate ./path/to/interface.cddl
|
|
31
|
+
✅ Valid CDDL file!
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Programmatic Interface
|
|
35
|
+
|
|
36
|
+
You can also use this package to parse a CDDL file into an [abstract syntax tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree) (AST). For example, given the following CDDL file:
|
|
24
37
|
|
|
25
38
|
```cddl
|
|
26
39
|
person = {
|
|
@@ -29,7 +42,7 @@ person = {
|
|
|
29
42
|
}
|
|
30
43
|
```
|
|
31
44
|
|
|
32
|
-
|
|
45
|
+
It parses the content into an AST:
|
|
33
46
|
|
|
34
47
|
```js
|
|
35
48
|
import { parse } from 'cddl'
|
|
@@ -49,6 +62,8 @@ console.log(ast)
|
|
|
49
62
|
*/
|
|
50
63
|
```
|
|
51
64
|
|
|
65
|
+
The CDDL AST is defined in [source files](./src/ast.ts). The `parse` method returns `Assignment[]`.
|
|
66
|
+
|
|
52
67
|
---
|
|
53
68
|
|
|
54
69
|
If you are interested in this project, please feel free to contribute ideas or code patches. Have a look at our [contributing](https://github.com/christian-bromann/cddl/blob/master/LICENSE) guidelines](https://github.com/christian-bromann/cddl/blob/master/LICENSE) to get started.
|
package/build/ast.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export type Group = {
|
|
|
13
13
|
Name: string;
|
|
14
14
|
IsChoiceAddition: boolean;
|
|
15
15
|
Properties: (Property | Property[])[];
|
|
16
|
+
Comments: Comment[];
|
|
16
17
|
};
|
|
17
18
|
/**
|
|
18
19
|
* an array definition
|
|
@@ -26,6 +27,7 @@ export type Array = {
|
|
|
26
27
|
Type: 'array';
|
|
27
28
|
Name: string;
|
|
28
29
|
Values: (Property | Property[])[];
|
|
30
|
+
Comments: Comment[];
|
|
29
31
|
};
|
|
30
32
|
/**
|
|
31
33
|
* a tag definition
|
|
@@ -49,6 +51,7 @@ export type Variable = {
|
|
|
49
51
|
IsChoiceAddition: boolean;
|
|
50
52
|
PropertyType: PropertyType | PropertyType[];
|
|
51
53
|
Operator?: Operator;
|
|
54
|
+
Comments: Comment[];
|
|
52
55
|
};
|
|
53
56
|
/**
|
|
54
57
|
* a comment statement
|
|
@@ -59,6 +62,7 @@ export type Variable = {
|
|
|
59
62
|
export type Comment = {
|
|
60
63
|
Type: 'comment';
|
|
61
64
|
Content: string;
|
|
65
|
+
Leading: boolean;
|
|
62
66
|
};
|
|
63
67
|
export type Occurrence = {
|
|
64
68
|
n: number;
|
|
@@ -69,7 +73,7 @@ export type Property = {
|
|
|
69
73
|
Occurrence: Occurrence;
|
|
70
74
|
Name: PropertyName;
|
|
71
75
|
Type: PropertyType | PropertyType[];
|
|
72
|
-
|
|
76
|
+
Comments: Comment[];
|
|
73
77
|
Operator?: Operator;
|
|
74
78
|
};
|
|
75
79
|
export declare enum Type {
|
|
@@ -93,7 +97,12 @@ export declare enum Type {
|
|
|
93
97
|
BSTR = "bstr",
|
|
94
98
|
BYTES = "bytes",
|
|
95
99
|
TSTR = "tstr",
|
|
96
|
-
TEXT = "text"
|
|
100
|
+
TEXT = "text",
|
|
101
|
+
/**
|
|
102
|
+
* null types
|
|
103
|
+
*/
|
|
104
|
+
NIL = "nil",
|
|
105
|
+
NULL = "null"
|
|
97
106
|
}
|
|
98
107
|
/**
|
|
99
108
|
* can be a number, e.g. "foo = 0..10"
|
|
@@ -122,7 +131,7 @@ export interface Operator {
|
|
|
122
131
|
Type: OperatorType;
|
|
123
132
|
Value: PropertyType;
|
|
124
133
|
}
|
|
125
|
-
export type PropertyReferenceType = 'literal' | 'group' | 'group_array' | 'range' | 'tag';
|
|
134
|
+
export type PropertyReferenceType = 'literal' | 'group' | 'group_array' | 'array' | 'range' | 'tag';
|
|
126
135
|
export type PropertyReference = {
|
|
127
136
|
Type: PropertyReferenceType;
|
|
128
137
|
Value: string | number | boolean | Group | Array | Range | Tag;
|
|
@@ -130,10 +139,10 @@ export type PropertyReference = {
|
|
|
130
139
|
Operator?: Operator;
|
|
131
140
|
};
|
|
132
141
|
export interface NativeTypeWithOperator {
|
|
133
|
-
Type: Type;
|
|
142
|
+
Type: Type | PropertyReference;
|
|
134
143
|
Operator?: Operator;
|
|
135
144
|
}
|
|
136
|
-
export type Assignment = Group | Array | Variable
|
|
145
|
+
export type Assignment = Group | Array | Variable;
|
|
137
146
|
export type PropertyType = Assignment | Array | PropertyReference | string | NativeTypeWithOperator;
|
|
138
147
|
export type PropertyName = string;
|
|
139
148
|
//# sourceMappingURL=ast.d.ts.map
|
package/build/ast.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,MAAM,KAAK,GAAG;IAChB,IAAI,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"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"}
|
package/build/ast.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/validate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/validate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAA;AAKrD,UAAU,iBAAiB;IACvB,QAAQ,EAAE,MAAM,CAAA;CACnB;AAED,eAAO,MAAM,OAAO,wBAAwB,CAAA;AAC5C,eAAO,MAAM,IAAI,2BAA2B,CAAA;AAC5C,eAAO,MAAM,OAAO,UAAW,KAAK,EAAE,CAAC,aAItC,CAAA;AAED,eAAO,MAAM,OAAO,SAAU,mBAAmB,iBAAiB,CAAC,cAuBlE,CAAA"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { CLI_EPILOGUE } from '../constants.js';
|
|
4
|
-
import {
|
|
5
|
-
import CDDL from '../../index.js';
|
|
4
|
+
import { parse } from '../../index.js';
|
|
6
5
|
export const command = 'validate <filePath>';
|
|
7
6
|
export const desc = 'Validate a *.cddl file';
|
|
8
7
|
export const builder = (yargs) => {
|
|
@@ -19,7 +18,7 @@ export const handler = (argv) => {
|
|
|
19
18
|
return process.exit(1);
|
|
20
19
|
}
|
|
21
20
|
try {
|
|
22
|
-
|
|
21
|
+
parse(filePath);
|
|
23
22
|
/**
|
|
24
23
|
* ToDo check for
|
|
25
24
|
* - missing group declarations
|
package/build/constants.d.ts
CHANGED
|
@@ -5,8 +5,4 @@ export declare const BOOLEAN_LITERALS: string[];
|
|
|
5
5
|
* https://tools.ietf.org/html/draft-ietf-cbor-cddl-08#appendix-D
|
|
6
6
|
*/
|
|
7
7
|
export declare const PREDEFINED_IDENTIFIER: string[];
|
|
8
|
-
export declare enum ParseTargets {
|
|
9
|
-
AST = "ast",
|
|
10
|
-
TS = "ts"
|
|
11
|
-
}
|
|
12
8
|
//# sourceMappingURL=constants.d.ts.map
|
package/build/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,UAA0B,CAAA;AAC5D,eAAO,MAAM,gBAAgB,UAAoB,CAAA;AAEjD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,UAQjC,CAAA
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,UAA0B,CAAA;AAC5D,eAAO,MAAM,gBAAgB,UAAoB,CAAA;AAEjD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,UAQjC,CAAA"}
|
package/build/constants.js
CHANGED
|
@@ -13,8 +13,3 @@ export const PREDEFINED_IDENTIFIER = [
|
|
|
13
13
|
'float32', 'float64', 'float16-32', 'float32-64', 'float',
|
|
14
14
|
'false', 'true', 'bool', 'nil', 'null', 'undefined'
|
|
15
15
|
];
|
|
16
|
-
export var ParseTargets;
|
|
17
|
-
(function (ParseTargets) {
|
|
18
|
-
ParseTargets["AST"] = "ast";
|
|
19
|
-
ParseTargets["TS"] = "ts";
|
|
20
|
-
})(ParseTargets || (ParseTargets = {}));
|
package/build/index.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import Lexer from './lexer.js';
|
|
2
2
|
import Parser from './parser.js';
|
|
3
|
-
|
|
4
|
-
import type { ParseOptions } from './types.js';
|
|
3
|
+
export declare function parse(filePath: string): import("./ast.js").Assignment[];
|
|
5
4
|
declare const _default: {
|
|
6
|
-
parse:
|
|
5
|
+
parse: typeof parse;
|
|
7
6
|
};
|
|
8
7
|
export default _default;
|
|
9
|
-
export { Lexer, Parser
|
|
8
|
+
export { Lexer, Parser };
|
|
10
9
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,MAAM,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,MAAM,MAAM,aAAa,CAAA;AAEhC,wBAAgB,KAAK,CAAE,QAAQ,EAAE,MAAM,mCAGtC;;;;AAED,wBAAwB;AACxB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA"}
|
package/build/index.js
CHANGED
|
@@ -1,18 +1,8 @@
|
|
|
1
1
|
import Lexer from './lexer.js';
|
|
2
2
|
import Parser from './parser.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (opts.target === ParseTargets.AST) {
|
|
10
|
-
return ast;
|
|
11
|
-
}
|
|
12
|
-
if (opts.target === ParseTargets.TS) {
|
|
13
|
-
return transformTS(ast);
|
|
14
|
-
}
|
|
15
|
-
throw new Error(`Unsupported parse target: "${opts.target || 'undefined'}"`);
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
export { Lexer, Parser, ParseTargets };
|
|
3
|
+
export function parse(filePath) {
|
|
4
|
+
const parser = new Parser(filePath);
|
|
5
|
+
return parser.parse();
|
|
6
|
+
}
|
|
7
|
+
export default { parse };
|
|
8
|
+
export { Lexer, Parser };
|
package/build/parser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,YAAY,CAAA;AAE9B,OAAO,EAAE,KAAK,EAAU,MAAM,aAAa,CAAC;AAG5C,OAAO,EAE2C,UAAU,EAE3D,MAAM,UAAU,CAAA;AAoBjB,MAAM,CAAC,OAAO,OAAO,MAAM;;IAEvB,CAAC,EAAE,KAAK,CAAC;IAET,QAAQ,EAAE,KAAK,CAAa;IAC5B,SAAS,EAAE,KAAK,CAAa;gBAEhB,QAAQ,EAAE,MAAM;IAQ7B,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,gBAAgB;
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,YAAY,CAAA;AAE9B,OAAO,EAAE,KAAK,EAAU,MAAM,aAAa,CAAC;AAG5C,OAAO,EAE2C,UAAU,EAE3D,MAAM,UAAU,CAAA;AAoBjB,MAAM,CAAC,OAAO,OAAO,MAAM;;IAEvB,CAAC,EAAE,KAAK,CAAC;IAET,QAAQ,EAAE,KAAK,CAAa;IAC5B,SAAS,EAAE,KAAK,CAAa;gBAEhB,QAAQ,EAAE,MAAM;IAQ7B,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,gBAAgB;IA2CxB,OAAO,CAAC,oBAAoB;IA6Y5B,OAAO,CAAC,wBAAwB;IAahC;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAoBnB,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,iBAAiB;IA6HzB,OAAO,CAAC,aAAa;IAgBrB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,kBAAkB;IAiD1B,OAAO,CAAC,gBAAgB;IA4DxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAcpB,KAAK;IAaL,OAAO,CAAC,WAAW;CAKtB"}
|
package/build/parser.js
CHANGED
|
@@ -38,6 +38,10 @@ export default class Parser {
|
|
|
38
38
|
return true;
|
|
39
39
|
}
|
|
40
40
|
parseAssignments() {
|
|
41
|
+
const comments = [];
|
|
42
|
+
while (this.curToken.Type === Tokens.COMMENT) {
|
|
43
|
+
comments.push(this.parseComment());
|
|
44
|
+
}
|
|
41
45
|
/**
|
|
42
46
|
* expect group identifier, e.g.
|
|
43
47
|
* groupName =
|
|
@@ -60,7 +64,14 @@ export default class Parser {
|
|
|
60
64
|
this.nextToken(); // eat `/`
|
|
61
65
|
}
|
|
62
66
|
this.nextToken(); // eat `=`
|
|
63
|
-
|
|
67
|
+
const assignmentValue = this.parseAssignmentValue(groupName, isChoiceAddition);
|
|
68
|
+
// @ts-expect-error curToken can be changed by now but TS doesn't understand this
|
|
69
|
+
while (this.curToken.Type === Tokens.COMMENT) {
|
|
70
|
+
const comment = this.parseComment();
|
|
71
|
+
comment && comments.push(comment);
|
|
72
|
+
}
|
|
73
|
+
assignmentValue.Comments = comments;
|
|
74
|
+
return assignmentValue;
|
|
64
75
|
}
|
|
65
76
|
parseAssignmentValue(groupName, isChoiceAddition = false) {
|
|
66
77
|
let isChoice = false;
|
|
@@ -79,7 +90,8 @@ export default class Parser {
|
|
|
79
90
|
Type: 'variable',
|
|
80
91
|
Name: groupName,
|
|
81
92
|
IsChoiceAddition: isChoiceAddition,
|
|
82
|
-
PropertyType: this.parsePropertyTypes()
|
|
93
|
+
PropertyType: this.parsePropertyTypes(),
|
|
94
|
+
Comments: []
|
|
83
95
|
};
|
|
84
96
|
return variable;
|
|
85
97
|
}
|
|
@@ -116,7 +128,8 @@ export default class Parser {
|
|
|
116
128
|
Type: 'variable',
|
|
117
129
|
Name: groupName,
|
|
118
130
|
IsChoiceAddition: isChoiceAddition,
|
|
119
|
-
PropertyType: propertyType
|
|
131
|
+
PropertyType: propertyType,
|
|
132
|
+
Comments: []
|
|
120
133
|
};
|
|
121
134
|
if (this.isOperator()) {
|
|
122
135
|
variable.Operator = this.parseOperator();
|
|
@@ -140,7 +153,8 @@ export default class Parser {
|
|
|
140
153
|
Name: groupName,
|
|
141
154
|
IsChoiceAddition: isChoiceAddition,
|
|
142
155
|
PropertyType: prop,
|
|
143
|
-
Operator: this.parseOperator()
|
|
156
|
+
Operator: this.parseOperator(),
|
|
157
|
+
Comments: []
|
|
144
158
|
};
|
|
145
159
|
return variable;
|
|
146
160
|
}
|
|
@@ -148,10 +162,12 @@ export default class Parser {
|
|
|
148
162
|
}
|
|
149
163
|
while (!closingTokens.includes(this.curToken.Type)) {
|
|
150
164
|
const propertyType = [];
|
|
165
|
+
const comments = [];
|
|
151
166
|
let isUnwrapped = false;
|
|
152
167
|
let hasCut = false;
|
|
153
168
|
let propertyName = '';
|
|
154
|
-
|
|
169
|
+
const leadingComment = this.parseComment(true);
|
|
170
|
+
leadingComment && comments.push(leadingComment);
|
|
155
171
|
const occurrence = this.parseOccurrences();
|
|
156
172
|
/**
|
|
157
173
|
* check if variable name is unwrapped
|
|
@@ -184,7 +200,7 @@ export default class Parser {
|
|
|
184
200
|
Occurrence: occurrence,
|
|
185
201
|
Name: '',
|
|
186
202
|
Type: innerGroup,
|
|
187
|
-
|
|
203
|
+
Comments: []
|
|
188
204
|
});
|
|
189
205
|
continue;
|
|
190
206
|
}
|
|
@@ -202,6 +218,7 @@ export default class Parser {
|
|
|
202
218
|
if (this.curToken.Type === Tokens.COMMA || closingTokens.includes(this.curToken.Type)) {
|
|
203
219
|
const tokenType = this.curToken.Type;
|
|
204
220
|
let parsedComments = false;
|
|
221
|
+
let comment;
|
|
205
222
|
/**
|
|
206
223
|
* check if line has a comment
|
|
207
224
|
*/
|
|
@@ -221,7 +238,7 @@ export default class Parser {
|
|
|
221
238
|
Value: propertyName,
|
|
222
239
|
Unwrapped: isUnwrapped
|
|
223
240
|
}],
|
|
224
|
-
|
|
241
|
+
Comments: comment ? [comment] : []
|
|
225
242
|
});
|
|
226
243
|
if (this.curToken.Literal === Tokens.COMMA || this.curToken.Literal === closingTokens[0]) {
|
|
227
244
|
if (this.curToken.Literal === Tokens.COMMA) {
|
|
@@ -263,11 +280,11 @@ export default class Parser {
|
|
|
263
280
|
Occurrence: occurrence,
|
|
264
281
|
Name: '',
|
|
265
282
|
Type: {
|
|
266
|
-
Type:
|
|
283
|
+
Type: 'group',
|
|
267
284
|
Value: propertyName,
|
|
268
285
|
Unwrapped: isUnwrapped
|
|
269
286
|
},
|
|
270
|
-
|
|
287
|
+
Comments: comments
|
|
271
288
|
};
|
|
272
289
|
if (isChoice) {
|
|
273
290
|
/**
|
|
@@ -318,14 +335,15 @@ export default class Parser {
|
|
|
318
335
|
flipIsChoice = true;
|
|
319
336
|
this.nextToken(); // eat ,
|
|
320
337
|
}
|
|
321
|
-
|
|
338
|
+
const trailingComment = this.parseComment();
|
|
339
|
+
trailingComment && comments.push(trailingComment);
|
|
322
340
|
const prop = {
|
|
323
341
|
HasCut: hasCut,
|
|
324
342
|
Occurrence: occurrence,
|
|
325
343
|
Name: propertyName,
|
|
326
344
|
Type: propertyType,
|
|
327
|
-
|
|
328
|
-
...(operator ? operator : {})
|
|
345
|
+
Comments: comments,
|
|
346
|
+
...(operator ? { Operator: operator } : {})
|
|
329
347
|
};
|
|
330
348
|
if (isChoice) {
|
|
331
349
|
valuesOrProperties[valuesOrProperties.length - 1].push(prop);
|
|
@@ -364,9 +382,35 @@ export default class Parser {
|
|
|
364
382
|
return {
|
|
365
383
|
Type: 'array',
|
|
366
384
|
Name: groupName || '',
|
|
367
|
-
Values: valuesOrProperties
|
|
385
|
+
Values: valuesOrProperties,
|
|
386
|
+
Comments: []
|
|
368
387
|
};
|
|
369
388
|
}
|
|
389
|
+
/**
|
|
390
|
+
* simplify wrapped types, e.g. from
|
|
391
|
+
* {
|
|
392
|
+
* "Type": "group",
|
|
393
|
+
* "Name": "",
|
|
394
|
+
* "Properties": [
|
|
395
|
+
* {
|
|
396
|
+
* "HasCut": false,
|
|
397
|
+
* "Occurrence": {
|
|
398
|
+
* "n": 1,
|
|
399
|
+
* "m": 1
|
|
400
|
+
* },
|
|
401
|
+
* "Name": "",
|
|
402
|
+
* "Type": "bool",
|
|
403
|
+
* "Comment": ""
|
|
404
|
+
* }
|
|
405
|
+
* ],
|
|
406
|
+
* "IsChoiceAddition": false
|
|
407
|
+
* }
|
|
408
|
+
* back to:
|
|
409
|
+
* bool
|
|
410
|
+
*/
|
|
411
|
+
if (!groupName && valuesOrProperties.length === 1 && PREDEFINED_IDENTIFIER.includes(valuesOrProperties[0].Type)) {
|
|
412
|
+
return valuesOrProperties[0].Type;
|
|
413
|
+
}
|
|
370
414
|
/**
|
|
371
415
|
* otherwise a group
|
|
372
416
|
*/
|
|
@@ -374,7 +418,8 @@ export default class Parser {
|
|
|
374
418
|
Type: 'group',
|
|
375
419
|
Name: groupName || '',
|
|
376
420
|
Properties: valuesOrProperties,
|
|
377
|
-
IsChoiceAddition: isChoiceAddition
|
|
421
|
+
IsChoiceAddition: isChoiceAddition,
|
|
422
|
+
Comments: []
|
|
378
423
|
};
|
|
379
424
|
}
|
|
380
425
|
isPropertyValueSeparator() {
|
|
@@ -446,6 +491,8 @@ export default class Parser {
|
|
|
446
491
|
case Type.BYTES:
|
|
447
492
|
case Type.TSTR:
|
|
448
493
|
case Type.TEXT:
|
|
494
|
+
case Type.NIL:
|
|
495
|
+
case Type.NULL:
|
|
449
496
|
type = this.curToken.Literal;
|
|
450
497
|
break;
|
|
451
498
|
default: {
|
|
@@ -656,26 +703,20 @@ export default class Parser {
|
|
|
656
703
|
/**
|
|
657
704
|
* check if line has a comment
|
|
658
705
|
*/
|
|
659
|
-
parseComment() {
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
comment = this.curToken.Literal.slice(2);
|
|
663
|
-
this.nextToken();
|
|
706
|
+
parseComment(isLeading) {
|
|
707
|
+
if (this.curToken.Type !== Tokens.COMMENT) {
|
|
708
|
+
return;
|
|
664
709
|
}
|
|
665
|
-
|
|
710
|
+
const comment = this.curToken.Literal.replace(/^;(\s*)/, '');
|
|
711
|
+
this.nextToken();
|
|
712
|
+
if (comment.trim().length === 0) {
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
return { Type: 'comment', Content: comment, Leading: Boolean(isLeading) };
|
|
666
716
|
}
|
|
667
717
|
parse() {
|
|
668
718
|
const definition = [];
|
|
669
719
|
while (this.curToken.Type !== Tokens.EOF) {
|
|
670
|
-
if (this.curToken.Type === Tokens.COMMENT) {
|
|
671
|
-
const comment = {
|
|
672
|
-
Type: 'comment',
|
|
673
|
-
Content: this.curToken.Literal.slice(1).trim()
|
|
674
|
-
};
|
|
675
|
-
definition.push(comment);
|
|
676
|
-
this.nextToken();
|
|
677
|
-
continue;
|
|
678
|
-
}
|
|
679
720
|
const group = this.parseAssignments();
|
|
680
721
|
if (group) {
|
|
681
722
|
definition.push(group);
|
|
@@ -375,14 +375,14 @@ script.RemoteReference = (
|
|
|
375
375
|
|
|
376
376
|
script.SharedReference = {
|
|
377
377
|
sharedId: script.SharedId
|
|
378
|
-
|
|
378
|
+
|
|
379
379
|
?handle: script.Handle,
|
|
380
380
|
Extensible
|
|
381
381
|
}
|
|
382
382
|
|
|
383
383
|
script.RemoteObjectReference = {
|
|
384
384
|
handle: script.Handle,
|
|
385
|
-
|
|
385
|
+
|
|
386
386
|
?sharedId: script.SharedId
|
|
387
387
|
Extensible
|
|
388
388
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cddl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Concise data definition language (RFC 8610) implementation and JSON validator in Node.js",
|
|
5
5
|
"author": "Christian Bromann <christian@saucelabs.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,9 +42,6 @@
|
|
|
42
42
|
"vitest": "^0.29.2"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@babel/parser": "^7.21.4",
|
|
46
|
-
"camelcase": "^7.0.1",
|
|
47
|
-
"recast": "^0.22.0",
|
|
48
45
|
"yargs": "^17.7.1"
|
|
49
46
|
}
|
|
50
47
|
}
|
package/build/transform/ts.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ts.d.ts","sourceRoot":"","sources":["../../src/transform/ts.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAA6C,MAAM,QAAQ,CAAA;AAanF,wBAAgB,SAAS,CAAE,WAAW,EAAE,UAAU,EAAE,UAoBnD"}
|
package/build/transform/ts.js
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import camelcase from 'camelcase';
|
|
2
|
-
import { parse, print, types } from 'recast';
|
|
3
|
-
import typescriptParser from 'recast/parsers/typescript.js';
|
|
4
|
-
// @ts-ignore
|
|
5
|
-
import pkg from '../../package.json' assert { type: 'json' };
|
|
6
|
-
const b = types.builders;
|
|
7
|
-
const comments = [];
|
|
8
|
-
const NATIVE_TYPES = {
|
|
9
|
-
number: 'number',
|
|
10
|
-
uint: 'Uint32Array',
|
|
11
|
-
bool: 'boolean',
|
|
12
|
-
str: 'string',
|
|
13
|
-
text: 'string',
|
|
14
|
-
tstr: 'string'
|
|
15
|
-
};
|
|
16
|
-
export function transform(assignments) {
|
|
17
|
-
let ast = parse(`// compiled with https://www.npmjs.com/package/cddl v${pkg.version}`, {
|
|
18
|
-
parser: typescriptParser,
|
|
19
|
-
sourceFileName: 'cddl2Ts.ts',
|
|
20
|
-
sourceRoot: process.cwd()
|
|
21
|
-
});
|
|
22
|
-
for (const assignment of assignments) {
|
|
23
|
-
const statement = parseAssignment(ast, assignment);
|
|
24
|
-
if (!statement) {
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
ast.program.body.push(statement);
|
|
28
|
-
}
|
|
29
|
-
ast.program.comments = comments.map((c) => b.commentLine(c, false, false));
|
|
30
|
-
return print(ast).code;
|
|
31
|
-
}
|
|
32
|
-
function parseAssignment(ast, assignment) {
|
|
33
|
-
if (assignment.Type === 'comment') {
|
|
34
|
-
comments.push(assignment.Content);
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
if (assignment.Type === 'variable') {
|
|
38
|
-
const propType = Array.isArray(assignment.PropertyType)
|
|
39
|
-
? assignment.PropertyType
|
|
40
|
-
: [assignment.PropertyType];
|
|
41
|
-
const id = b.identifier(camelcase(assignment.Name, { pascalCase: true }));
|
|
42
|
-
let typeParameters;
|
|
43
|
-
// @ts-expect-error e.g. "js-int = -9007199254740991..9007199254740991"
|
|
44
|
-
if (propType.length === 1 && propType[0].Type === 'range') {
|
|
45
|
-
typeParameters = b.tsNumberKeyword();
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
typeParameters = b.tsUnionType(propType.map(parsePropertyType));
|
|
49
|
-
}
|
|
50
|
-
const expr = b.tsTypeAliasDeclaration(id, typeParameters);
|
|
51
|
-
expr.comments = comments.map((c) => b.commentLine(c, true));
|
|
52
|
-
return expr;
|
|
53
|
-
}
|
|
54
|
-
if (assignment.Type === 'group') {
|
|
55
|
-
const id = b.identifier(camelcase(assignment.Name, { pascalCase: true }));
|
|
56
|
-
const objectType = parseObjectType(assignment.Properties);
|
|
57
|
-
const expr = b.interfaceDeclaration(id, objectType, []);
|
|
58
|
-
return expr;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
function parsePropertyType(propType) {
|
|
62
|
-
if (typeof propType === 'string') {
|
|
63
|
-
return b.tsStringKeyword();
|
|
64
|
-
}
|
|
65
|
-
if (propType.Type === 'group') {
|
|
66
|
-
return b.tsTypeReference(b.identifier(propType.Value.toString()));
|
|
67
|
-
}
|
|
68
|
-
if (propType.Type === 'literal') {
|
|
69
|
-
return b.tsLiteralType(b.stringLiteral(propType.Value.toString()));
|
|
70
|
-
}
|
|
71
|
-
throw new Error(`Couldn't parse property type ${JSON.stringify(propType, null, 4)}`);
|
|
72
|
-
}
|
|
73
|
-
function parseObjectType(props) {
|
|
74
|
-
const propItems = [];
|
|
75
|
-
for (const prop of props) {
|
|
76
|
-
/**
|
|
77
|
-
* ToDo(Christian): support Extensible
|
|
78
|
-
*/
|
|
79
|
-
if (prop.Name === '') {
|
|
80
|
-
propItems[propItems.length - 1].comments = [b.commentLine(`Missing: ${JSON.stringify(prop)}`)];
|
|
81
|
-
continue;
|
|
82
|
-
}
|
|
83
|
-
const id = b.identifier(camelcase(prop.Name));
|
|
84
|
-
const cddlType = Array.isArray(prop.Type) ? prop.Type : [prop.Type];
|
|
85
|
-
const typeParameters = b.unionTypeAnnotation(cddlType.map((t) => {
|
|
86
|
-
if (typeof t === 'string') {
|
|
87
|
-
if (!NATIVE_TYPES[t]) {
|
|
88
|
-
throw new Error(`Unknown native type: "${t}`);
|
|
89
|
-
}
|
|
90
|
-
return b.typeParameter(NATIVE_TYPES[t]);
|
|
91
|
-
}
|
|
92
|
-
else if (t.Value === 'null') {
|
|
93
|
-
return b.nullTypeAnnotation();
|
|
94
|
-
}
|
|
95
|
-
else if (t.Type === 'group') {
|
|
96
|
-
const value = t.Value;
|
|
97
|
-
return b.typeParameter(
|
|
98
|
-
/**
|
|
99
|
-
* transform native CDDL types into TypeScript types
|
|
100
|
-
*/
|
|
101
|
-
NATIVE_TYPES[value] ? value : camelcase(value.toString(), { pascalCase: true }));
|
|
102
|
-
}
|
|
103
|
-
else if (t.Type === 'literal' && typeof t.Value === 'string') {
|
|
104
|
-
return b.stringLiteralTypeAnnotation(t.Value, t.Value);
|
|
105
|
-
}
|
|
106
|
-
throw new Error(`Couldn't parse property ${JSON.stringify(t)}`);
|
|
107
|
-
}));
|
|
108
|
-
const isOptional = prop.Occurrence.n === 0;
|
|
109
|
-
propItems.push(b.objectTypeProperty(id, typeParameters, isOptional));
|
|
110
|
-
}
|
|
111
|
-
const obj = b.objectTypeAnnotation(propItems);
|
|
112
|
-
return obj;
|
|
113
|
-
}
|
package/build/types.d.ts
DELETED
package/build/types.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAE7C,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,YAAY,CAAA;CACvB"}
|
package/build/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|