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 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
- Currently, you can 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:
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
- You can use this package to parse the file into an abstract syntax tree (AST):
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
- Comment: string;
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 | Comment;
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
@@ -1 +1 @@
1
- {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"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"}
package/build/ast.js CHANGED
@@ -33,4 +33,9 @@ export var Type;
33
33
  Type["TSTR"] = "tstr";
34
34
  // Text string (major type 3)
35
35
  Type["TEXT"] = "text";
36
+ /**
37
+ * null types
38
+ */
39
+ Type["NIL"] = "nil";
40
+ Type["NULL"] = "null";
36
41
  })(Type || (Type = {}));
@@ -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;AAMrD,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
+ {"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 { ParseTargets } from '../../constants.js';
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
- CDDL.parse(filePath, { target: ParseTargets.AST });
21
+ parse(filePath);
23
22
  /**
24
23
  * ToDo check for
25
24
  * - missing group declarations
@@ -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
@@ -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;AAED,oBAAY,YAAY;IACpB,GAAG,QAAQ;IACX,EAAE,OAAO;CACZ"}
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"}
@@ -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
- import { ParseTargets } from './constants.js';
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: (filePath: string, opts: ParseOptions) => string | import("./ast.js").Assignment[];
5
+ parse: typeof parse;
7
6
  };
8
7
  export default _default;
9
- export { Lexer, Parser, ParseTargets };
8
+ export { Lexer, Parser };
10
9
  //# sourceMappingURL=index.d.ts.map
@@ -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;AAGhC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;;sBAGxB,MAAM,QAAQ,YAAY;;AADhD,wBAcC;AAED,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,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
- import { transform as transformTS } from './transform/ts.js';
4
- import { ParseTargets } from './constants.js';
5
- export default {
6
- parse: (filePath, opts) => {
7
- const parser = new Parser(filePath);
8
- const ast = parser.parse();
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 };
@@ -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;IA8BxB,OAAO,CAAC,oBAAoB;IAyW5B,OAAO,CAAC,wBAAwB;IAahC;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAoBnB,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,iBAAiB;IA2HzB,OAAO,CAAC,aAAa;IAgBrB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,kBAAkB;IAiD1B,OAAO,CAAC,gBAAgB;IA4DxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAUpB,KAAK;IAuBL,OAAO,CAAC,WAAW;CAKtB"}
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
- return this.parseAssignmentValue(groupName, isChoiceAddition);
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
- let comment = '';
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
- Comment: ''
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
- Comment: comment
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: "group",
283
+ Type: 'group',
267
284
  Value: propertyName,
268
285
  Unwrapped: isUnwrapped
269
286
  },
270
- Comment: comment
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
- comment = this.parseComment();
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
- Comment: comment,
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
- let comment = '';
661
- if (this.curToken.Type === Tokens.COMMENT) {
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
- return comment;
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.6.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
  }
@@ -1,3 +0,0 @@
1
- import type { Assignment } from '../ast';
2
- export declare function transform(assignments: Assignment[]): string;
3
- //# sourceMappingURL=ts.d.ts.map
@@ -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"}
@@ -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
@@ -1,5 +0,0 @@
1
- import { ParseTargets } from './constants.js';
2
- export interface ParseOptions {
3
- target: ParseTargets;
4
- }
5
- //# sourceMappingURL=types.d.ts.map
@@ -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 {};