@coffeerunhobby/mcp-ha-connect 2.2.1 → 2.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.
Files changed (293) hide show
  1. package/.env.example +1 -1
  2. package/README.md +24 -2
  3. package/dist/omadaClient/accessControl.d.ts +290 -0
  4. package/dist/omadaClient/accessControl.js +509 -0
  5. package/dist/omadaClient/accessControl.js.map +1 -0
  6. package/dist/omadaClient/client.d.ts +6 -1
  7. package/dist/omadaClient/client.js +12 -1
  8. package/dist/omadaClient/client.js.map +1 -1
  9. package/dist/omadaClient/diagnose.d.ts +68 -0
  10. package/dist/omadaClient/diagnose.js +164 -0
  11. package/dist/omadaClient/diagnose.js.map +1 -0
  12. package/dist/omadaClient/index.d.ts +9 -0
  13. package/dist/omadaClient/index.js +19 -0
  14. package/dist/omadaClient/index.js.map +1 -1
  15. package/dist/omadaClient/macGroups.d.ts +58 -0
  16. package/dist/omadaClient/macGroups.js +110 -0
  17. package/dist/omadaClient/macGroups.js.map +1 -0
  18. package/dist/omadaClient/serialize.d.ts +13 -0
  19. package/dist/omadaClient/serialize.js +29 -0
  20. package/dist/omadaClient/serialize.js.map +1 -0
  21. package/dist/omadaClient/timeRange.d.ts +41 -0
  22. package/dist/omadaClient/timeRange.js +109 -0
  23. package/dist/omadaClient/timeRange.js.map +1 -0
  24. package/dist/tools/infra/actions.d.ts +1 -1
  25. package/dist/tools/infra/actions.js +1 -1
  26. package/dist/tools/omada/accessControl.d.ts +151 -0
  27. package/dist/tools/omada/accessControl.js +158 -0
  28. package/dist/tools/omada/accessControl.js.map +1 -0
  29. package/dist/tools/omada/index.js +9 -0
  30. package/dist/tools/omada/index.js.map +1 -1
  31. package/dist/tools/omada/macGroups.d.ts +19 -0
  32. package/dist/tools/omada/macGroups.js +77 -0
  33. package/dist/tools/omada/macGroups.js.map +1 -0
  34. package/dist/tools/omada/namespace.js +16 -0
  35. package/dist/tools/omada/namespace.js.map +1 -1
  36. package/dist/version.d.ts +1 -1
  37. package/dist/version.js +1 -1
  38. package/package.json +5 -1
  39. package/.codex/review-rules.md +0 -16
  40. package/.dockerignore +0 -8
  41. package/.gitattributes +0 -30
  42. package/.github/workflows/ci.yml +0 -193
  43. package/AGENTS.md +0 -389
  44. package/Dockerfile +0 -50
  45. package/docker-compose.yml +0 -23
  46. package/docs/CHANGELOG.md +0 -341
  47. package/docs/COVERAGE.md +0 -219
  48. package/docs/QUICK_START.md +0 -240
  49. package/eslint.config.js +0 -33
  50. package/n8n/ai-agent-safety-monitor.json +0 -355
  51. package/openapi.json +0 -1259
  52. package/scripts/check-version-sync.mjs +0 -69
  53. package/scripts/generate-jwt.ts +0 -121
  54. package/src/config.ts +0 -440
  55. package/src/haClient/automations.ts +0 -261
  56. package/src/haClient/calendars.ts +0 -94
  57. package/src/haClient/config.ts +0 -52
  58. package/src/haClient/devices.ts +0 -653
  59. package/src/haClient/entities.ts +0 -128
  60. package/src/haClient/events.ts +0 -689
  61. package/src/haClient/history.ts +0 -73
  62. package/src/haClient/index.ts +0 -336
  63. package/src/haClient/request.ts +0 -142
  64. package/src/haClient/services.ts +0 -45
  65. package/src/haClient/states.ts +0 -60
  66. package/src/haClient/updates.ts +0 -58
  67. package/src/haClient/wsCommand.ts +0 -44
  68. package/src/index.ts +0 -164
  69. package/src/localAI/index.ts +0 -88
  70. package/src/localAI/prompts.ts +0 -50
  71. package/src/localAI/providers/base.ts +0 -120
  72. package/src/localAI/providers/ollama.ts +0 -78
  73. package/src/localAI/providers/openai.ts +0 -86
  74. package/src/localAI/types.ts +0 -67
  75. package/src/omadaClient/auth.ts +0 -178
  76. package/src/omadaClient/client.ts +0 -337
  77. package/src/omadaClient/device.ts +0 -118
  78. package/src/omadaClient/index.ts +0 -310
  79. package/src/omadaClient/network.ts +0 -284
  80. package/src/omadaClient/request.ts +0 -365
  81. package/src/omadaClient/security.ts +0 -51
  82. package/src/omadaClient/site.ts +0 -344
  83. package/src/ownerQuestions/service.ts +0 -536
  84. package/src/permissions/index.ts +0 -143
  85. package/src/resources/index.ts +0 -213
  86. package/src/server/auth.ts +0 -175
  87. package/src/server/chatFace.ts +0 -789
  88. package/src/server/chatSlice.ts +0 -57
  89. package/src/server/common.ts +0 -170
  90. package/src/server/eventSubscription.ts +0 -343
  91. package/src/server/http.ts +0 -626
  92. package/src/server/instructions.ts +0 -97
  93. package/src/server/rateLimiter.ts +0 -227
  94. package/src/server/stdio.ts +0 -41
  95. package/src/server/stream.ts +0 -205
  96. package/src/tools/ai/analyzeSensors.ts +0 -33
  97. package/src/tools/ai/index.ts +0 -20
  98. package/src/tools/common.ts +0 -442
  99. package/src/tools/homeassistant/askOwner.ts +0 -133
  100. package/src/tools/homeassistant/automationControls.ts +0 -66
  101. package/src/tools/homeassistant/calendar.ts +0 -97
  102. package/src/tools/homeassistant/callService.ts +0 -25
  103. package/src/tools/homeassistant/controlClimate.ts +0 -68
  104. package/src/tools/homeassistant/controlCover.ts +0 -48
  105. package/src/tools/homeassistant/controlFan.ts +0 -44
  106. package/src/tools/homeassistant/controlLight.ts +0 -38
  107. package/src/tools/homeassistant/controlMediaPlayer.ts +0 -50
  108. package/src/tools/homeassistant/createAutomation.ts +0 -35
  109. package/src/tools/homeassistant/deleteAutomation.ts +0 -24
  110. package/src/tools/homeassistant/entityAction.ts +0 -35
  111. package/src/tools/homeassistant/entityGuard.ts +0 -28
  112. package/src/tools/homeassistant/getAllSensors.ts +0 -46
  113. package/src/tools/homeassistant/getAutomationTrace.ts +0 -30
  114. package/src/tools/homeassistant/getDomainSummary.ts +0 -29
  115. package/src/tools/homeassistant/getEntitiesByDomain.ts +0 -56
  116. package/src/tools/homeassistant/getHistory.ts +0 -24
  117. package/src/tools/homeassistant/getState.ts +0 -24
  118. package/src/tools/homeassistant/getStates.ts +0 -46
  119. package/src/tools/homeassistant/getVersion.ts +0 -21
  120. package/src/tools/homeassistant/index.ts +0 -121
  121. package/src/tools/homeassistant/listAutomations.ts +0 -35
  122. package/src/tools/homeassistant/listEntities.ts +0 -44
  123. package/src/tools/homeassistant/listPersons.ts +0 -46
  124. package/src/tools/homeassistant/sceneAndScript.ts +0 -53
  125. package/src/tools/homeassistant/searchEntities.ts +0 -58
  126. package/src/tools/homeassistant/sendNotification.ts +0 -179
  127. package/src/tools/homeassistant/systemTools.ts +0 -52
  128. package/src/tools/homeassistant/triggerAutomation.ts +0 -24
  129. package/src/tools/index.ts +0 -78
  130. package/src/tools/infra/actions.ts +0 -95
  131. package/src/tools/infra/index.ts +0 -138
  132. package/src/tools/omada/blockClient.ts +0 -28
  133. package/src/tools/omada/cyclePoePort.ts +0 -32
  134. package/src/tools/omada/deleteClient.ts +0 -27
  135. package/src/tools/omada/disableClientRateLimit.ts +0 -23
  136. package/src/tools/omada/getClient.ts +0 -14
  137. package/src/tools/omada/getDevice.ts +0 -14
  138. package/src/tools/omada/getFirewallSetting.ts +0 -14
  139. package/src/tools/omada/getInternetInfo.ts +0 -14
  140. package/src/tools/omada/getLanNetworkList.ts +0 -14
  141. package/src/tools/omada/getLanProfileList.ts +0 -14
  142. package/src/tools/omada/getPortForwardingStatus.ts +0 -26
  143. package/src/tools/omada/getRateLimitProfiles.ts +0 -14
  144. package/src/tools/omada/getSiteNtpStatus.ts +0 -14
  145. package/src/tools/omada/getSsidDetail.ts +0 -22
  146. package/src/tools/omada/getSsidList.ts +0 -21
  147. package/src/tools/omada/getSwitchStackDetail.ts +0 -14
  148. package/src/tools/omada/getThreatList.ts +0 -42
  149. package/src/tools/omada/getWlanGroupList.ts +0 -14
  150. package/src/tools/omada/graph.ts +0 -187
  151. package/src/tools/omada/index.ts +0 -153
  152. package/src/tools/omada/listBlockedClients.ts +0 -17
  153. package/src/tools/omada/listClients.ts +0 -14
  154. package/src/tools/omada/listClientsActivity.ts +0 -25
  155. package/src/tools/omada/listClientsPastConnections.ts +0 -44
  156. package/src/tools/omada/listDevices.ts +0 -14
  157. package/src/tools/omada/listDevicesStats.ts +0 -41
  158. package/src/tools/omada/listMostActiveClients.ts +0 -14
  159. package/src/tools/omada/listSites.ts +0 -18
  160. package/src/tools/omada/namespace.ts +0 -1164
  161. package/src/tools/omada/searchDevices.ts +0 -20
  162. package/src/tools/omada/setClientRateLimit.ts +0 -26
  163. package/src/tools/omada/setClientRateLimitProfile.ts +0 -25
  164. package/src/tools/omada/setSiteNtpServers.ts +0 -36
  165. package/src/tools/omada/setSsidEnabled.ts +0 -38
  166. package/src/tools/omada/unblockClient.ts +0 -26
  167. package/src/tools/types.ts +0 -11
  168. package/src/tools/utils/pagination-schema.ts +0 -27
  169. package/src/types/ai/index.ts +0 -11
  170. package/src/types/ai/types.ts +0 -67
  171. package/src/types/homeassistant/automations.ts +0 -43
  172. package/src/types/homeassistant/calendars.ts +0 -26
  173. package/src/types/homeassistant/config.ts +0 -14
  174. package/src/types/homeassistant/entities.ts +0 -14
  175. package/src/types/homeassistant/errors.ts +0 -33
  176. package/src/types/homeassistant/haConfig.ts +0 -7
  177. package/src/types/homeassistant/history.ts +0 -13
  178. package/src/types/homeassistant/index.ts +0 -46
  179. package/src/types/homeassistant/request.ts +0 -6
  180. package/src/types/homeassistant/serviceCall.ts +0 -18
  181. package/src/types/homeassistant/states.ts +0 -58
  182. package/src/types/homeassistant/updates.ts +0 -28
  183. package/src/types/index.ts +0 -12
  184. package/src/types/omada/activeClientInfo.ts +0 -17
  185. package/src/types/omada/clientActivity.ts +0 -32
  186. package/src/types/omada/clientBlockStatus.ts +0 -11
  187. package/src/types/omada/clientPastConnection.ts +0 -82
  188. package/src/types/omada/index.ts +0 -14
  189. package/src/types/omada/omadaApiResponse.ts +0 -5
  190. package/src/types/omada/omadaClientInfo.ts +0 -11
  191. package/src/types/omada/omadaDeviceInfo.ts +0 -11
  192. package/src/types/omada/omadaDeviceStats.ts +0 -31
  193. package/src/types/omada/omadaSiteSummary.ts +0 -5
  194. package/src/types/omada/oswStackDetail.ts +0 -11
  195. package/src/types/omada/paginatedResult.ts +0 -6
  196. package/src/types/omada/rateLimitProfile.ts +0 -58
  197. package/src/types/omada/threatInfo.ts +0 -38
  198. package/src/types/omada/tokenResult.ts +0 -6
  199. package/src/types.ts +0 -2
  200. package/src/utils/config-validations.ts +0 -68
  201. package/src/utils/jwt.ts +0 -112
  202. package/src/utils/logger.ts +0 -121
  203. package/src/utils/plainText.ts +0 -48
  204. package/src/utils/redact.ts +0 -59
  205. package/src/utils/sanitizeError.ts +0 -18
  206. package/src/utils/tlsDispatcher.ts +0 -69
  207. package/src/version.ts +0 -5
  208. package/tests/bdd/automation-creation.spec.ts +0 -214
  209. package/tests/bdd/automation-management.spec.ts +0 -267
  210. package/tests/bdd/calendar.spec.ts +0 -190
  211. package/tests/bdd/configuration.spec.ts +0 -283
  212. package/tests/bdd/device-control.spec.ts +0 -344
  213. package/tests/bdd/entity-listing.spec.ts +0 -208
  214. package/tests/bdd/entity-search.spec.ts +0 -183
  215. package/tests/bdd/history-retrieval.spec.ts +0 -195
  216. package/tests/bdd/notifications.spec.ts +0 -238
  217. package/tests/bdd/service-calls.spec.ts +0 -144
  218. package/tests/bdd/state-retrieval.spec.ts +0 -204
  219. package/tests/bench/hotpaths.bench.ts +0 -68
  220. package/tests/config.test.ts +0 -355
  221. package/tests/features/automation-creation.feature +0 -36
  222. package/tests/features/automation-management.feature +0 -54
  223. package/tests/features/calendar.feature +0 -37
  224. package/tests/features/configuration.feature +0 -70
  225. package/tests/features/device-control.feature +0 -100
  226. package/tests/features/entity-listing.feature +0 -51
  227. package/tests/features/entity-search.feature +0 -44
  228. package/tests/features/history-retrieval.feature +0 -38
  229. package/tests/features/notifications.feature +0 -37
  230. package/tests/features/service-calls.feature +0 -35
  231. package/tests/features/state-retrieval.feature +0 -37
  232. package/tests/fixtures/openapi-default-slice.json +0 -290
  233. package/tests/haClient/automationTrace.test.ts +0 -59
  234. package/tests/haClient/automations.test.ts +0 -149
  235. package/tests/haClient/config.test.ts +0 -117
  236. package/tests/haClient/entities.test.ts +0 -188
  237. package/tests/haClient/events.test.ts +0 -455
  238. package/tests/haClient/eventsTls.test.ts +0 -52
  239. package/tests/haClient/history.test.ts +0 -228
  240. package/tests/haClient/index.test.ts +0 -243
  241. package/tests/haClient/request.test.ts +0 -217
  242. package/tests/haClient/services.test.ts +0 -120
  243. package/tests/haClient/states.test.ts +0 -119
  244. package/tests/haClient/updates.test.ts +0 -193
  245. package/tests/index.test.ts +0 -160
  246. package/tests/integration/homeassistant.test.ts +0 -144
  247. package/tests/integration/omada.test.ts +0 -167
  248. package/tests/integration/server.test.ts +0 -151
  249. package/tests/localAI/index.test.ts +0 -177
  250. package/tests/localAI/ollama.test.ts +0 -187
  251. package/tests/localAI/openai.test.ts +0 -257
  252. package/tests/omadaClient/actions.test.ts +0 -161
  253. package/tests/omadaClient/clientBlocks.test.ts +0 -170
  254. package/tests/omadaClient/ntp.test.ts +0 -381
  255. package/tests/omadaClient/site.test.ts +0 -37
  256. package/tests/ownerQuestions/service.test.ts +0 -499
  257. package/tests/ownerQuestions/tools.test.ts +0 -186
  258. package/tests/permissions/index.test.ts +0 -217
  259. package/tests/resources/index.test.ts +0 -288
  260. package/tests/scripts/generateJwt.test.ts +0 -44
  261. package/tests/security/accessControl.test.ts +0 -223
  262. package/tests/security/authentication.test.ts +0 -117
  263. package/tests/security/configuration.test.ts +0 -170
  264. package/tests/security/cryptoTransport.test.ts +0 -172
  265. package/tests/security/dependencies.test.ts +0 -152
  266. package/tests/security/injection.test.ts +0 -117
  267. package/tests/security/insecureDesign.test.ts +0 -121
  268. package/tests/security/logging.test.ts +0 -131
  269. package/tests/security/resourceConsumption.test.ts +0 -142
  270. package/tests/server/auth.test.ts +0 -249
  271. package/tests/server/chatFace.test.ts +0 -320
  272. package/tests/server/common.test.ts +0 -84
  273. package/tests/server/http.test.ts +0 -561
  274. package/tests/server/instructions.test.ts +0 -152
  275. package/tests/server/memoizeJsonSchema.test.ts +0 -71
  276. package/tests/server/stdio.test.ts +0 -99
  277. package/tests/server/stream.test.ts +0 -285
  278. package/tests/server/toolVisibility.http.test.ts +0 -111
  279. package/tests/server/toolVisibility.test.ts +0 -129
  280. package/tests/tools/ai/analyzeSensors.test.ts +0 -227
  281. package/tests/tools/common.test.ts +0 -123
  282. package/tests/tools/homeassistant/handlers.test.ts +0 -872
  283. package/tests/tools/infra/invokeAction.test.ts +0 -280
  284. package/tests/tools/omada/graph.test.ts +0 -385
  285. package/tests/tools/omada/handlers.test.ts +0 -897
  286. package/tests/tools/omada/namespace.test.ts +0 -483
  287. package/tests/tools/registry.test.ts +0 -168
  288. package/tests/utils/config-validations.test.ts +0 -352
  289. package/tests/utils/jwt.test.ts +0 -115
  290. package/tests/utils/logger.test.ts +0 -327
  291. package/tests/utils/redact.test.ts +0 -105
  292. package/tsconfig.json +0 -24
  293. package/vitest.config.ts +0 -38
