cddl2ts 0.4.4 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -58,4 +58,3 @@ console.log(ts)
58
58
  ---
59
59
 
60
60
  If you are interested in this project, please feel free to contribute ideas or code patches. Have a look at our [contributing guidelines](https://github.com/webdriverio/cddl/blob/master/CONTRIBUTING.md) to get started.
61
-
package/build/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Assignment } from 'cddl';
1
+ import { type Assignment } from 'cddl';
2
2
  export interface TransformOptions {
3
3
  useUnknown?: boolean;
4
4
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAA8D,MAAM,MAAM,CAAA;AAoClG,MAAM,WAAW,gBAAgB;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,wBAAgB,SAAS,CAAE,WAAW,EAAE,UAAU,EAAE,EAAE,OAAO,CAAC,EAAE,gBAAgB,UAwB/E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAWH,KAAK,UAAU,EAMlB,MAAM,MAAM,CAAA;AAuBb,MAAM,WAAW,gBAAgB;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,wBAAgB,SAAS,CAAE,WAAW,EAAE,UAAU,EAAE,EAAE,OAAO,CAAC,EAAE,gBAAgB,UAwB/E"}
package/build/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import camelcase from 'camelcase';
2
2
  import { parse, print, types } from 'recast';
3
3
  import typescriptParser from 'recast/parsers/typescript.js';
4
- import { isCDDLArray, isGroup, isNamedGroupReference, isLiteralWithValue, isNativeTypeWithOperator, isUnNamedProperty, isPropertyReference, isRange, isVariable, pascalCase } from './utils.js';
4
+ import { isCDDLArray, isGroup, isNamedGroupReference, isLiteralWithValue, isNativeTypeWithOperator, isUnNamedProperty, isPropertyReference, isRange, isVariable, pascalCase } from 'cddl';
5
5
  import { pkg } from './constants.js';
6
6
  const b = types.builders;
7
7
  const NATIVE_TYPES = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cddl2ts",
3
- "version": "0.4.4",
3
+ "version": "0.5.0",
4
4
  "description": "A Node.js package that can generate a TypeScript definition based on a CDDL file",
5
5
  "author": "Christian Bromann <mail@bromann.dev>",
6
6
  "license": "MIT",
@@ -32,7 +32,7 @@
32
32
  "camelcase": "^9.0.0",
33
33
  "recast": "^0.23.11",
34
34
  "yargs": "^18.0.0",
35
- "cddl": "0.14.9"
35
+ "cddl": "0.15.0"
36
36
  },
