steelseries-sonar-sdk 0.1.1

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.
Files changed (118) hide show
  1. package/.gitattributes +8 -0
  2. package/.github/workflows/tests.yml +18 -0
  3. package/.vscode/extensions.json +8 -0
  4. package/.vscode/settings.json +33 -0
  5. package/LICENSE +21 -0
  6. package/README.md +121 -0
  7. package/_.todo +4 -0
  8. package/biome.json +62 -0
  9. package/http/sonar.http +104 -0
  10. package/package.json +31 -0
  11. package/src/consts/fetch-options-put.ts +3 -0
  12. package/src/enums.ts +88 -0
  13. package/src/exceptions.ts +45 -0
  14. package/src/functions/audio/get-audio-data-classic.ts +31 -0
  15. package/src/functions/audio/get-audio-data-stream.ts +37 -0
  16. package/src/functions/audio/get-audio-mode.ts +11 -0
  17. package/src/functions/audio/set-audio-mode.ts +12 -0
  18. package/src/functions/audio/set-channel-mute-classic.ts +35 -0
  19. package/src/functions/audio/set-channel-mute-streamer.ts +41 -0
  20. package/src/functions/audio/set-channel-volume-classic.ts +37 -0
  21. package/src/functions/audio/set-channel-volume-streamer.ts +43 -0
  22. package/src/functions/chatmix/get-chat-mix-state.ts +20 -0
  23. package/src/functions/chatmix/set-chat-mix-balance.ts +22 -0
  24. package/src/functions/converters/convert-channel-to-api.ts +19 -0
  25. package/src/functions/converters/convert-chat-mix-balance-to-api.ts +6 -0
  26. package/src/functions/converters/convert-chat-mix-balance-to-user.ts +7 -0
  27. package/src/functions/converters/convert-profile-channel-to-api.ts +19 -0
  28. package/src/functions/converters/convert-profile-channel-to-user.ts +19 -0
  29. package/src/functions/converters/convert-volume-to-api.ts +5 -0
  30. package/src/functions/converters/convert-volume-to-user.ts +6 -0
  31. package/src/functions/devices/get-audio-devices.ts +40 -0
  32. package/src/functions/devices/set-audio-device.ts +19 -0
  33. package/src/functions/endpoint/get-app-endpoint.ts +73 -0
  34. package/src/functions/endpoint/get-sonar-endpoint-cached.ts +28 -0
  35. package/src/functions/endpoint/get-sonar-endpoint.ts +88 -0
  36. package/src/functions/profile/get-channel-profiles.ts +26 -0
  37. package/src/functions/profile/get-selected-profiles.ts +17 -0
  38. package/src/functions/profile/set-selected-profile.ts +17 -0
  39. package/src/index.ts +41 -0
  40. package/src/sonar/models/audio-settings/chatmix-data.ts +6 -0
  41. package/src/sonar/models/audio-settings/enums/audio-mode.ts +4 -0
  42. package/src/sonar/models/audio-settings/enums/chat-mix-state.ts +6 -0
  43. package/src/sonar/models/audio-settings/enums/device-data-flow.ts +5 -0
  44. package/src/sonar/models/audio-settings/enums/device-default-roles.ts +6 -0
  45. package/src/sonar/models/audio-settings/enums/device-role.ts +9 -0
  46. package/src/sonar/models/audio-settings/enums/device-state.ts +8 -0
  47. package/src/sonar/models/audio-settings/enums/sonar-channel.ts +8 -0
  48. package/src/sonar/models/audio-settings/enums/streaming-path.ts +4 -0
  49. package/src/sonar/models/audio-settings/volume-info-classic.ts +4 -0
  50. package/src/sonar/models/audio-settings/volume-info-streamer.ts +10 -0
  51. package/src/sonar/models/audio-settings/volume-settings-classic.ts +13 -0
  52. package/src/sonar/models/audio-settings/volume-settings-streamer.ts +13 -0
  53. package/src/sonar/models/config/config.ts +9 -0
  54. package/src/sonar/models/config/enums/VirtualAudioDevice.ts +7 -0
  55. package/src/sonar/models/devices/audio-device.ts +17 -0
  56. package/src/sonar/models/devices/changed-device.ts +7 -0
  57. package/src/sonar/requests/audio-devices/change-audio-device.ts +37 -0
  58. package/src/sonar/requests/audio-devices/request-audio-devices.ts +42 -0
  59. package/src/sonar/requests/chatmix/change-chat-mix-balance.ts +25 -0
  60. package/src/sonar/requests/chatmix/request-chat-mix-state.ts +24 -0
  61. package/src/sonar/requests/mode/change-audio-mode.ts +24 -0
  62. package/src/sonar/requests/mode/request-audio-mode.ts +24 -0
  63. package/src/sonar/requests/profiles/change-selected-config.ts +25 -0
  64. package/src/sonar/requests/profiles/request-configs.ts +24 -0
  65. package/src/sonar/requests/profiles/request-selected-configs.ts +22 -0
  66. package/src/sonar/requests/volume-settings/change-volume-level-classic.ts +27 -0
  67. package/src/sonar/requests/volume-settings/change-volume-level-streamer.ts +29 -0
  68. package/src/sonar/requests/volume-settings/change-volume-mute-classic.ts +27 -0
  69. package/src/sonar/requests/volume-settings/change-volume-mute-streamer.ts +29 -0
  70. package/src/sonar/requests/volume-settings/request-volume-settings-classic.ts +22 -0
  71. package/src/sonar/requests/volume-settings/request-volume-settings-streamer.ts +22 -0
  72. package/src/types/audio-device.ts +7 -0
  73. package/src/types/changed-device.ts +7 -0
  74. package/src/types/channel-volume-classic.ts +4 -0
  75. package/src/types/channel-volume-streamer-path.ts +4 -0
  76. package/src/types/channel-volume-streamer.ts +6 -0
  77. package/src/types/channel-volumes-classic.ts +8 -0
  78. package/src/types/channel-volumes-streamer.ts +8 -0
  79. package/src/types/chat-mix-data.ts +7 -0
  80. package/src/types/profile-option.ts +9 -0
  81. package/tests/e2e/audio/get-audio-data-classic.real.test.ts +11 -0
  82. package/tests/e2e/audio/get-audio-data-stream.real.test.ts +11 -0
  83. package/tests/e2e/audio/get-audio-mode.real.test.ts +12 -0
  84. package/tests/e2e/audio/set-audio-mode.real.test.ts +20 -0
  85. package/tests/e2e/audio/set-channel-mute-classic.real.test.ts +18 -0
  86. package/tests/e2e/audio/set-channel-mute-streamer.real.test.ts +18 -0
  87. package/tests/e2e/audio/set-channel-volume-classic.real.test.ts +17 -0
  88. package/tests/e2e/audio/set-channel-volume-streamer.real.test.ts +22 -0
  89. package/tests/e2e/chatmix/get-chat-mix-state.real.test.ts +25 -0
  90. package/tests/e2e/chatmix/set-chat-mix-balance.real.test.ts +25 -0
  91. package/tests/e2e/devices/get-audio-devices.real.test.ts +29 -0
  92. package/tests/e2e/devices/set-audio-device.real.test.ts +32 -0
  93. package/tests/e2e/enpoint/get-app-endpoint.real.test.ts +19 -0
  94. package/tests/e2e/enpoint/get-sonar-endpoint-cached.real.test.ts +32 -0
  95. package/tests/e2e/enpoint/get-sonar-endpoint.real.test.ts +21 -0
  96. package/tests/e2e/profiles/get-channel-profiles.real.test.ts +21 -0
  97. package/tests/e2e/profiles/get-selected-profiles.real.test.ts +11 -0
  98. package/tests/e2e/profiles/set-selected-profile.real.test.ts +17 -0
  99. package/tests/helpers/get-endpoint-e2e.ts +8 -0
  100. package/tests/unit/audio/get-audio-data-classic.test.ts +57 -0
  101. package/tests/unit/audio/get-audio-data-stream.test.ts +65 -0
  102. package/tests/unit/audio/get-audio-mode.test.ts +58 -0
  103. package/tests/unit/audio/set-audio-mode.test.ts +66 -0
  104. package/tests/unit/audio/set-channel-mute-classic.test.ts +58 -0
  105. package/tests/unit/audio/set-channel-mute-streamer.test.ts +64 -0
  106. package/tests/unit/audio/set-channel-volume-classic.test.ts +58 -0
  107. package/tests/unit/audio/set-channel-volume-streamer.test.ts +64 -0
  108. package/tests/unit/chatmix/get-chat-mix-state.test.ts +70 -0
  109. package/tests/unit/chatmix/set-chat-mix-balance.test.ts +58 -0
  110. package/tests/unit/devices/get-audio-devices.test.ts +59 -0
  111. package/tests/unit/devices/set-audio-devices.test.ts +62 -0
  112. package/tests/unit/endpoint/get-app-endpoint.test.ts +72 -0
  113. package/tests/unit/endpoint/get-sonar-endpoint-cached.test.ts +93 -0
  114. package/tests/unit/endpoint/get-sonar-endpoint.test.ts +140 -0
  115. package/tests/unit/profiles/get-channel-profiles.test.ts +91 -0
  116. package/tests/unit/profiles/get-selected-profiles.test.ts +64 -0
  117. package/tests/unit/profiles/set-selected-profile.test.ts +55 -0
  118. package/tsconfig.json +36 -0
