cddl2ts 0.3.0 → 0.4.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.
@@ -0,0 +1,54 @@
1
+ import url from 'node:url'
2
+ import path from 'node:path'
3
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
4
+
5
+ import cli from '../src/cli.js'
6
+
7
+ const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
8
+ const complexTypesCDDL = path.join(__dirname, '..', '..', '..', 'examples', 'commons', 'complex_types.cddl')
9
+
10
+
11
+ vi.mock('../src/constants', () => ({
12
+ pkg: {
13
+ name: 'cddl2ts',
14
+ version: '0.0.0'
15
+ }
16
+ }))
17
+
18
+ describe('complex types (Map, Set, RegExp, Date...)', () => {
19
+ let exitOrig = process.exit
20
+ let logOrig = console.log
21
+ let errorOrig = console.error
22
+
23
+ beforeEach(() => {
24
+ process.exit = vi.fn() as any
25
+ console.log = vi.fn()
26
+ console.error = vi.fn()
27
+ })
28
+
29
+ afterEach(() => {
30
+ process.exit = exitOrig
31
+ console.log = logOrig
32
+ console.error = errorOrig
33
+ })
34
+
35
+ it('should include all types in the union', async () => {
36
+ await cli([complexTypesCDDL, '--unknown-as-any'])
37
+
38
+ expect(process.exit).not.toHaveBeenCalledWith(1)
39
+ expect(console.error).not.toHaveBeenCalled()
40
+ expect(console.log).toHaveBeenCalled()
41
+ const output = vi.mocked(console.log).mock.calls.flat().join('\n')
42
+
43
+ // Check if all types are present in the union or defined
44
+ expect(output).toContain('ArrayLocalValue')
45
+ expect(output).toContain('DateLocalValue')
46
+ expect(output).toContain('MapLocalValue')
47
+ expect(output).toContain('ObjectLocalValue')
48
+ expect(output).toContain('RegExpLocalValue')
49
+ expect(output).toContain('SetLocalValue')
50
+
51
+ // Specific check for the buggy union generation where types were dropped
52
+ expect(output).toContain('export type LocalValue = ArrayLocalValue | DateLocalValue | MapLocalValue | ObjectLocalValue | RegExpLocalValue | SetLocalValue;')
53
+ })
54
+ })
@@ -0,0 +1,53 @@
1
+ import url from 'node:url'
2
+ import path from 'node:path'
3
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
4
+
5
+ import cli from '../src/cli.js'
6
+
7
+ const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
8
+ const groupChoiceCDDL = path.join(__dirname, '..', '..', '..', 'examples', 'commons', 'group_choice.cddl')
9
+
10
+ vi.mock('../src/constants', () => ({
11
+ pkg: {
12
+ name: 'cddl2ts',
13
+ version: '0.0.0'
14
+ }
15
+ }))
16
+
17
+ describe('group choice conversion', () => {
18
+ let exitOrig = process.exit
19
+ let logOrig = console.log
20
+ let errorOrig = console.error
21
+
22
+ beforeEach(() => {
23
+ process.exit = vi.fn() as any
24
+ console.log = vi.fn()
25
+ console.error = vi.fn()
26
+ })
27
+
28
+ afterEach(() => {
29
+ process.exit = exitOrig
30
+ console.log = logOrig
31
+ console.error = errorOrig
32
+ })
33
+
34
+ it('should generate a union type for multiple group choices', async () => {
35
+ await cli([groupChoiceCDDL, '--unknown-as-any'])
36
+
37
+ expect(process.exit).not.toHaveBeenCalledWith(1)
38
+ expect(console.error).not.toHaveBeenCalled()
39
+ expect(console.log).toHaveBeenCalled()
40
+ const output = vi.mocked(console.log).mock.calls.flat().join('\n')
41
+
42
+ // Verify it generates a union of all 3 types
43
+ expect(output).toContain('export type ProxyConfiguration = AutodetectProxyConfiguration | DirectProxyConfiguration | ManualProxyConfiguration')
44
+
45
+ // Verify interfaces are generated comfortably
46
+ // Note: As we now use Type Alias intersections for mixins instead of interfaces extends to support union mixins,
47
+ // these assertions are updated to expect type aliases.
48
+ expect(output).toContain('export type AutodetectProxyConfiguration = Extensible & {')
49
+ expect(output).toContain('export type DirectProxyConfiguration = Extensible & {')
50
+
51
+ expect(output).toMatchSnapshot()
52
+ })
53
+ })
@@ -0,0 +1,45 @@
1
+ import url from 'node:url'
2
+ import path from 'node:path'
3
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
4
+
5
+ import cli from '../src/cli.js'
6
+
7
+ const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
8
+ const cddlFile = path.join(__dirname, '..', '..', '..', 'examples', 'commons', 'literals.cddl')
9
+
10
+ vi.mock('../src/constants', () => ({
11
+ pkg: {
12
+ name: 'cddl2ts',
13
+ version: '0.0.0'
14
+ }
15
+ }))
16
+
17
+ describe('literals', () => {
18
+ let exitOrig = process.exit
19
+ let logOrig = console.log
20
+ let errorOrig = console.error
21
+
22
+ beforeEach(() => {
23
+ process.exit = vi.fn() as any
24
+ console.log = vi.fn()
25
+ console.error = vi.fn()
26
+ })
27
+
28
+ afterEach(() => {
29
+ process.exit = exitOrig
30
+ console.log = logOrig
31
+ console.error = errorOrig
32
+ })
33
+
34
+ it('should support bigint and null literals', async () => {
35
+ await cli([cddlFile])
36
+
37
+ expect(process.exit).not.toHaveBeenCalledWith(1)
38
+ expect(console.error).not.toHaveBeenCalled()
39
+
40
+ const output = vi.mocked(console.log).mock.calls.flat().join('\n')
41
+
42
+ // Assert output structure
43
+ expect(output).toMatchSnapshot()
44
+ })
45
+ })
@@ -0,0 +1,56 @@
1
+ import url from 'node:url'
2
+ import path from 'node:path'
3
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
4
+
5
+ import cli from '../src/cli.js'
6
+
7
+ const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
8
+ const cddlFile = path.join(__dirname, '..', '..', '..', 'examples', 'commons', 'mixin_union.cddl')
9
+
10
+ vi.mock('../src/constants', () => ({
11
+ pkg: {
12
+ name: 'cddl2ts',
13
+ version: '0.0.0'
14
+ }
15
+ }))
16
+
17
+ describe('mixin union types', () => {
18
+ let exitOrig = process.exit
19
+ let logOrig = console.log
20
+ let errorOrig = console.error
21
+
22
+ beforeEach(() => {
23
+ process.exit = vi.fn() as any
24
+ console.log = vi.fn()
25
+ console.error = vi.fn()
26
+ })
27
+
28
+ afterEach(() => {
29
+ process.exit = exitOrig
30
+ console.log = logOrig
31
+ console.error = errorOrig
32
+ })
33
+
34
+ it('should generate union type aliases for mixin choices', async () => {
35
+ await cli([cddlFile])
36
+
37
+ expect(process.exit).not.toHaveBeenCalledWith(1)
38
+ expect(console.error).not.toHaveBeenCalled()
39
+
40
+ const output = vi.mocked(console.log).mock.calls.flat().join('\n')
41
+
42
+ // Check if Mixins is parsed correctly (intersection)
43
+ expect(output).toContain('export type Mixins = MixinA & MixinB')
44
+
45
+ // Check if UnionMixin is parsed correctly (single choice group)
46
+ // Group = (A / B) -> usually parsed as a choice of properties in the group
47
+
48
+ // More importantly for the queried code block:
49
+ // ComplexMixins = ((MixinA / MixinB), c: bool)
50
+ // This means it has a mixin that is a choice between MixinA and MixinB
51
+
52
+ // We expect something like:
53
+ // export type ComplexMixins = (MixinA | MixinB) & { c: boolean }
54
+ expect(output).toMatchSnapshot()
55
+ })
56
+ })
@@ -0,0 +1,74 @@
1
+ import url from 'node:url'
2
+ import path from 'node:path'
3
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
4
+
5
+ import cli from '../src/cli.js'
6
+
7
+ const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
8
+
9
+ vi.mock('../src/constants', () => ({
10
+ pkg: {
11
+ name: 'foobar',
12
+ version: '1.2.3'
13
+ }
14
+ }))
15
+
16
+ describe('cddl2ts', () => {
17
+ const exitOrig = process.exit.bind(process)
18
+ const logOrig = console.log.bind(console)
19
+ const errorOrig = console.error.bind(console)
20
+ beforeEach(() => {
21
+ // @ts-expect-error
22
+ process.exit = vi.fn(() => {})
23
+ console.log = vi.fn()
24
+ console.error = vi.fn()
25
+ })
26
+
27
+ it('should print help if no args were provided', async () => {
28
+ await cli([])
29
+
30
+ expect(console.error).toHaveBeenCalledWith(expect.stringMatching(/foobar/)) // Yargs showHelp() defaults to stderr
31
+ expect(process.exit).toHaveBeenCalledWith(0)
32
+ })
33
+
34
+ it('should print help --help is set in args', async () => {
35
+ await cli(['foo', 'bar', '--help', 'barfoo'])
36
+
37
+ expect(console.log).toHaveBeenCalledWith(expect.stringMatching(/foobar/))
38
+ expect(process.exit).toHaveBeenCalledWith(0)
39
+ })
40
+
41
+ it('should print version (alias)', async () => {
42
+ await cli(['foo', '-v', 'bar'])
43
+
44
+ expect(console.log).toHaveBeenCalledWith('1.2.3')
45
+ expect(process.exit).toHaveBeenCalledWith(0)
46
+ })
47
+
48
+ it('should print version (long flag)', async () => {
49
+ await cli(['foo', '--version', 'bar'])
50
+
51
+ expect(console.log).toHaveBeenCalledWith('1.2.3')
52
+ expect(process.exit).toHaveBeenCalledWith(0)
53
+ })
54
+
55
+ it('should fail if first parameter is not pointing to a file', async () => {
56
+ await cli(['foo'])
57
+
58
+ expect(console.error).toHaveBeenCalledTimes(1)
59
+ expect(process.exit).toHaveBeenCalledWith(1)
60
+ })
61
+
62
+ it('should generate correct types for test.cddl', async () => {
63
+ await cli([path.join(__dirname, '..', '..', '..', 'examples', 'commons', 'test.cddl')])
64
+
65
+ expect(vi.mocked(console.log).mock.calls).toMatchSnapshot()
66
+ expect(process.exit).toHaveBeenCalledTimes(0)
67
+ })
68
+
69
+ afterEach(() => {
70
+ process.exit = exitOrig
71
+ console.log = logOrig
72
+ console.error = errorOrig
73
+ })
74
+ })
@@ -0,0 +1,47 @@
1
+ import url from 'node:url'
2
+ import path from 'node:path'
3
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
4
+
5
+ import cli from '../src/cli.js'
6
+
7
+ const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
8
+ const cddlFile = path.join(__dirname, '..', '..', '..', 'examples', 'commons', 'named_group_choice.cddl')
9
+
10
+ vi.mock('../src/constants', () => ({
11
+ pkg: {
12
+ name: 'cddl2ts',
13
+ version: '0.0.0'
14
+ }
15
+ }))
16
+
17
+ describe('named group choice', () => {
18
+ let exitOrig = process.exit
19
+ let logOrig = console.log
20
+ let errorOrig = console.error
21
+
22
+ beforeEach(() => {
23
+ process.exit = vi.fn() as any
24
+ console.log = vi.fn()
25
+ console.error = vi.fn()
26
+ })
27
+
28
+ afterEach(() => {
29
+ process.exit = exitOrig
30
+ console.log = logOrig
31
+ console.error = errorOrig
32
+ })
33
+
34
+ it('should generate a union type alias for named group references', async () => {
35
+ await cli([cddlFile])
36
+
37
+ expect(process.exit).not.toHaveBeenCalledWith(1)
38
+ expect(console.error).not.toHaveBeenCalled()
39
+
40
+ const output = vi.mocked(console.log).mock.calls.flat().join('\n')
41
+
42
+ // The export keyword is separated from the type definition by comments
43
+ expect(output).toMatch(/export\s+(\/\/.*\n)+\s*type Choice = OptionA \| OptionB/)
44
+ expect(output).toContain('export interface OptionA {')
45
+ expect(output).toContain('export interface OptionB {')
46
+ })
47
+ })
@@ -0,0 +1,21 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { transform } from '../src/index.js'
3
+ import type { Variable } from 'cddl'
4
+
5
+ describe('literal transformation direct', () => {
6
+ it('should transform bigint literals correctly', () => {
7
+ const assignment: Variable = {
8
+ Type: 'variable',
9
+ Name: 'MyBigInt',
10
+ PropertyType: {
11
+ Type: 'literal',
12
+ Value: 9007199254740995n
13
+ } as any,
14
+ Comments: [],
15
+ IsChoiceAddition: false
16
+ }
17
+
18
+ const output = transform([assignment])
19
+ expect(output).toContain('export type MyBigInt = 9007199254740995n;')
20
+ })
21
+ })
@@ -0,0 +1,51 @@
1
+ import url from 'node:url'
2
+ import path from 'node:path'
3
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
4
+
5
+ import cli from '../src/cli.js'
6
+
7
+ const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
8
+ const localCDDL = path.join(__dirname, '..', '..', '..', 'examples', 'commons', 'unknown.cddl')
9
+
10
+ vi.mock('../src/constants', () => ({
11
+ pkg: {
12
+ name: 'cddl2ts',
13
+ version: '0.0.0'
14
+ }
15
+ }))
16
+
17
+ describe('unknown option', () => {
18
+ let exitOrig = process.exit
19
+ let logOrig = console.log
20
+ let errorOrig = console.error
21
+
22
+ beforeEach(() => {
23
+ process.exit = vi.fn() as any
24
+ console.log = vi.fn()
25
+ console.error = vi.fn()
26
+ })
27
+
28
+ afterEach(() => {
29
+ process.exit = exitOrig
30
+ console.log = logOrig
31
+ console.error = errorOrig
32
+ })
33
+
34
+ it('should use unknown instead of any', async () => {
35
+ await cli([localCDDL, '--unknown-as-any'])
36
+
37
+ const output = vi.mocked(console.log).mock.calls.flat().join('\n')
38
+ expect(output).toContain('export type Foo = unknown;')
39
+ expect(output).toContain('export type Bar = unknown[];')
40
+ expect(output).toContain('export type Baz = Record<string, unknown>;')
41
+ })
42
+
43
+ it('should default to any', async () => {
44
+ await cli([localCDDL])
45
+
46
+ const output = vi.mocked(console.log).mock.calls.flat().join('\n')
47
+ expect(output).toContain('export type Foo = any;')
48
+ expect(output).toContain('export type Bar = any[];')
49
+ expect(output).toContain('export type Baz = Record<string, any>;')
50
+ })
51
+ })
@@ -0,0 +1,43 @@
1
+ import url from 'node:url'
2
+ import path from 'node:path'
3
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
4
+
5
+ import cli from '../src/cli.js'
6
+
7
+ const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
8
+ const localCDDL = path.join(__dirname, '..', '..', '..', 'examples', 'webdriver', 'local.cddl')
9
+
10
+ vi.mock('../src/constants', () => ({
11
+ pkg: {
12
+ name: 'cddl2ts',
13
+ version: '0.0.0'
14
+ }
15
+ }))
16
+
17
+ describe('webdriver examples', () => {
18
+ let exitOrig = process.exit
19
+ let logOrig = console.log
20
+ let errorOrig = console.error
21
+
22
+ beforeEach(() => {
23
+ process.exit = vi.fn() as any
24
+ console.log = vi.fn()
25
+ console.error = vi.fn()
26
+ })
27
+
28
+ afterEach(() => {
29
+ process.exit = exitOrig
30
+ console.log = logOrig
31
+ console.error = errorOrig
32
+ })
33
+
34
+ it('should generate types for local.cddl', async () => {
35
+ await cli([localCDDL, '--unknown-as-any'])
36
+
37
+ expect(process.exit).not.toHaveBeenCalledWith(1)
38
+ expect(console.error).not.toHaveBeenCalled()
39
+ expect(console.log).toHaveBeenCalled()
40
+ const output = vi.mocked(console.log).mock.calls.flat().join('\n')
41
+ expect(output).toMatchSnapshot()
42
+ })
43
+ })
@@ -0,0 +1,43 @@
1
+ import url from 'node:url'
2
+ import path from 'node:path'
3
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
4
+
5
+ import cli from '../src/cli.js'
6
+
7
+ const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
8
+ const remoteCDDL = path.join(__dirname, '..', '..', '..', 'examples', 'webdriver', 'remote.cddl')
9
+
10
+ vi.mock('../src/constants', () => ({
11
+ pkg: {
12
+ name: 'cddl2ts',
13
+ version: '0.0.0'
14
+ }
15
+ }))
16
+
17
+ describe('webdriver examples', () => {
18
+ let exitOrig = process.exit
19
+ let logOrig = console.log
20
+ let errorOrig = console.error
21
+
22
+ beforeEach(() => {
23
+ process.exit = vi.fn() as any
24
+ console.log = vi.fn()
25
+ console.error = vi.fn()
26
+ })
27
+
28
+ afterEach(() => {
29
+ process.exit = exitOrig
30
+ console.log = logOrig
31
+ console.error = errorOrig
32
+ })
33
+
34
+ it('should generate types for remote.cddl', async () => {
35
+ await cli([remoteCDDL, '--unknown-as-any'])
36
+
37
+ expect(process.exit).not.toHaveBeenCalledWith(1)
38
+ expect(console.error).not.toHaveBeenCalled()
39
+ expect(console.log).toHaveBeenCalled()
40
+ const output = vi.mocked(console.log).mock.calls.flat().join('\n')
41
+ expect(output).toMatchSnapshot()
42
+ })
43
+ })
package/tsconfig.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "../../tsconfig",
3
+ "compilerOptions": {
4
+ "outDir": "build",
5
+ "rootDir": "src",
6
+ },
7
+ "types": ["node"],
8
+ "include": [
9
+ "src/**/*",
10
+ ]
11
+ }