37
37
  "scripts": {
38
38
  "release": "release-it --config .release-it.ts --VV",
package/src/index.ts CHANGED
@@ -2,8 +2,6 @@ import camelcase from 'camelcase'
2
2
  import { parse, print, types } from 'recast'
3
3
  import typescriptParser from 'recast/parsers/typescript.js'
4
4
 
5
- import type { Assignment, PropertyType, PropertyReference, Property, Array, Operator } from 'cddl'
6
-
7
5
  import {
8
6
  isCDDLArray,
9
7
  isGroup,
@@ -14,8 +12,14 @@ import {
14
12
  isPropertyReference,
15
13
  isRange,
16
14
  isVariable,
17
- pascalCase
18
- } from './utils.js'
15
+ pascalCase,
16
+ type Assignment,
17
+ type PropertyType,
18
+ type PropertyReference,
19
+ type Property,
20
+ type Array,
21
+ type Operator
22
+ } from 'cddl'
19
23
 
20
24
  import { pkg } from './constants.js'
21
25
 
@@ -0,0 +1,272 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import type {
4
+ Array as CDDLArray,
5
+ Comment,
6
+ Group,
7
+ Operator,
8
+ Property,
9
+ PropertyReference,
10
+ Variable
11
+ } from 'cddl'
12
+
13
+ import { transform } from '../src/index.js'
14
+
15
+ const COMMENTS: Comment[] = []
16
+
17
+ function comment (content: string): Comment {
18
+ return {
19
+ Type: 'comment',
20
+ Content: content,
21
+ Leading: false
22
+ }
23
+ }
24
+
25
+ function groupRef (value: string, operator?: Operator): PropertyReference {
26
+ return {
27
+ Type: 'group',
28
+ Value: value,
29
+ Unwrapped: false,
30
+ Operator: operator
31
+ }
32
+ }
33
+
34
+ function literal (value: unknown): PropertyReference {
35
+ return {
36
+ Type: 'literal',
37
+ Value: value as any,
38
+ Unwrapped: false
39
+ } as PropertyReference
40
+ }
41
+
42
+ function rangeRef (): PropertyReference {
43
+ return {
44
+ Type: 'range',
45
+ Value: {
46
+ Min: 0,
47
+ Max: 10,
48
+ Inclusive: true
49
+ },
50
+ Unwrapped: false
51
+ }
52
+ }
53
+
54
+ function property (
55
+ name: string,
56
+ type: Property['Type'],
57
+ overrides: Partial<Property> = {}
58
+ ): Property {
59
+ return {
60
+ HasCut: false,
61
+ Occurrence: { n: 1, m: 1 },
62
+ Name: name,
63
+ Type: type,
64
+ Comments: COMMENTS,
65
+ ...overrides
66
+ }
67
+ }
68
+
69
+ function unnamedProperty (
70
+ type: Property['Type'],
71
+ overrides: Partial<Property> = {}
72
+ ): Property {
73
+ return property('', type, overrides)
74
+ }
75
+
76
+ function group (
77
+ name: string,
78
+ properties: Group['Properties'],
79
+ comments: Comment[] = COMMENTS
80
+ ): Group {
81
+ return {
82
+ Type: 'group',
83
+ Name: name,
84
+ IsChoiceAddition: false,
85
+ Properties: properties,
86
+ Comments: comments
87
+ }
88
+ }
89
+
90
+ function array (
91
+ name: string,
92
+ values: CDDLArray['Values'],
93
+ comments: Comment[] = COMMENTS
94
+ ): CDDLArray {
95
+ return {
96
+ Type: 'array',
97
+ Name: name,
98
+ Values: values,
99
+ Comments: comments
100
+ }
101
+ }
102
+
103
+ function variable (
104
+ name: string,
105
+ propertyType: Variable['PropertyType'],
106
+ comments: Comment[] = COMMENTS
107
+ ): Variable {
108
+ return {
109
+ Type: 'variable',
110
+ Name: name,
111
+ PropertyType: propertyType,
112
+ IsChoiceAddition: false,
113
+ Comments: comments
114
+ }
115
+ }
116
+
117
+ describe('transform edge cases', () => {
118
+ it('should map any to unknown when configured', () => {
119
+ const output = transform([
120
+ variable('maybe-value', 'any')
121
+ ], { useUnknown: true })
122
+
123
+ expect(output).toContain('export type MaybeValue = unknown;')
124
+ })
125
+
126
+ it('should generate intersections for choices with static props and mixins', () => {
127
+ const output = transform([
128
+ group('combined', [
129
+ [
130
+ unnamedProperty(groupRef('option-a')),
131
+ unnamedProperty(groupRef('option-b'))
132
+ ],
133
+ property('enabled', 'bool'),
134
+ unnamedProperty([groupRef('mixin-a'), groupRef('mixin-b')])
135
+ ])
136
+ ])
137
+
138
+ expect(output).toContain('export type Combined =')
139
+ expect(output).toContain('enabled: boolean')
140
+ expect(output).toContain('OptionA | OptionB')
141
+ expect(output).toContain('MixinA | MixinB')
142
+ })
143
+
144
+ it('should resolve deeply wrapped group mixins into intersections', () => {
145
+ const output = transform([
146
+ group('wrapped-mixins', [
147
+ unnamedProperty(group('', [
148
+ [
149
+ unnamedProperty(groupRef('choice-a')),
150
+ unnamedProperty(groupRef('choice-b'))
151
+ ],
152
+ unnamedProperty([
153
+ unnamedProperty(groupRef('wrapped-a')) as any,
154
+ unnamedProperty(groupRef('wrapped-b')) as any
155
+ ] as any),
156
+ unnamedProperty([
157
+ [
158
+ unnamedProperty(groupRef('nested-a')) as any,
159
+ unnamedProperty(groupRef('nested-b')) as any
160
+ ]
161
+ ] as any),
162
+ unnamedProperty([unnamedProperty(groupRef('scalar-ref')) as any] as any),
163
+ unnamedProperty(group('', [
164
+ property('flag', 'bool')
165
+ ]))
166
+ ])),
167
+ property('name', 'tstr')
168
+ ])
169
+ ])
170
+
171
+ expect(output).toContain('export type WrappedMixins =')
172
+ expect(output).toContain('ChoiceA | ChoiceB')
173
+ expect(output).toContain('WrappedA | WrappedB')
174
+ expect(output).toContain('NestedA | NestedB')
175
+ expect(output).toContain('ScalarRef')
176
+ expect(output).toContain('flag: boolean')
177
+ expect(output).toContain('name: string')
178
+ })
179
+
180
+ it('should resolve tuples, records, arrays, literals and special references', () => {
181
+ const output = transform([
182
+ variable('tuple-type', group('', [
183
+ unnamedProperty('int'),
184
+ unnamedProperty('tstr')
185
+ ]) as any),
186
+ variable('choice-type', group('', [
187
+ [unnamedProperty('int'), unnamedProperty('tstr')],
188
+ property('flag', 'bool')
189
+ ]) as any),
190
+ variable('record-type', group('', [
191
+ property('text', ['tstr'])
192
+ ]) as any),
193
+ variable('array-type', array('', [
194
+ unnamedProperty(['int', groupRef('custom-value')])
195
+ ]) as any),
196
+ variable('null-type', { Type: 'group', Value: 'null', Unwrapped: false }),
197
+ variable('range-type', rangeRef()),
198
+ variable('pointer-type', {
199
+ Type: groupRef('pointer-value'),
200
+ Operator: { Type: 'default', Value: literal('mouse') }
201
+ }),
202
+ variable('bool-literal', literal(true)),
203
+ variable('null-literal', literal(null))
204
+ ])
205
+
206
+ expect(output).toContain('export type TupleType = [number, string];')
207
+ expect(output).toContain('export type ChoiceType = [number, string] | {')
208
+ expect(output).toContain('export type RecordType = Record<string, string>;')
209
+ expect(output).toContain('export type ArrayType = (number | CustomValue)[];')
210
+ expect(output).toContain('export type NullType = null;')
211
+ expect(output).toContain('export type RangeType = number;')
212
+ expect(output).toContain('export type PointerType = PointerValue;')
213
+ expect(output).toContain('export type BoolLiteral = true;')
214
+ expect(output).toContain('export type NullLiteral = null;')
215
+ })
216
+
217
+ it('should include optional properties and default tags in object docs', () => {
218
+ const output = transform([
219
+ group('defaults', [
220
+ property('count', 'int', {
221
+ Operator: { Type: 'default', Value: literal(7) },
222
+ Comments: [comment('count docs')]
223
+ }),
224
+ property('status', groupRef('status-value', {
225
+ Type: 'default',
226
+ Value: literal('ready')
227
+ }), {
228
+ Comments: [comment('status docs')]
229
+ }),
230
+ property('enabled', 'bool', {
231
+ Occurrence: { n: 0, m: 1 }
232
+ })
233
+ ])
234
+ ])
235
+
236
+ expect(output).toContain('* count docs')
237
+ expect(output).toContain(`* @default 7`)
238
+ expect(output).toContain('* status docs')
239
+ expect(output).toContain(`* @default 'ready'`)
240
+ expect(output).toContain('enabled?: boolean')
241
+ })
242
+
243
+ it('should throw clear errors for unsupported inputs', () => {
244
+ expect(() => transform([
245
+ variable('unknown-native', 'nope')
246
+ ])).toThrow('Unknown native type: "nope')
247
+
248
+ expect(() => transform([
249
+ variable('bad-literal', literal({ nope: true }))
250
+ ])).toThrow('Unsupported literal type')
251
+
252
+ expect(() => transform([
253
+ variable('bad-group', { Type: 'group', Value: false, Unwrapped: false } as any)
254
+ ])).toThrow('Unknown group type')
255
+
256
+ expect(() => transform([
257
+ variable('bad-union', { Type: 'mystery', Value: 'x', Unwrapped: false } as any)
258
+ ])).toThrow('Unknown union type')
259
+
260
+ expect(() => transform([
261
+ group('bad-default', [
262
+ property('foo', 'int', {
263
+ Operator: { Type: 'default', Value: groupRef('no-literal') }
264
+ })
265
+ ])
266
+ ])).toThrow(`Can't parse operator default value`)
267
+
268
+ expect(() => transform([
269
+ { Type: 'mystery' } as any
270
+ ])).toThrow('Unknown assignment type')
271
+ })
272
+ })
package/build/utils.d.ts DELETED
@@ -1,23 +0,0 @@
1
- import { Assignment, PropertyReference, Property, Array, NativeTypeWithOperator, Group, Variable } from 'cddl';
2
- export declare function pascalCase(name: string): string;
3
- export declare function isVariable(assignment: Assignment): assignment is Variable;
4
- export declare function isGroup(t: any): t is Group;
5
- export declare function isCDDLArray(t: any): t is Array;
6
- export declare function isProperty(t: any): t is Property;
7
- export declare function isUnNamedProperty(t: any): t is Property & {
8
- Name: '';
9
- };
10
- export declare function isNamedGroupReference(t: any): t is PropertyReference & {
11
- Value: string;
12
- };
13
- export declare function isPropertyReference(t: any): t is PropertyReference;
14
- export declare function isNativeTypeWithOperator(t: any): t is NativeTypeWithOperator;
15
- export declare function isRange(t: any): boolean;
16
- export declare function isLiteralWithValue(t: any): t is {
17
- Type: 'literal';
18
- Value: unknown;
19
- };
20
- export declare function hasTypeProperty(t: any): t is {
21
- Type: string;
22
- };
23
- //# sourceMappingURL=utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,UAAU,EACV,iBAAiB,EACjB,QAAQ,EACR,KAAK,EACL,sBAAsB,EACtB,KAAK,EACL,QAAQ,EACX,MAAM,MAAM,CAAA;AAGb,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,UAEtC;AAED,wBAAgB,UAAU,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,IAAI,QAAQ,CAEzE;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,IAAI,KAAK,CAE1C;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,IAAI,KAAK,CAE9C;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,IAAI,QAAQ,CAEhD;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,IAAI,QAAQ,GAAG;IAAE,IAAI,EAAE,EAAE,CAAA;CAAE,CAEtE;AAED,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,IAAI,iBAAiB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAExF;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,IAAI,iBAAiB,CAElE;AAED,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,IAAI,sBAAsB,CAE5E;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,GAAG,GAAG,OAAO,CAEvC;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,IAAI;IAC7C,IAAI,EAAE,SAAS,CAAA;IACf,KAAK,EAAE,OAAO,CAAA;CACjB,CAEA;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,IAAI;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAE7D"}
package/build/utils.js DELETED
@@ -1,37 +0,0 @@
1
- import camelcase from 'camelcase';
2
- export function pascalCase(name) {
3
- return camelcase(name, { pascalCase: true });
4
- }
5
- export function isVariable(assignment) {
6
- return assignment.Type === 'variable';
7
- }
8
- export function isGroup(t) {
9
- return t && t.Type === 'group';
10
- }
11
- export function isCDDLArray(t) {
12
- return t && t.Type === 'array';
13
- }
14
- export function isProperty(t) {
15
- return t && typeof t.Name === 'string' && typeof t.HasCut === 'boolean';
16
- }
17
- export function isUnNamedProperty(t) {
18
- return isProperty(t) && t.Name === '';
19
- }
20
- export function isNamedGroupReference(t) {
21
- return isGroup(t) && isPropertyReference(t) && typeof t.Value === 'string';
22
- }
23
- export function isPropertyReference(t) {
24
- return t && 'Value' in t;
25
- }
26
- export function isNativeTypeWithOperator(t) {
27
- return t && typeof t.Type === 'object' && 'Operator' in t;
28
- }
29
- export function isRange(t) {
30
- return t && typeof t.Type === 'object' && t.Type.Type === 'range';
31
- }
32
- export function isLiteralWithValue(t) {
33
- return t && t.Type === 'literal' && 'Value' in t;
34
- }
35
- export function hasTypeProperty(t) {
36
- return t && typeof t.Type === 'string';
37
- }
package/src/utils.ts DELETED
@@ -1,61 +0,0 @@
1
- import {
2
- Assignment,
3
- PropertyReference,
4
- Property,
5
- Array,
6
- NativeTypeWithOperator,
7
- Group,
8
- Variable
9
- } from 'cddl'
10
- import camelcase from 'camelcase'
11
-
12
- export function pascalCase(name: string) {
13
- return camelcase(name, { pascalCase: true })
14
- }
15
-
16
- export function isVariable(assignment: Assignment): assignment is Variable {
17
- return assignment.Type === 'variable'
18
- }
19
-
20
- export function isGroup(t: any): t is Group {
21
- return t && t.Type === 'group'
22
- }
23
-
24
- export function isCDDLArray(t: any): t is Array {
25
- return t && t.Type === 'array'
26
- }
27
-
28
- export function isProperty(t: any): t is Property {
29
- return t && typeof t.Name === 'string' && typeof t.HasCut === 'boolean'
30
- }
31
-
32
- export function isUnNamedProperty(t: any): t is Property & { Name: '' } {
33
- return isProperty(t) && t.Name === ''
34
- }
35
-
36
- export function isNamedGroupReference(t: any): t is PropertyReference & { Value: string } {
37
- return isGroup(t) && isPropertyReference(t) && typeof t.Value === 'string'
38
- }
39
-
40
- export function isPropertyReference(t: any): t is PropertyReference {
41
- return t && 'Value' in t
42
- }
43
-
44
- export function isNativeTypeWithOperator(t: any): t is NativeTypeWithOperator {
45
- return t && typeof t.Type === 'object' && 'Operator' in t
46
- }
47
-
48
- export function isRange(t: any): boolean {
49
- return t && typeof t.Type === 'object' && (t.Type as any).Type === 'range'
50
- }
51
-
52
- export function isLiteralWithValue(t: any): t is {
53
- Type: 'literal'
54
- Value: unknown
55
- } {
56
- return t && t.Type === 'literal' && 'Value' in t
57
- }
58
-
59
- export function hasTypeProperty(t: any): t is { Type: string } {
60
- return t && typeof t.Type === 'string'
61
- }