@@ -1,118 +0,0 @@
1
- import type { GetDeviceStatsOptions, OmadaApiResponse, OmadaDeviceInfo, OmadaDeviceStats, OswStackDetail } from '../types/index.js';
2
-
3
- import type { RequestHandler } from './request.js';
4
- import type { SiteOperations } from './site.js';
5
-
6
- /**
7
- * Device-related operations for the Omada API.
8
- */
9
- export class DeviceOperations {
10
- constructor(
11
- private readonly request: RequestHandler,
12
- private readonly site: SiteOperations,
13
- private readonly buildPath: (path: string) => string
14
- ) {}
15
-
16
- /**
17
- * List all devices in a site.
18
- */
19
- public async listDevices(siteId?: string): Promise<OmadaDeviceInfo[]> {
20
- const resolvedSiteId = this.site.resolveSiteId(siteId);
21
- return await this.request.fetchPaginated<OmadaDeviceInfo>(this.buildPath(`/sites/${encodeURIComponent(resolvedSiteId)}/devices`));
22
- }
23
-
24
- /**
25
- * Get a specific device by MAC address or device ID.
26
- */
27
- public async getDevice(identifier: string, siteId?: string): Promise<OmadaDeviceInfo | undefined> {
28
- const devices = await this.listDevices(siteId);
29
- return devices.find((device) => device.mac === identifier || device.deviceId === identifier);
30
- }
31
-
32
- /**
33
- * Get detailed information about a switch stack.
34
- */
35
- public async getSwitchStackDetail(stackId: string, siteId?: string): Promise<OswStackDetail> {
36
- if (!stackId) {
37
- throw new Error('A stack id must be provided.');
38
- }
39
-
40
- const resolvedSiteId = this.site.resolveSiteId(siteId);
41
- const path = this.buildPath(`/sites/${encodeURIComponent(resolvedSiteId)}/stacks/${encodeURIComponent(stackId)}`);
42
-
43
- const response = await this.request.get<OmadaApiResponse<OswStackDetail>>(path);
44
- return this.request.ensureSuccess(response);
45
- }
46
-
47
- /**
48
- * Search for devices globally across all sites the user has access to.
49
- */
50
- public async searchDevices(searchKey: string): Promise<OmadaDeviceInfo[]> {
51
- if (!searchKey) {
52
- throw new Error('A search key must be provided.');
53
- }
54
-
55
- const path = this.buildPath(`/devices?searchKey=${encodeURIComponent(searchKey)}`);
56
- const response = await this.request.get<OmadaApiResponse<OmadaDeviceInfo[]>>(path);
57
- return this.request.ensureSuccess(response);
58
- }
59
-
60
- /**
61
- * Get statistics for global adopted devices with filtering and pagination.
62
- */
63
- public async listDevicesStats(options: GetDeviceStatsOptions): Promise<OmadaDeviceStats> {
64
- const queryParams = new URLSearchParams();
65
- queryParams.append('page', options.page.toString());
66
- queryParams.append('pageSize', options.pageSize.toString());
67
-
68
- if (options.searchMacs) {
69
- queryParams.append('searchMacs', options.searchMacs);
70
- }
71
- if (options.searchNames) {
72
- queryParams.append('searchNames', options.searchNames);
73
- }
74
- if (options.searchModels) {
75
- queryParams.append('searchModels', options.searchModels);
76
- }
77
- if (options.searchSns) {
78
- queryParams.append('searchSns', options.searchSns);
79
- }
80
- if (options.filterTag) {
81
- queryParams.append('filters.tag', options.filterTag);
82
- }
83
- if (options.filterDeviceSeriesType) {
84
- queryParams.append('filters.deviceSeriesType', options.filterDeviceSeriesType);
85
- }
86
-
87
- const path = this.buildPath(`/devices/stat?${queryParams.toString()}`);
88
- const response = await this.request.get<OmadaApiResponse<OmadaDeviceStats>>(path);
89
- return this.request.ensureSuccess(response);
90
- }
91
-
92
- /**
93
- * Power-cycle PoE on one or more switch ports ("PoE recovery").
94
- * OperationId: createSitesSwitchesMultiPortsPoeRecovery
95
- *
96
- * The switch briefly cuts and restores PoE power on the given ports —
97
- * a remote hard-reboot for whatever is powered by them (APs, cameras).
98
- * The switch itself and other ports are unaffected.
99
- *
100
- * @param switchMac - MAC address of the Omada switch
101
- * @param ports - Port numbers to cycle, e.g. [1, 2]
102
- */
103
- public async cyclePoePorts(switchMac: string, ports: number[], siteId?: string): Promise<void> {
104
- if (!switchMac) {
105
- throw new Error('A switchMac must be provided. Use omada_listDevices to find switch MAC addresses.');
106
- }
107
- if (!ports.length) {
108
- throw new Error('At least one port number must be provided, e.g. ports: [1].');
109
- }
110
-
111
- const resolvedSiteId = this.site.resolveSiteId(siteId);
112
- const path = this.buildPath(
113
- `/sites/${encodeURIComponent(resolvedSiteId)}/switches/${encodeURIComponent(switchMac)}/multi-ports/poe-recovery`
114
- );
115
- const response = await this.request.post<OmadaApiResponse<unknown>>(path, { ports });
116
- this.request.ensureSuccess(response);
117
- }
118
- }
@@ -1,310 +0,0 @@
1
- import type {
2
- ActiveClientInfo,
3
- ClientActivity,
4
- ClientBlockStatus,
5
- ClientPastConnection,
6
- ClientRateLimitSetting,
7
- GetClientActivityOptions,
8
- GetDeviceStatsOptions,
9
- GetThreatListOptions,
10
- ListClientsPastConnectionsOptions,
11
- OmadaClientInfo,
12
- OmadaApiResponse,
13
- OmadaDeviceInfo,
14
- OmadaDeviceStats,
15
- OmadaSiteSummary,
16
- OswStackDetail,
17
- PaginatedResult,
18
- RateLimitProfile,
19
- ThreatInfo,
20
- } from '../types/index.js';
21
-
22
- import { AuthManager } from './auth.js';
23
- import { ClientOperations, type KnownClient } from './client.js';
24
- import { DeviceOperations } from './device.js';
25
- import { NetworkOperations, type SsidEnableResult } from './network.js';
26
- import { RequestHandler, type RequestOptions } from './request.js';
27
- import { SecurityOperations } from './security.js';
28
- import { SiteOperations, type SiteNtpChangeResult } from './site.js';
29
-
30
- export interface OmadaClientOptions {
31
- baseUrl: string;
32
- clientId: string;
33
- clientSecret: string;
34
- omadacId: string;
35
- siteId?: string;
36
- strictSsl: boolean;
37
- requestTimeout?: number;
38
- }
39
-
40
- /**
41
- * Main client for interacting with the TP-Link Omada API.
42
- * Organized by API tag with dedicated operation classes for each domain.
43
- */
44
- export class OmadaClient {
45
- private readonly auth: AuthManager;
46
-
47
- private readonly request: RequestHandler;
48
-
49
- private readonly siteOps: SiteOperations;
50
-
51
- private readonly deviceOps: DeviceOperations;
52
-
53
- private readonly clientOps: ClientOperations;
54
-
55
- private readonly securityOps: SecurityOperations;
56
-
57
- private readonly networkOps: NetworkOperations;
58
-
59
- private readonly omadacId: string;
60
-
61
- constructor(options: OmadaClientOptions) {
62
- this.omadacId = options.omadacId;
63
-
64
- const timeout = options.requestTimeout ?? 30000;
65
-
66
- // Initialize operation modules
67
- this.auth = new AuthManager({
68
- baseUrl: options.baseUrl,
69
- clientId: options.clientId,
70
- clientSecret: options.clientSecret,
71
- omadacId: options.omadacId,
72
- timeout,
73
- strictSsl: options.strictSsl,
74
- });
75
-
76
- this.request = new RequestHandler(
77
- {
78
- baseUrl: options.baseUrl,
79
- timeout,
80
- strictSsl: options.strictSsl,
81
- },
82
- this.auth
83
- );
84
-
85
- this.siteOps = new SiteOperations(this.request, this.buildOmadaPath.bind(this), options.siteId);
86
- this.deviceOps = new DeviceOperations(this.request, this.siteOps, this.buildOmadaPath.bind(this));
87
- this.clientOps = new ClientOperations(this.request, this.siteOps, this.buildOmadaPath.bind(this));
88
- this.securityOps = new SecurityOperations(this.request, this.buildOmadaPath.bind(this));
89
- this.networkOps = new NetworkOperations(this.request, this.siteOps, this.buildOmadaPath.bind(this));
90
- }
91
-
92
- // Site operations
93
- public async listSites(): Promise<OmadaSiteSummary[]> {
94
- return await this.siteOps.listSites();
95
- }
96
-
97
- public async getSiteNtpStatus(siteId?: string): Promise<unknown> {
98
- return await this.siteOps.getSiteNtpStatus(siteId);
99
- }
100
-
101
- public async setSiteNtpServers(
102
- servers: string[],
103
- options: { enabled?: boolean; siteId?: string; dryRun?: boolean } = {}
104
- ): Promise<SiteNtpChangeResult> {
105
- return await this.siteOps.setSiteNtpServers(servers, options);
106
- }
107
-
108
- // Device operations
109
- public async listDevices(siteId?: string): Promise<OmadaDeviceInfo[]> {
110
- return await this.deviceOps.listDevices(siteId);
111
- }
112
-
113
- public async getDevice(identifier: string, siteId?: string): Promise<OmadaDeviceInfo | undefined> {
114
- return await this.deviceOps.getDevice(identifier, siteId);
115
- }
116
-
117
- public async getSwitchStackDetail(stackId: string, siteId?: string): Promise<OswStackDetail> {
118
- return await this.deviceOps.getSwitchStackDetail(stackId, siteId);
119
- }
120
-
121
- public async searchDevices(searchKey: string): Promise<OmadaDeviceInfo[]> {
122
- return await this.deviceOps.searchDevices(searchKey);
123
- }
124
-
125
- public async listDevicesStats(options: GetDeviceStatsOptions): Promise<OmadaDeviceStats> {
126
- return await this.deviceOps.listDevicesStats(options);
127
- }
128
-
129
- // Client operations
130
- public async listClients(siteId?: string): Promise<OmadaClientInfo[]> {
131
- return await this.clientOps.listClients(siteId);
132
- }
133
-
134
- public async getClient(identifier: string, siteId?: string): Promise<OmadaClientInfo | undefined> {
135
- return await this.clientOps.getClient(identifier, siteId);
136
- }
137
-
138
- public async listMostActiveClients(siteId?: string): Promise<ActiveClientInfo[]> {
139
- return await this.clientOps.listMostActiveClients(siteId);
140
- }
141
-
142
- public async listClientsActivity(options?: GetClientActivityOptions): Promise<ClientActivity[]> {
143
- return await this.clientOps.listClientsActivity(options);
144
- }
145
-
146
- public async listClientsPastConnections(options: ListClientsPastConnectionsOptions): Promise<ClientPastConnection[]> {
147
- return await this.clientOps.listClientsPastConnections(options);
148
- }
149
-
150
- // Rate limit operations
151
- public async getRateLimitProfiles(siteId?: string): Promise<RateLimitProfile[]> {
152
- return await this.clientOps.getRateLimitProfiles(siteId);
153
- }
154
-
155
- public async setClientRateLimit(clientMac: string, downLimit: number, upLimit: number, siteId?: string): Promise<ClientRateLimitSetting> {
156
- return await this.clientOps.setClientRateLimit(clientMac, downLimit, upLimit, siteId);
157
- }
158
-
159
- public async setClientRateLimitProfile(clientMac: string, profileId: string, siteId?: string): Promise<ClientRateLimitSetting> {
160
- return await this.clientOps.setClientRateLimitProfile(clientMac, profileId, siteId);
161
- }
162
-
163
- public async disableClientRateLimit(clientMac: string, siteId?: string): Promise<ClientRateLimitSetting> {
164
- return await this.clientOps.disableClientRateLimit(clientMac, siteId);
165
- }
166
-
167
- // Client block operations
168
- public async blockClient(clientMac: string, siteId?: string): Promise<ClientBlockStatus> {
169
- return await this.clientOps.blockClient(clientMac, siteId);
170
- }
171
-
172
- public async unblockClient(clientMac: string, siteId?: string): Promise<ClientBlockStatus> {
173
- return await this.clientOps.unblockClient(clientMac, siteId);
174
- }
175
-
176
- public async listBlockedClients(siteId?: string): Promise<KnownClient[]> {
177
- return await this.clientOps.listBlockedClients(siteId);
178
- }
179
-
180
- public async deleteClient(clientMac: string, siteId?: string): Promise<{ mac: string; siteId: string; deleted: true }> {
181
- return await this.clientOps.deleteClient(clientMac, siteId);
182
- }
183
-
184
- // Security operations
185
- public async getThreatList(options: GetThreatListOptions): Promise<PaginatedResult<ThreatInfo>> {
186
- return await this.securityOps.getThreatList(options);
187
- }
188
-
189
- // Network operations
190
- public async getInternetInfo(siteId?: string): Promise<unknown> {
191
- return await this.networkOps.getInternetInfo(siteId);
192
- }
193
-
194
- public async getPortForwardingStatus(type: 'User' | 'UPnP', siteId?: string, page = 1, pageSize = 10): Promise<PaginatedResult<unknown>> {
195
- return await this.networkOps.getPortForwardingStatus(type, siteId, page, pageSize);
196
- }
197
-
198
- public async getLanNetworkList(siteId?: string): Promise<unknown[]> {
199
- return await this.networkOps.getLanNetworkList(siteId);
200
- }
201
-
202
- public async getLanProfileList(siteId?: string): Promise<unknown[]> {
203
- return await this.networkOps.getLanProfileList(siteId);
204
- }
205
-
206
- public async getWlanGroupList(siteId?: string): Promise<unknown[]> {
207
- return await this.networkOps.getWlanGroupList(siteId);
208
- }
209
-
210
- public async getSsidList(wlanId: string, siteId?: string): Promise<unknown[]> {
211
- return await this.networkOps.getSsidList(wlanId, siteId);
212
- }
213
-
214
- public async getSsidDetail(wlanId: string, ssidId: string, siteId?: string): Promise<unknown> {
215
- return await this.networkOps.getSsidDetail(wlanId, ssidId, siteId);
216
- }
217
-
218
- public async getFirewallSetting(siteId?: string): Promise<unknown> {
219
- return await this.networkOps.getFirewallSetting(siteId);
220
- }
221
-
222
- /** Power-cycle PoE on switch ports (remote hard-reboot of PoE-powered devices). */
223
- public async cyclePoePorts(switchMac: string, ports: number[], siteId?: string): Promise<void> {
224
- return await this.deviceOps.cyclePoePorts(switchMac, ports, siteId);
225
- }
226
-
227
- /** Enable/disable an SSID (guest network on/off) via the WLAN-schedule mechanism. */
228
- public async setSsidEnabled(ssid: string, enabled: boolean, siteId?: string): Promise<SsidEnableResult> {
229
- return await this.networkOps.setSsidEnabled(ssid, enabled, siteId);
230
- }
231
-
232
- // Generic API call
233
- public async callApi<T = unknown>(config: RequestOptions): Promise<T> {
234
- return await this.request.request<T>(config);
235
- }
236
-
237
- /**
238
- * Read an arbitrary Omada resource described by a path template.
239
- *
240
- * This is the single client primitive behind the resource-graph `omada_read`
241
- * tool: "many endpoints, zero new client methods". A path template may contain
242
- * `{placeholder}` segments (each substituted from `siteId`/`pathParams` and
243
- * URL-encoded), and may be site-scoped (the common case) or controller-global.
244
- *
245
- * Pagination is deliberately SINGLE-page: for paginated resources it forwards
246
- * one page/pageSize to a single GET rather than walking every page (no giant
247
- * payloads). It returns the unwrapped `result` (errorCode !== 0 throws via
248
- * `ensureSuccess`).
249
- *
250
- * @param options.pathTemplate e.g. '/sites/{siteId}/gateways/{gatewayMac}/wan-status'
251
- * @param options.siteScoped when true (default) `{siteId}` is resolved from siteId/default
252
- * @param options.paginated when true, page/pageSize are sent as query params
253
- * @param options.pathParams values for non-site `{placeholder}` segments
254
- * @param options.query extra query parameters
255
- */
256
- public async readResource(options: {
257
- pathTemplate: string;
258
- siteScoped?: boolean;
259
- paginated?: boolean;
260
- siteId?: string;
261
- pathParams?: Record<string, string>;
262
- query?: Record<string, unknown>;
263
- page?: number;
264
- pageSize?: number;
265
- }): Promise<unknown> {
266
- const {
267
- pathTemplate,
268
- siteScoped = true,
269
- paginated = false,
270
- siteId,
271
- pathParams = {},
272
- query = {},
273
- page,
274
- pageSize,
275
- } = options;
276
-
277
- const substitutions: Record<string, string> = { ...pathParams };
278
- if (siteScoped || pathTemplate.includes('{siteId}')) {
279
- substitutions.siteId = this.siteOps.resolveSiteId(siteId);
280
- }
281
-
282
- const relativePath = pathTemplate.replace(/\{(\w+)\}/g, (_match, key: string) => {
283
- const value = substitutions[key];
284
- if (value === undefined || value === '') {
285
- throw new Error(`Missing required path parameter '${key}' for resource '${pathTemplate}'`);
286
- }
287
- return encodeURIComponent(value);
288
- });
289
-
290
- const effectiveQuery: Record<string, unknown> = { ...query };
291
- if (paginated) {
292
- effectiveQuery.page = page ?? 1;
293
- effectiveQuery.pageSize = pageSize ?? 50;
294
- }
295
-
296
- const fullPath = this.buildOmadaPath(relativePath);
297
- const response = await this.request.get<OmadaApiResponse<unknown>>(fullPath, effectiveQuery);
298
- return this.request.ensureSuccess(response);
299
- }
300
-
301
- /**
302
- * Build a full Omada API path from a relative path.
303
- * @param relativePath - The relative path to append to the base API path
304
- * @param version - The API version to use (default: 'v1')
305
- */
306
- private buildOmadaPath(relativePath: string, version = 'v1'): string {
307
- const normalized = relativePath.startsWith('/') ? relativePath : `/${relativePath}`;
308
- return `/openapi/${version}/${encodeURIComponent(this.omadacId)}${normalized}`;
309
- }
310
- }