@coffeerunhobby/mcp-ha-connect 2.2.1 → 2.3.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.
- package/.env.example +1 -1
- package/README.md +11 -2
- package/dist/omadaClient/client.d.ts +6 -1
- package/dist/omadaClient/client.js +12 -1
- package/dist/omadaClient/client.js.map +1 -1
- package/dist/omadaClient/diagnose.d.ts +68 -0
- package/dist/omadaClient/diagnose.js +164 -0
- package/dist/omadaClient/diagnose.js.map +1 -0
- package/dist/omadaClient/index.d.ts +6 -0
- package/dist/omadaClient/index.js +15 -0
- package/dist/omadaClient/index.js.map +1 -1
- package/dist/omadaClient/macGroups.d.ts +58 -0
- package/dist/omadaClient/macGroups.js +124 -0
- package/dist/omadaClient/macGroups.js.map +1 -0
- package/dist/tools/infra/actions.d.ts +1 -1
- package/dist/tools/infra/actions.js +1 -1
- package/dist/tools/omada/index.js +6 -0
- package/dist/tools/omada/index.js.map +1 -1
- package/dist/tools/omada/macGroups.d.ts +19 -0
- package/dist/tools/omada/macGroups.js +77 -0
- package/dist/tools/omada/macGroups.js.map +1 -0
- package/dist/tools/omada/namespace.js +8 -0
- package/dist/tools/omada/namespace.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -1
- package/.codex/review-rules.md +0 -16
- package/.dockerignore +0 -8
- package/.gitattributes +0 -30
- package/.github/workflows/ci.yml +0 -193
- package/AGENTS.md +0 -389
- package/Dockerfile +0 -50
- package/docker-compose.yml +0 -23
- package/docs/CHANGELOG.md +0 -341
- package/docs/COVERAGE.md +0 -219
- package/docs/QUICK_START.md +0 -240
- package/eslint.config.js +0 -33
- package/n8n/ai-agent-safety-monitor.json +0 -355
- package/openapi.json +0 -1259
- package/scripts/check-version-sync.mjs +0 -69
- package/scripts/generate-jwt.ts +0 -121
- package/src/config.ts +0 -440
- package/src/haClient/automations.ts +0 -261
- package/src/haClient/calendars.ts +0 -94
- package/src/haClient/config.ts +0 -52
- package/src/haClient/devices.ts +0 -653
- package/src/haClient/entities.ts +0 -128
- package/src/haClient/events.ts +0 -689
- package/src/haClient/history.ts +0 -73
- package/src/haClient/index.ts +0 -336
- package/src/haClient/request.ts +0 -142
- package/src/haClient/services.ts +0 -45
- package/src/haClient/states.ts +0 -60
- package/src/haClient/updates.ts +0 -58
- package/src/haClient/wsCommand.ts +0 -44
- package/src/index.ts +0 -164
- package/src/localAI/index.ts +0 -88
- package/src/localAI/prompts.ts +0 -50
- package/src/localAI/providers/base.ts +0 -120
- package/src/localAI/providers/ollama.ts +0 -78
- package/src/localAI/providers/openai.ts +0 -86
- package/src/localAI/types.ts +0 -67
- package/src/omadaClient/auth.ts +0 -178
- package/src/omadaClient/client.ts +0 -337
- package/src/omadaClient/device.ts +0 -118
- package/src/omadaClient/index.ts +0 -310
- package/src/omadaClient/network.ts +0 -284
- package/src/omadaClient/request.ts +0 -365
- package/src/omadaClient/security.ts +0 -51
- package/src/omadaClient/site.ts +0 -344
- package/src/ownerQuestions/service.ts +0 -536
- package/src/permissions/index.ts +0 -143
- package/src/resources/index.ts +0 -213
- package/src/server/auth.ts +0 -175
- package/src/server/chatFace.ts +0 -789
- package/src/server/chatSlice.ts +0 -57
- package/src/server/common.ts +0 -170
- package/src/server/eventSubscription.ts +0 -343
- package/src/server/http.ts +0 -626
- package/src/server/instructions.ts +0 -97
- package/src/server/rateLimiter.ts +0 -227
- package/src/server/stdio.ts +0 -41
- package/src/server/stream.ts +0 -205
- package/src/tools/ai/analyzeSensors.ts +0 -33
- package/src/tools/ai/index.ts +0 -20
- package/src/tools/common.ts +0 -442
- package/src/tools/homeassistant/askOwner.ts +0 -133
- package/src/tools/homeassistant/automationControls.ts +0 -66
- package/src/tools/homeassistant/calendar.ts +0 -97
- package/src/tools/homeassistant/callService.ts +0 -25
- package/src/tools/homeassistant/controlClimate.ts +0 -68
- package/src/tools/homeassistant/controlCover.ts +0 -48
- package/src/tools/homeassistant/controlFan.ts +0 -44
- package/src/tools/homeassistant/controlLight.ts +0 -38
- package/src/tools/homeassistant/controlMediaPlayer.ts +0 -50
- package/src/tools/homeassistant/createAutomation.ts +0 -35
- package/src/tools/homeassistant/deleteAutomation.ts +0 -24
- package/src/tools/homeassistant/entityAction.ts +0 -35
- package/src/tools/homeassistant/entityGuard.ts +0 -28
- package/src/tools/homeassistant/getAllSensors.ts +0 -46
- package/src/tools/homeassistant/getAutomationTrace.ts +0 -30
- package/src/tools/homeassistant/getDomainSummary.ts +0 -29
- package/src/tools/homeassistant/getEntitiesByDomain.ts +0 -56
- package/src/tools/homeassistant/getHistory.ts +0 -24
- package/src/tools/homeassistant/getState.ts +0 -24
- package/src/tools/homeassistant/getStates.ts +0 -46
- package/src/tools/homeassistant/getVersion.ts +0 -21
- package/src/tools/homeassistant/index.ts +0 -121
- package/src/tools/homeassistant/listAutomations.ts +0 -35
- package/src/tools/homeassistant/listEntities.ts +0 -44
- package/src/tools/homeassistant/listPersons.ts +0 -46
- package/src/tools/homeassistant/sceneAndScript.ts +0 -53
- package/src/tools/homeassistant/searchEntities.ts +0 -58
- package/src/tools/homeassistant/sendNotification.ts +0 -179
- package/src/tools/homeassistant/systemTools.ts +0 -52
- package/src/tools/homeassistant/triggerAutomation.ts +0 -24
- package/src/tools/index.ts +0 -78
- package/src/tools/infra/actions.ts +0 -95
- package/src/tools/infra/index.ts +0 -138
- package/src/tools/omada/blockClient.ts +0 -28
- package/src/tools/omada/cyclePoePort.ts +0 -32
- package/src/tools/omada/deleteClient.ts +0 -27
- package/src/tools/omada/disableClientRateLimit.ts +0 -23
- package/src/tools/omada/getClient.ts +0 -14
- package/src/tools/omada/getDevice.ts +0 -14
- package/src/tools/omada/getFirewallSetting.ts +0 -14
- package/src/tools/omada/getInternetInfo.ts +0 -14
- package/src/tools/omada/getLanNetworkList.ts +0 -14
- package/src/tools/omada/getLanProfileList.ts +0 -14
- package/src/tools/omada/getPortForwardingStatus.ts +0 -26
- package/src/tools/omada/getRateLimitProfiles.ts +0 -14
- package/src/tools/omada/getSiteNtpStatus.ts +0 -14
- package/src/tools/omada/getSsidDetail.ts +0 -22
- package/src/tools/omada/getSsidList.ts +0 -21
- package/src/tools/omada/getSwitchStackDetail.ts +0 -14
- package/src/tools/omada/getThreatList.ts +0 -42
- package/src/tools/omada/getWlanGroupList.ts +0 -14
- package/src/tools/omada/graph.ts +0 -187
- package/src/tools/omada/index.ts +0 -153
- package/src/tools/omada/listBlockedClients.ts +0 -17
- package/src/tools/omada/listClients.ts +0 -14
- package/src/tools/omada/listClientsActivity.ts +0 -25
- package/src/tools/omada/listClientsPastConnections.ts +0 -44
- package/src/tools/omada/listDevices.ts +0 -14
- package/src/tools/omada/listDevicesStats.ts +0 -41
- package/src/tools/omada/listMostActiveClients.ts +0 -14
- package/src/tools/omada/listSites.ts +0 -18
- package/src/tools/omada/namespace.ts +0 -1164
- package/src/tools/omada/searchDevices.ts +0 -20
- package/src/tools/omada/setClientRateLimit.ts +0 -26
- package/src/tools/omada/setClientRateLimitProfile.ts +0 -25
- package/src/tools/omada/setSiteNtpServers.ts +0 -36
- package/src/tools/omada/setSsidEnabled.ts +0 -38
- package/src/tools/omada/unblockClient.ts +0 -26
- package/src/tools/types.ts +0 -11
- package/src/tools/utils/pagination-schema.ts +0 -27
- package/src/types/ai/index.ts +0 -11
- package/src/types/ai/types.ts +0 -67
- package/src/types/homeassistant/automations.ts +0 -43
- package/src/types/homeassistant/calendars.ts +0 -26
- package/src/types/homeassistant/config.ts +0 -14
- package/src/types/homeassistant/entities.ts +0 -14
- package/src/types/homeassistant/errors.ts +0 -33
- package/src/types/homeassistant/haConfig.ts +0 -7
- package/src/types/homeassistant/history.ts +0 -13
- package/src/types/homeassistant/index.ts +0 -46
- package/src/types/homeassistant/request.ts +0 -6
- package/src/types/homeassistant/serviceCall.ts +0 -18
- package/src/types/homeassistant/states.ts +0 -58
- package/src/types/homeassistant/updates.ts +0 -28
- package/src/types/index.ts +0 -12
- package/src/types/omada/activeClientInfo.ts +0 -17
- package/src/types/omada/clientActivity.ts +0 -32
- package/src/types/omada/clientBlockStatus.ts +0 -11
- package/src/types/omada/clientPastConnection.ts +0 -82
- package/src/types/omada/index.ts +0 -14
- package/src/types/omada/omadaApiResponse.ts +0 -5
- package/src/types/omada/omadaClientInfo.ts +0 -11
- package/src/types/omada/omadaDeviceInfo.ts +0 -11
- package/src/types/omada/omadaDeviceStats.ts +0 -31
- package/src/types/omada/omadaSiteSummary.ts +0 -5
- package/src/types/omada/oswStackDetail.ts +0 -11
- package/src/types/omada/paginatedResult.ts +0 -6
- package/src/types/omada/rateLimitProfile.ts +0 -58
- package/src/types/omada/threatInfo.ts +0 -38
- package/src/types/omada/tokenResult.ts +0 -6
- package/src/types.ts +0 -2
- package/src/utils/config-validations.ts +0 -68
- package/src/utils/jwt.ts +0 -112
- package/src/utils/logger.ts +0 -121
- package/src/utils/plainText.ts +0 -48
- package/src/utils/redact.ts +0 -59
- package/src/utils/sanitizeError.ts +0 -18
- package/src/utils/tlsDispatcher.ts +0 -69
- package/src/version.ts +0 -5
- package/tests/bdd/automation-creation.spec.ts +0 -214
- package/tests/bdd/automation-management.spec.ts +0 -267
- package/tests/bdd/calendar.spec.ts +0 -190
- package/tests/bdd/configuration.spec.ts +0 -283
- package/tests/bdd/device-control.spec.ts +0 -344
- package/tests/bdd/entity-listing.spec.ts +0 -208
- package/tests/bdd/entity-search.spec.ts +0 -183
- package/tests/bdd/history-retrieval.spec.ts +0 -195
- package/tests/bdd/notifications.spec.ts +0 -238
- package/tests/bdd/service-calls.spec.ts +0 -144
- package/tests/bdd/state-retrieval.spec.ts +0 -204
- package/tests/bench/hotpaths.bench.ts +0 -68
- package/tests/config.test.ts +0 -355
- package/tests/features/automation-creation.feature +0 -36
- package/tests/features/automation-management.feature +0 -54
- package/tests/features/calendar.feature +0 -37
- package/tests/features/configuration.feature +0 -70
- package/tests/features/device-control.feature +0 -100
- package/tests/features/entity-listing.feature +0 -51
- package/tests/features/entity-search.feature +0 -44
- package/tests/features/history-retrieval.feature +0 -38
- package/tests/features/notifications.feature +0 -37
- package/tests/features/service-calls.feature +0 -35
- package/tests/features/state-retrieval.feature +0 -37
- package/tests/fixtures/openapi-default-slice.json +0 -290
- package/tests/haClient/automationTrace.test.ts +0 -59
- package/tests/haClient/automations.test.ts +0 -149
- package/tests/haClient/config.test.ts +0 -117
- package/tests/haClient/entities.test.ts +0 -188
- package/tests/haClient/events.test.ts +0 -455
- package/tests/haClient/eventsTls.test.ts +0 -52
- package/tests/haClient/history.test.ts +0 -228
- package/tests/haClient/index.test.ts +0 -243
- package/tests/haClient/request.test.ts +0 -217
- package/tests/haClient/services.test.ts +0 -120
- package/tests/haClient/states.test.ts +0 -119
- package/tests/haClient/updates.test.ts +0 -193
- package/tests/index.test.ts +0 -160
- package/tests/integration/homeassistant.test.ts +0 -144
- package/tests/integration/omada.test.ts +0 -167
- package/tests/integration/server.test.ts +0 -151
- package/tests/localAI/index.test.ts +0 -177
- package/tests/localAI/ollama.test.ts +0 -187
- package/tests/localAI/openai.test.ts +0 -257
- package/tests/omadaClient/actions.test.ts +0 -161
- package/tests/omadaClient/clientBlocks.test.ts +0 -170
- package/tests/omadaClient/ntp.test.ts +0 -381
- package/tests/omadaClient/site.test.ts +0 -37
- package/tests/ownerQuestions/service.test.ts +0 -499
- package/tests/ownerQuestions/tools.test.ts +0 -186
- package/tests/permissions/index.test.ts +0 -217
- package/tests/resources/index.test.ts +0 -288
- package/tests/scripts/generateJwt.test.ts +0 -44
- package/tests/security/accessControl.test.ts +0 -223
- package/tests/security/authentication.test.ts +0 -117
- package/tests/security/configuration.test.ts +0 -170
- package/tests/security/cryptoTransport.test.ts +0 -172
- package/tests/security/dependencies.test.ts +0 -152
- package/tests/security/injection.test.ts +0 -117
- package/tests/security/insecureDesign.test.ts +0 -121
- package/tests/security/logging.test.ts +0 -131
- package/tests/security/resourceConsumption.test.ts +0 -142
- package/tests/server/auth.test.ts +0 -249
- package/tests/server/chatFace.test.ts +0 -320
- package/tests/server/common.test.ts +0 -84
- package/tests/server/http.test.ts +0 -561
- package/tests/server/instructions.test.ts +0 -152
- package/tests/server/memoizeJsonSchema.test.ts +0 -71
- package/tests/server/stdio.test.ts +0 -99
- package/tests/server/stream.test.ts +0 -285
- package/tests/server/toolVisibility.http.test.ts +0 -111
- package/tests/server/toolVisibility.test.ts +0 -129
- package/tests/tools/ai/analyzeSensors.test.ts +0 -227
- package/tests/tools/common.test.ts +0 -123
- package/tests/tools/homeassistant/handlers.test.ts +0 -872
- package/tests/tools/infra/invokeAction.test.ts +0 -280
- package/tests/tools/omada/graph.test.ts +0 -385
- package/tests/tools/omada/handlers.test.ts +0 -897
- package/tests/tools/omada/namespace.test.ts +0 -483
- package/tests/tools/registry.test.ts +0 -168
- package/tests/utils/config-validations.test.ts +0 -352
- package/tests/utils/jwt.test.ts +0 -115
- package/tests/utils/logger.test.ts +0 -327
- package/tests/utils/redact.test.ts +0 -105
- package/tsconfig.json +0 -24
- 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
|
-
}
|
package/src/omadaClient/index.ts
DELETED
|
@@ -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
|
-
}
|