@@ -0,0 +1,140 @@
1
+ import { afterEach, beforeEach, describe, expect, it } from 'bun:test'
2
+ import { InitializeErrorReason, SonarInitializationException } from '../../../src/exceptions'
3
+ import { getSonarEndpoint } from '../../../src/functions/endpoint/get-sonar-endpoint'
4
+
5
+ let originalFetch: typeof fetch
6
+
7
+ const request = () => getSonarEndpoint('')
8
+
9
+ describe('getSonarEndpoint', () => {
10
+ beforeEach(() => {
11
+ originalFetch = globalThis.fetch
12
+ })
13
+
14
+ afterEach(() => {
15
+ globalThis.fetch = originalFetch
16
+ })
17
+
18
+ it('throws NotEnabled Exception if sonar is not enabled', async () => {
19
+ globalThis.fetch = (async () =>
20
+ ({
21
+ ok: true,
22
+ json: async () => ({
23
+ subApps: {
24
+ sonar: {
25
+ isEnabled: false,
26
+ isReady: true,
27
+ isRunning: true,
28
+ metadata: { webServerAddress: '127.0.0.1:1234' }
29
+ }
30
+ }
31
+ })
32
+ }) as Response) as unknown as typeof fetch
33
+
34
+ const rejects = expect(request()).rejects
35
+ rejects.toThrow(SonarInitializationException)
36
+ rejects.toMatchObject({ reason: InitializeErrorReason.NotEnabled })
37
+ })
38
+
39
+ it('throws NotReady Exception if sonar is not ready', async () => {
40
+ globalThis.fetch = (async () =>
41
+ ({
42
+ ok: true,
43
+ json: async () => ({
44
+ subApps: {
45
+ sonar: {
46
+ isEnabled: true,
47
+ isReady: false,
48
+ isRunning: true,
49
+ metadata: { webServerAddress: '127.0.0.1:1234' }
50
+ }
51
+ }
52
+ })
53
+ }) as Response) as unknown as typeof fetch
54
+
55
+ const rejects = expect(request()).rejects
56
+ rejects.toThrow(SonarInitializationException)
57
+ rejects.toMatchObject({ reason: InitializeErrorReason.NotReady })
58
+ })
59
+
60
+ it('throws NotRunning Exception if sonar is not running', async () => {
61
+ globalThis.fetch = (async () =>
62
+ ({
63
+ ok: true,
64
+ json: async () => ({
65
+ subApps: {
66
+ sonar: {
67
+ isEnabled: true,
68
+ isReady: true,
69
+ isRunning: false,
70
+ metadata: { webServerAddress: '127.0.0.1:1234' }
71
+ }
72
+ }
73
+ })
74
+ }) as Response) as unknown as typeof fetch
75
+
76
+ const rejects = expect(request()).rejects
77
+ rejects.toThrow(SonarInitializationException)
78
+ rejects.toMatchObject({ reason: InitializeErrorReason.NotRunning })
79
+ })
80
+
81
+ it('throws NotResponding Exception if sonar server is not found', async () => {
82
+ globalThis.fetch = (async () => {
83
+ throw new Error('Failed to fetch')
84
+ }) as unknown as typeof fetch
85
+ const rejects = expect(request()).rejects
86
+ rejects.toThrow(SonarInitializationException)
87
+ rejects.toMatchObject({ reason: InitializeErrorReason.NotResponding })
88
+ })
89
+
90
+ it('throws NotResponding Exception if sonar server returns bad status code', async () => {
91
+ globalThis.fetch = (async () =>
92
+ ({
93
+ ok: false
94
+ }) as Response) as unknown as typeof fetch
95
+ const rejects = expect(request()).rejects
96
+ rejects.toThrow(SonarInitializationException)
97
+ rejects.toMatchObject({ reason: InitializeErrorReason.NotResponding })
98
+ })
99
+
100
+ it('throws NotAvailable Exception if sonar webServerAddress is not provided', async () => {
101
+ globalThis.fetch = (async () =>
102
+ ({
103
+ ok: true,
104
+ json: async () => ({
105
+ subApps: {
106
+ sonar: {
107
+ isEnabled: true,
108
+ isReady: true,
109
+ isRunning: true
110
+ }
111
+ }
112
+ })
113
+ }) as Response) as unknown as typeof fetch
114
+
115
+ const rejects = expect(request()).rejects
116
+ rejects.toThrow(SonarInitializationException)
117
+ rejects.toMatchObject({ reason: InitializeErrorReason.NotAvailable })
118
+ })
119
+
120
+ it('return Sonar webServerAddress when response is valid', async () => {
121
+ const expectedWebServerAddress = 'https://127.0.0.1:1234'
122
+
123
+ globalThis.fetch = (async () =>
124
+ ({
125
+ ok: true,
126
+ json: async () => ({
127
+ subApps: {
128
+ sonar: {
129
+ isEnabled: true,
130
+ isReady: true,
131
+ isRunning: true,
132
+ metadata: { webServerAddress: expectedWebServerAddress }
133
+ }
134
+ }
135
+ })
136
+ }) as Response) as unknown as typeof fetch
137
+
138
+ expect(getSonarEndpoint('')).resolves.toBe(expectedWebServerAddress)
139
+ })
140
+ })
@@ -0,0 +1,91 @@
1
+ import { afterEach, beforeEach, describe, expect, it } from 'bun:test'
2
+ import { ProfileChannel } from '@/enums'
3
+ import { SonarRequestException } from '@/exceptions'
4
+ import { getChannelProfiles } from '@/functions/profile/get-channel-profiles'
5
+ import { VirtualAudioDevice } from '@/sonar/models/config/enums/VirtualAudioDevice'
6
+
7
+ let originalFetch: typeof fetch
8
+
9
+ const request = (favorite?: boolean) => getChannelProfiles('http://localhost', ProfileChannel.Media, favorite)
10
+
11
+ describe('getChannelProfiles', () => {
12
+ beforeEach(() => {
13
+ originalFetch = globalThis.fetch
14
+ })
15
+
16
+ afterEach(() => {
17
+ globalThis.fetch = originalFetch
18
+ })
19
+
20
+ it('throws SonarException when response not 200', async () => {
21
+ globalThis.fetch = (async () =>
22
+ ({
23
+ ok: false,
24
+ json: async () => 'Some error occurred'
25
+ }) as Response) as unknown as typeof fetch
26
+
27
+ expect(request()).rejects.toThrow(SonarRequestException)
28
+ })
29
+
30
+ it('throws SonarException when response 200 but not data', async () => {
31
+ globalThis.fetch = (async () =>
32
+ ({
33
+ ok: true,
34
+ json: async () => ({})
35
+ }) as Response) as unknown as typeof fetch
36
+
37
+ expect(request()).rejects.toThrow(SonarRequestException)
38
+ })
39
+
40
+ it('return data when response 200', async () => {
41
+ globalThis.fetch = (async () =>
42
+ ({
43
+ ok: true,
44
+ json: async () => [
45
+ {
46
+ id: 'one',
47
+ name: 'one',
48
+ isFavorite: true,
49
+ virtualAudioDevice: VirtualAudioDevice.Game,
50
+ image: 'string'
51
+ },
52
+ {
53
+ id: 'two',
54
+ name: 'two',
55
+ isFavorite: false,
56
+ virtualAudioDevice: VirtualAudioDevice.Game,
57
+ image: 'string'
58
+ }
59
+ ]
60
+ }) as Response) as unknown as typeof fetch
61
+
62
+ const response = await request()
63
+ expect(response.length).toBe(2)
64
+ })
65
+
66
+ it('return favorites data when response 200', async () => {
67
+ globalThis.fetch = (async () =>
68
+ ({
69
+ ok: true,
70
+ json: async () => [
71
+ {
72
+ id: 'one',
73
+ name: 'one',
74
+ isFavorite: true,
75
+ virtualAudioDevice: VirtualAudioDevice.Game,
76
+ image: 'string'
77
+ },
78
+ {
79
+ id: 'two',
80
+ name: 'two',
81
+ isFavorite: false,
82
+ virtualAudioDevice: VirtualAudioDevice.Game,
83
+ image: 'string'
84
+ }
85
+ ]
86
+ }) as Response) as unknown as typeof fetch
87
+
88
+ const response = await request(true)
89
+ expect(response.length).toBe(1)
90
+ })
91
+ })
@@ -0,0 +1,64 @@
1
+ import { afterEach, beforeEach, describe, expect, it } from 'bun:test'
2
+ import { SonarRequestException } from '@/exceptions'
3
+ import { getSelectedProfiles } from '@/functions/profile/get-selected-profiles'
4
+ import { VirtualAudioDevice } from '@/sonar/models/config/enums/VirtualAudioDevice'
5
+
6
+ let originalFetch: typeof fetch
7
+
8
+ const request = () => getSelectedProfiles('http://localhost')
9
+
10
+ describe('getSelectedProfiles', () => {
11
+ beforeEach(() => {
12
+ originalFetch = globalThis.fetch
13
+ })
14
+
15
+ afterEach(() => {
16
+ globalThis.fetch = originalFetch
17
+ })
18
+
19
+ it('throws SonarException when response not 200', async () => {
20
+ globalThis.fetch = (async () =>
21
+ ({
22
+ ok: false,
23
+ json: async () => 'Some error occurred'
24
+ }) as Response) as unknown as typeof fetch
25
+
26
+ expect(request()).rejects.toThrow(SonarRequestException)
27
+ })
28
+
29
+ it('throws SonarException when response 200 but not data', async () => {
30
+ globalThis.fetch = (async () =>
31
+ ({
32
+ ok: true,
33
+ json: async () => ({})
34
+ }) as Response) as unknown as typeof fetch
35
+
36
+ expect(request()).rejects.toThrow(SonarRequestException)
37
+ })
38
+
39
+ it('return data when response 200', async () => {
40
+ globalThis.fetch = (async () =>
41
+ ({
42
+ ok: true,
43
+ json: async () => [
44
+ {
45
+ id: 'one',
46
+ name: 'one',
47
+ isFavorite: true,
48
+ virtualAudioDevice: VirtualAudioDevice.Game,
49
+ image: 'string'
50
+ },
51
+ {
52
+ id: 'two',
53
+ name: 'two',
54
+ isFavorite: false,
55
+ virtualAudioDevice: VirtualAudioDevice.Media,
56
+ image: 'string'
57
+ }
58
+ ]
59
+ }) as Response) as unknown as typeof fetch
60
+
61
+ const response = await request()
62
+ expect(response.length).toBe(2)
63
+ })
64
+ })
@@ -0,0 +1,55 @@
1
+ import { afterEach, beforeEach, describe, expect, it } from 'bun:test'
2
+ import { SonarRequestException } from '@/exceptions'
3
+ import { setSelectedProfile } from '@/functions/profile/set-selected-profile'
4
+ import { VirtualAudioDevice } from '@/sonar/models/config/enums/VirtualAudioDevice'
5
+
6
+ let originalFetch: typeof fetch
7
+
8
+ const request = () => setSelectedProfile('http://localhost', 'one')
9
+
10
+ describe('setSelectedProfile', () => {
11
+ beforeEach(() => {
12
+ originalFetch = globalThis.fetch
13
+ })
14
+
15
+ afterEach(() => {
16
+ globalThis.fetch = originalFetch
17
+ })
18
+
19
+ it('throws SonarException when response not 200', async () => {
20
+ globalThis.fetch = (async () =>
21
+ ({
22
+ ok: false,
23
+ json: async () => 'Some error occurred'
24
+ }) as Response) as unknown as typeof fetch
25
+
26
+ expect(request()).rejects.toThrow(SonarRequestException)
27
+ })
28
+
29
+ it('throws SonarException when response 200 but not data', async () => {
30
+ globalThis.fetch = (async () =>
31
+ ({
32
+ ok: true,
33
+ json: async () => ({})
34
+ }) as Response) as unknown as typeof fetch
35
+
36
+ expect(request()).rejects.toThrow(SonarRequestException)
37
+ })
38
+
39
+ it('return data when response 200', async () => {
40
+ globalThis.fetch = (async () =>
41
+ ({
42
+ ok: true,
43
+ json: async () => ({
44
+ id: 'one',
45
+ name: 'one',
46
+ isFavorite: true,
47
+ virtualAudioDevice: VirtualAudioDevice.Game,
48
+ image: 'string'
49
+ })
50
+ }) as Response) as unknown as typeof fetch
51
+
52
+ const response = await request()
53
+ expect(response.id).toBe('one')
54
+ })
55
+ })
package/tsconfig.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "compilerOptions": {
3
+ // Environment setup & latest features
4
+ "lib": ["ESNext"],
5
+ "target": "ESNext",
6
+ "module": "Preserve",
7
+ "moduleDetection": "force",
8
+ "jsx": "react-jsx",
9
+ "allowJs": true,
10
+
11
+ // Bundler mode
12
+ "moduleResolution": "bundler",
13
+ "allowImportingTsExtensions": true,
14
+ "verbatimModuleSyntax": true,
15
+ "noEmit": true,
16
+
17
+ // Best practices
18
+ "strict": true,
19
+ "skipLibCheck": true,
20
+ "noFallthroughCasesInSwitch": true,
21
+ "noUncheckedIndexedAccess": true,
22
+ "noImplicitOverride": true,
23
+
24
+ // Some stricter flags (disabled by default)
25
+ "noUnusedLocals": false,
26
+ "noUnusedParameters": false,
27
+ "noPropertyAccessFromIndexSignature": false,
28
+
29
+ // Path alias for '@' to 'src/'
30
+ "baseUrl": ".",
31
+ "paths": {
32
+ "@/*": ["src/*"]
33
+ }
34
+ },
35
+ "exclude": ["dist"]
36
+ }