@owine/unifi-protect-mcp 2.14.2 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +248 -92
- package/dist/client.d.ts +43 -3
- package/dist/client.js +255 -85
- package/dist/config.d.ts +7 -1
- package/dist/config.js +114 -6
- package/dist/index.js +14 -6
- package/dist/instructions.d.ts +6 -0
- package/dist/instructions.js +24 -0
- package/dist/schemas/cameras.d.ts +32 -30
- package/dist/schemas/cameras.js +7 -6
- package/dist/schemas/common.d.ts +31 -6
- package/dist/schemas/common.js +45 -6
- package/dist/schemas/devices.d.ts +2 -10
- package/dist/schemas/devices.js +35 -26
- package/dist/schemas/misc.d.ts +50 -18
- package/dist/schemas/misc.js +23 -15
- package/dist/schemas/pos.d.ts +1 -1
- package/dist/schemas/pos.js +1 -1
- package/dist/tls.d.ts +41 -0
- package/dist/tls.js +75 -0
- package/dist/tools/alarm-manager.d.ts +3 -0
- package/dist/tools/alarm-manager.js +32 -0
- package/dist/tools/arm-profiles.d.ts +8 -2
- package/dist/tools/arm-profiles.js +98 -95
- package/dist/tools/cameras.d.ts +2 -2
- package/dist/tools/cameras.js +156 -181
- package/dist/tools/device-actions.d.ts +2 -2
- package/dist/tools/device-actions.js +84 -97
- package/dist/tools/devices.d.ts +6 -3
- package/dist/tools/devices.js +50 -51
- package/dist/tools/files.d.ts +2 -2
- package/dist/tools/files.js +82 -57
- package/dist/tools/index.d.ts +2 -2
- package/dist/tools/index.js +15 -10
- package/dist/tools/liveviews.d.ts +2 -2
- package/dist/tools/liveviews.js +52 -52
- package/dist/tools/pos.d.ts +6 -4
- package/dist/tools/pos.js +15 -20
- package/dist/tools/registrar.d.ts +34 -0
- package/dist/tools/registrar.js +103 -0
- package/dist/tools/subscriptions.d.ts +13 -2
- package/dist/tools/subscriptions.js +148 -27
- package/dist/tools/system.d.ts +2 -2
- package/dist/tools/system.js +5 -15
- package/dist/tools/users.d.ts +2 -2
- package/dist/tools/users.js +18 -35
- package/dist/utils/limits.d.ts +33 -0
- package/dist/utils/limits.js +74 -0
- package/dist/utils/paging.d.ts +15 -0
- package/dist/utils/paging.js +28 -0
- package/dist/utils/params.d.ts +13 -0
- package/dist/utils/params.js +40 -0
- package/dist/utils/responses.js +2 -3
- package/dist/utils/safety.d.ts +39 -3
- package/dist/utils/safety.js +45 -3
- package/dist/utils/url.d.ts +4 -1
- package/dist/utils/url.js +4 -1
- package/dist/version.d.ts +6 -0
- package/dist/version.js +11 -0
- package/package.json +14 -12
package/dist/schemas/misc.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
/**
|
|
3
3
|
* Schemas below are verified against live UniFi Protect Integration API 7.3.47
|
|
4
|
-
* responses (Melrose NVR Pro console, 2026-09-14) where instances exist
|
|
5
|
-
*
|
|
6
|
-
* instances on the console). The Integration API surface is much thinner than
|
|
4
|
+
* responses (Melrose NVR Pro console, 2026-09-14) where instances exist —
|
|
5
|
+
* re-verified live on 7.3.70 (2026-10-12) — and against the 7.3.70 published
|
|
6
|
+
* docs otherwise (arm profiles, files — no instances on the console). The Integration API surface is much thinner than
|
|
7
7
|
* the internal Protect app API — only observed/documented fields are typed;
|
|
8
|
-
* `.
|
|
8
|
+
* `.loose()` still allows anything extra a firmware/hardware mix adds.
|
|
9
9
|
*/
|
|
10
10
|
export declare const infoOutputSchema: {
|
|
11
11
|
applicationVersion: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
@@ -17,13 +17,13 @@ export declare const nvrSchema: z.ZodObject<{
|
|
|
17
17
|
modelKey: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
18
18
|
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
19
19
|
mac: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
20
|
-
doorbellSettings: z.ZodOptional<z.ZodObject<{
|
|
20
|
+
doorbellSettings: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
21
21
|
defaultMessageText: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
22
22
|
defaultMessageResetTimeoutMs: z.ZodOptional<z.ZodUnknown>;
|
|
23
23
|
customMessages: z.ZodOptional<z.ZodUnknown>;
|
|
24
24
|
customImages: z.ZodOptional<z.ZodUnknown>;
|
|
25
|
-
}, z.core.$loose
|
|
26
|
-
armMode: z.ZodOptional<z.ZodObject<{
|
|
25
|
+
}, z.core.$loose>>>;
|
|
26
|
+
armMode: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
27
27
|
status: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
28
28
|
armProfileId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
29
29
|
armedAt: z.ZodOptional<z.ZodUnknown>;
|
|
@@ -32,7 +32,7 @@ export declare const nvrSchema: z.ZodObject<{
|
|
|
32
32
|
breachEventCount: z.ZodOptional<z.ZodUnknown>;
|
|
33
33
|
breachTriggerEventId: z.ZodOptional<z.ZodUnknown>;
|
|
34
34
|
breachEventId: z.ZodOptional<z.ZodUnknown>;
|
|
35
|
-
}, z.core.$loose
|
|
35
|
+
}, z.core.$loose>>>;
|
|
36
36
|
}, z.core.$loose>;
|
|
37
37
|
export declare const nvrOutputSchema: {
|
|
38
38
|
type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
@@ -41,13 +41,13 @@ export declare const nvrOutputSchema: {
|
|
|
41
41
|
modelKey: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
42
42
|
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
43
43
|
mac: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
44
|
-
doorbellSettings: z.ZodOptional<z.ZodObject<{
|
|
44
|
+
doorbellSettings: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
45
45
|
defaultMessageText: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
46
46
|
defaultMessageResetTimeoutMs: z.ZodOptional<z.ZodUnknown>;
|
|
47
47
|
customMessages: z.ZodOptional<z.ZodUnknown>;
|
|
48
48
|
customImages: z.ZodOptional<z.ZodUnknown>;
|
|
49
|
-
}, z.core.$loose
|
|
50
|
-
armMode: z.ZodOptional<z.ZodObject<{
|
|
49
|
+
}, z.core.$loose>>>;
|
|
50
|
+
armMode: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
51
51
|
status: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
52
52
|
armProfileId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
53
53
|
armedAt: z.ZodOptional<z.ZodUnknown>;
|
|
@@ -56,7 +56,7 @@ export declare const nvrOutputSchema: {
|
|
|
56
56
|
breachEventCount: z.ZodOptional<z.ZodUnknown>;
|
|
57
57
|
breachTriggerEventId: z.ZodOptional<z.ZodUnknown>;
|
|
58
58
|
breachEventId: z.ZodOptional<z.ZodUnknown>;
|
|
59
|
-
}, z.core.$loose
|
|
59
|
+
}, z.core.$loose>>>;
|
|
60
60
|
};
|
|
61
61
|
export declare const userSchema: z.ZodObject<{
|
|
62
62
|
id: z.ZodOptional<z.ZodString>;
|
|
@@ -86,6 +86,8 @@ export declare const userListOutputSchema: {
|
|
|
86
86
|
email: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
87
87
|
ucoreUserId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
88
88
|
}, z.core.$loose>>;
|
|
89
|
+
totalCount: z.ZodOptional<z.ZodNumber>;
|
|
90
|
+
offset: z.ZodOptional<z.ZodNumber>;
|
|
89
91
|
};
|
|
90
92
|
export declare const ulpUserSchema: z.ZodObject<{
|
|
91
93
|
id: z.ZodOptional<z.ZodString>;
|
|
@@ -115,6 +117,8 @@ export declare const ulpUserListOutputSchema: {
|
|
|
115
117
|
email: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
116
118
|
status: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
117
119
|
}, z.core.$loose>>;
|
|
120
|
+
totalCount: z.ZodOptional<z.ZodNumber>;
|
|
121
|
+
offset: z.ZodOptional<z.ZodNumber>;
|
|
118
122
|
};
|
|
119
123
|
export declare const liveviewSchema: z.ZodObject<{
|
|
120
124
|
id: z.ZodOptional<z.ZodString>;
|
|
@@ -124,11 +128,11 @@ export declare const liveviewSchema: z.ZodObject<{
|
|
|
124
128
|
isGlobal: z.ZodOptional<z.ZodUnknown>;
|
|
125
129
|
layout: z.ZodOptional<z.ZodUnknown>;
|
|
126
130
|
owner: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
127
|
-
slots: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
131
|
+
slots: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
128
132
|
cameras: z.ZodOptional<z.ZodUnknown>;
|
|
129
133
|
cycleMode: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
130
134
|
cycleInterval: z.ZodOptional<z.ZodUnknown>;
|
|
131
|
-
}, z.core.$loose
|
|
135
|
+
}, z.core.$loose>>>>;
|
|
132
136
|
}, z.core.$loose>;
|
|
133
137
|
export declare const liveviewOutputSchema: {
|
|
134
138
|
id: z.ZodOptional<z.ZodString>;
|
|
@@ -138,11 +142,11 @@ export declare const liveviewOutputSchema: {
|
|
|
138
142
|
isGlobal: z.ZodOptional<z.ZodUnknown>;
|
|
139
143
|
layout: z.ZodOptional<z.ZodUnknown>;
|
|
140
144
|
owner: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
141
|
-
slots: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
145
|
+
slots: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
142
146
|
cameras: z.ZodOptional<z.ZodUnknown>;
|
|
143
147
|
cycleMode: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
144
148
|
cycleInterval: z.ZodOptional<z.ZodUnknown>;
|
|
145
|
-
}, z.core.$loose
|
|
149
|
+
}, z.core.$loose>>>>;
|
|
146
150
|
};
|
|
147
151
|
export declare const liveviewListOutputSchema: {
|
|
148
152
|
result: z.ZodArray<z.ZodObject<{
|
|
@@ -153,12 +157,14 @@ export declare const liveviewListOutputSchema: {
|
|
|
153
157
|
isGlobal: z.ZodOptional<z.ZodUnknown>;
|
|
154
158
|
layout: z.ZodOptional<z.ZodUnknown>;
|
|
155
159
|
owner: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
156
|
-
slots: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
160
|
+
slots: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
157
161
|
cameras: z.ZodOptional<z.ZodUnknown>;
|
|
158
162
|
cycleMode: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
159
163
|
cycleInterval: z.ZodOptional<z.ZodUnknown>;
|
|
160
|
-
}, z.core.$loose
|
|
164
|
+
}, z.core.$loose>>>>;
|
|
161
165
|
}, z.core.$loose>>;
|
|
166
|
+
totalCount: z.ZodOptional<z.ZodNumber>;
|
|
167
|
+
offset: z.ZodOptional<z.ZodNumber>;
|
|
162
168
|
};
|
|
163
169
|
export declare const armProfileSchema: z.ZodObject<{
|
|
164
170
|
id: z.ZodOptional<z.ZodString>;
|
|
@@ -183,6 +189,8 @@ export declare const armProfileListOutputSchema: {
|
|
|
183
189
|
createdAt: z.ZodOptional<z.ZodUnknown>;
|
|
184
190
|
updatedAt: z.ZodOptional<z.ZodUnknown>;
|
|
185
191
|
}, z.core.$loose>>;
|
|
192
|
+
totalCount: z.ZodOptional<z.ZodNumber>;
|
|
193
|
+
offset: z.ZodOptional<z.ZodNumber>;
|
|
186
194
|
};
|
|
187
195
|
export declare const armProfileOutputSchema: {
|
|
188
196
|
id: z.ZodOptional<z.ZodString>;
|
|
@@ -196,21 +204,45 @@ export declare const armProfileOutputSchema: {
|
|
|
196
204
|
updatedAt: z.ZodOptional<z.ZodUnknown>;
|
|
197
205
|
};
|
|
198
206
|
export declare const fileSchema: z.ZodObject<{
|
|
207
|
+
id: z.ZodOptional<z.ZodString>;
|
|
199
208
|
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
200
209
|
type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
201
210
|
originalName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
202
211
|
path: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
212
|
+
size: z.ZodOptional<z.ZodUnknown>;
|
|
213
|
+
createdAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
214
|
+
updatedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
215
|
+
metadata: z.ZodOptional<z.ZodUnknown>;
|
|
203
216
|
}, z.core.$loose>;
|
|
204
217
|
export declare const fileListOutputSchema: {
|
|
205
218
|
result: z.ZodArray<z.ZodObject<{
|
|
219
|
+
id: z.ZodOptional<z.ZodString>;
|
|
206
220
|
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
207
221
|
type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
208
222
|
originalName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
209
223
|
path: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
224
|
+
size: z.ZodOptional<z.ZodUnknown>;
|
|
225
|
+
createdAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
226
|
+
updatedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
227
|
+
metadata: z.ZodOptional<z.ZodUnknown>;
|
|
210
228
|
}, z.core.$loose>>;
|
|
229
|
+
totalCount: z.ZodOptional<z.ZodNumber>;
|
|
230
|
+
offset: z.ZodOptional<z.ZodNumber>;
|
|
231
|
+
};
|
|
232
|
+
export declare const fileOutputSchema: {
|
|
233
|
+
id: z.ZodOptional<z.ZodString>;
|
|
234
|
+
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
235
|
+
type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
236
|
+
originalName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
237
|
+
path: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
238
|
+
size: z.ZodOptional<z.ZodUnknown>;
|
|
239
|
+
createdAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
240
|
+
updatedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
241
|
+
metadata: z.ZodOptional<z.ZodUnknown>;
|
|
211
242
|
};
|
|
212
243
|
export declare const subscriptionOutputSchema: {
|
|
213
244
|
messages: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
214
245
|
duration: z.ZodOptional<z.ZodUnknown>;
|
|
215
246
|
error: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
247
|
+
truncated: z.ZodOptional<z.ZodUnknown>;
|
|
216
248
|
};
|
package/dist/schemas/misc.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.subscriptionOutputSchema = exports.fileListOutputSchema = exports.fileSchema = exports.armProfileOutputSchema = exports.armProfileListOutputSchema = exports.armProfileSchema = exports.liveviewListOutputSchema = exports.liveviewOutputSchema = exports.liveviewSchema = exports.ulpUserListOutputSchema = exports.ulpUserOutputSchema = exports.ulpUserSchema = exports.userListOutputSchema = exports.userOutputSchema = exports.userSchema = exports.nvrOutputSchema = exports.nvrSchema = exports.infoOutputSchema = void 0;
|
|
3
|
+
exports.subscriptionOutputSchema = exports.fileOutputSchema = exports.fileListOutputSchema = exports.fileSchema = exports.armProfileOutputSchema = exports.armProfileListOutputSchema = exports.armProfileSchema = exports.liveviewListOutputSchema = exports.liveviewOutputSchema = exports.liveviewSchema = exports.ulpUserListOutputSchema = exports.ulpUserOutputSchema = exports.ulpUserSchema = exports.userListOutputSchema = exports.userOutputSchema = exports.userSchema = exports.nvrOutputSchema = exports.nvrSchema = exports.infoOutputSchema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const common_js_1 = require("./common.js");
|
|
6
6
|
/**
|
|
7
7
|
* Schemas below are verified against live UniFi Protect Integration API 7.3.47
|
|
8
|
-
* responses (Melrose NVR Pro console, 2026-09-14) where instances exist
|
|
9
|
-
*
|
|
10
|
-
* instances on the console). The Integration API surface is much thinner than
|
|
8
|
+
* responses (Melrose NVR Pro console, 2026-09-14) where instances exist —
|
|
9
|
+
* re-verified live on 7.3.70 (2026-10-12) — and against the 7.3.70 published
|
|
10
|
+
* docs otherwise (arm profiles, files — no instances on the console). The Integration API surface is much thinner than
|
|
11
11
|
* the internal Protect app API — only observed/documented fields are typed;
|
|
12
|
-
* `.
|
|
12
|
+
* `.loose()` still allows anything extra a firmware/hardware mix adds.
|
|
13
13
|
*/
|
|
14
14
|
// --- System ---
|
|
15
15
|
exports.infoOutputSchema = {
|
|
@@ -30,7 +30,7 @@ const doorbellSettingsSchema = (0, common_js_1.passthroughObject)({
|
|
|
30
30
|
defaultMessageText: (0, common_js_1.nullableString)("Default doorbell LCD message"),
|
|
31
31
|
defaultMessageResetTimeoutMs: (0, common_js_1.unknownField)("Reset timeout in ms (number)"),
|
|
32
32
|
customMessages: (0, common_js_1.unknownField)("Configured custom LCD messages (array of strings)"),
|
|
33
|
-
customImages: (0, common_js_1.unknownField)("Configured custom LCD images (array)"),
|
|
33
|
+
customImages: (0, common_js_1.unknownField)("Configured custom LCD images (array of objects: preview, sprite)"),
|
|
34
34
|
});
|
|
35
35
|
exports.nvrSchema = (0, common_js_1.passthroughObject)({
|
|
36
36
|
id: (0, common_js_1.idField)("NVR ID"),
|
|
@@ -38,8 +38,8 @@ exports.nvrSchema = (0, common_js_1.passthroughObject)({
|
|
|
38
38
|
name: (0, common_js_1.nullableString)("NVR name"),
|
|
39
39
|
...(0, common_js_1.hardwareModelFields)(),
|
|
40
40
|
mac: (0, common_js_1.nullableString)("MAC address, added in 7.3.x"),
|
|
41
|
-
doorbellSettings: doorbellSettingsSchema.optional(),
|
|
42
|
-
armMode: armModeSchema.optional(),
|
|
41
|
+
doorbellSettings: doorbellSettingsSchema.nullable().optional(),
|
|
42
|
+
armMode: armModeSchema.nullable().optional(),
|
|
43
43
|
});
|
|
44
44
|
// Single object — use the shape directly, NOT a list wrapper.
|
|
45
45
|
exports.nvrOutputSchema = { ...exports.nvrSchema.shape };
|
|
@@ -62,7 +62,7 @@ exports.ulpUserSchema = (0, common_js_1.passthroughObject)({
|
|
|
62
62
|
lastName: (0, common_js_1.nullableString)("Last name"),
|
|
63
63
|
fullName: (0, common_js_1.nullableString)("Full name"),
|
|
64
64
|
email: (0, common_js_1.nullableString)("Email address, added in 7.3.x. Empty string for service accounts " +
|
|
65
|
-
"(verified live 7.3.
|
|
65
|
+
"(verified live 7.3.70)"),
|
|
66
66
|
status: (0, common_js_1.nullableString)("Account status, e.g. ACTIVE"),
|
|
67
67
|
});
|
|
68
68
|
exports.ulpUserOutputSchema = { ...exports.ulpUserSchema.shape };
|
|
@@ -81,12 +81,12 @@ exports.liveviewSchema = (0, common_js_1.passthroughObject)({
|
|
|
81
81
|
isGlobal: (0, common_js_1.unknownField)("Whether shared across all users (boolean)"),
|
|
82
82
|
layout: (0, common_js_1.unknownField)("Grid layout / slot count (number)"),
|
|
83
83
|
owner: (0, common_js_1.nullableString)("Owning user ID"),
|
|
84
|
-
slots: zod_1.z.array(liveviewSlotSchema).optional().describe("Camera slots"),
|
|
84
|
+
slots: zod_1.z.array(liveviewSlotSchema).nullable().optional().describe("Camera slots"),
|
|
85
85
|
});
|
|
86
86
|
exports.liveviewOutputSchema = { ...exports.liveviewSchema.shape };
|
|
87
87
|
exports.liveviewListOutputSchema = (0, common_js_1.listResultSchema)(exports.liveviewSchema);
|
|
88
88
|
// --- Arm profiles ---
|
|
89
|
-
// Fields from the 7.
|
|
89
|
+
// Fields from the 7.3.70 docs (no instances on the console to verify live).
|
|
90
90
|
// Arm profiles carry no `modelKey`. Nested arrays stay unknownField.
|
|
91
91
|
exports.armProfileSchema = (0, common_js_1.passthroughObject)({
|
|
92
92
|
id: (0, common_js_1.idField)("Arm profile ID"),
|
|
@@ -102,21 +102,29 @@ exports.armProfileSchema = (0, common_js_1.passthroughObject)({
|
|
|
102
102
|
exports.armProfileListOutputSchema = (0, common_js_1.listResultSchema)(exports.armProfileSchema);
|
|
103
103
|
exports.armProfileOutputSchema = { ...exports.armProfileSchema.shape };
|
|
104
104
|
// --- Files ---
|
|
105
|
-
// Device asset files (only fileType=animations supported).
|
|
106
|
-
//
|
|
105
|
+
// Device asset files (only fileType=animations supported). The 7.3.70 docs show
|
|
106
|
+
// { name, type, originalName, path }; live 7.3.70 records (2026-10-12) also
|
|
107
|
+
// carry id (equal to name), size, createdAt, updatedAt and metadata. No modelKey.
|
|
107
108
|
exports.fileSchema = (0, common_js_1.passthroughObject)({
|
|
109
|
+
id: (0, common_js_1.idField)("File ID (same value as name)"),
|
|
108
110
|
name: (0, common_js_1.nullableString)("Stored file name (server-generated)"),
|
|
109
111
|
type: (0, common_js_1.nullableString)('Asset file type, e.g. "animations"'),
|
|
110
|
-
originalName: (0, common_js_1.nullableString)(
|
|
112
|
+
originalName: (0, common_js_1.nullableString)('Uploaded file name; Protect appends the stored extension, e.g. "welcome.gif.png"'),
|
|
111
113
|
path: (0, common_js_1.nullableString)("Server-side storage path"),
|
|
114
|
+
size: (0, common_js_1.unknownField)("File size in bytes (number)"),
|
|
115
|
+
createdAt: (0, common_js_1.nullableString)("Creation time (ISO 8601)"),
|
|
116
|
+
updatedAt: (0, common_js_1.nullableString)("Last update time (ISO 8601)"),
|
|
117
|
+
metadata: (0, common_js_1.unknownField)("Asset metadata (object, empty in observed records)"),
|
|
112
118
|
});
|
|
113
119
|
exports.fileListOutputSchema = (0, common_js_1.listResultSchema)(exports.fileSchema);
|
|
120
|
+
exports.fileOutputSchema = { ...exports.fileSchema.shape };
|
|
114
121
|
// --- Subscriptions ---
|
|
115
122
|
exports.subscriptionOutputSchema = {
|
|
116
123
|
messages: zod_1.z
|
|
117
124
|
.array(zod_1.z.unknown())
|
|
118
125
|
.optional()
|
|
119
126
|
.describe("Captured WebSocket messages (add/update/remove or event envelopes)"),
|
|
120
|
-
duration: (0, common_js_1.unknownField)("
|
|
127
|
+
duration: (0, common_js_1.unknownField)("Seconds actually spent listening, to 0.1s (number); shorter than requested when the message cap or an error ends the listen early"),
|
|
121
128
|
error: (0, common_js_1.nullableString)("Connection error, if any"),
|
|
129
|
+
truncated: (0, common_js_1.unknownField)("true when listening stopped early at the message cap (boolean, absent otherwise)"),
|
|
122
130
|
};
|
package/dist/schemas/pos.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Point-of-sale event ingestion, added in UniFi Protect 7.3.x
|
|
3
3
|
* (POST /v1/pos/cameras/{id}/transactions).
|
|
4
4
|
*
|
|
5
|
-
* Shape taken from the 7.3.
|
|
5
|
+
* Shape taken from the 7.3.70 published docs with the response sample expanded
|
|
6
6
|
* — there is no POS-capable register on the available console, so this is
|
|
7
7
|
* doc-verified rather than live-verified. `created` stays `unknownField()`
|
|
8
8
|
* because we have not observed the boolean live; `eventId` publishes the string
|
package/dist/schemas/pos.js
CHANGED
|
@@ -6,7 +6,7 @@ const common_js_1 = require("./common.js");
|
|
|
6
6
|
* Point-of-sale event ingestion, added in UniFi Protect 7.3.x
|
|
7
7
|
* (POST /v1/pos/cameras/{id}/transactions).
|
|
8
8
|
*
|
|
9
|
-
* Shape taken from the 7.3.
|
|
9
|
+
* Shape taken from the 7.3.70 published docs with the response sample expanded
|
|
10
10
|
* — there is no POS-capable register on the available console, so this is
|
|
11
11
|
* doc-verified rather than live-verified. `created` stays `unknownField()`
|
|
12
12
|
* because we have not observed the boolean live; `eventId` publishes the string
|
package/dist/tls.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { X509Certificate } from "node:crypto";
|
|
2
|
+
import { type PeerCertificate } from "node:tls";
|
|
3
|
+
import { type Dispatcher } from "undici";
|
|
4
|
+
/** Every certificate in a PEM bundle. Throws on a malformed certificate block. */
|
|
5
|
+
export declare function pemCertificates(pem: string): X509Certificate[];
|
|
6
|
+
interface TlsSettings {
|
|
7
|
+
verifySsl: boolean;
|
|
8
|
+
caCert?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* TLS options for a connection to the console, shared by requests and the
|
|
12
|
+
* subscription WebSocket. They are scoped to this client, not set in the
|
|
13
|
+
* process-wide NODE_TLS_REJECT_UNAUTHORIZED, which turned verification off for
|
|
14
|
+
* every other TLS connection in the process as well.
|
|
15
|
+
*/
|
|
16
|
+
export declare function consoleTlsOptions({ verifySsl, caCert }: TlsSettings): {
|
|
17
|
+
rejectUnauthorized: boolean;
|
|
18
|
+
ca?: undefined;
|
|
19
|
+
allowPartialTrustChain?: undefined;
|
|
20
|
+
checkServerIdentity?: undefined;
|
|
21
|
+
} | {
|
|
22
|
+
rejectUnauthorized?: undefined;
|
|
23
|
+
ca?: undefined;
|
|
24
|
+
allowPartialTrustChain?: undefined;
|
|
25
|
+
checkServerIdentity?: undefined;
|
|
26
|
+
} | {
|
|
27
|
+
rejectUnauthorized?: undefined;
|
|
28
|
+
ca: string;
|
|
29
|
+
allowPartialTrustChain: boolean;
|
|
30
|
+
checkServerIdentity: (host: string, cert: PeerCertificate) => Error | undefined;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* The dispatcher for requests to the console: its TLS settings, and
|
|
34
|
+
* connections kept open across the gaps between a model's calls instead of
|
|
35
|
+
* paying a new TLS handshake each time. HTTP/1.1 only, as Node's built-in
|
|
36
|
+
* fetch speaks, rather than undici's default of offering HTTP/2. With Node's
|
|
37
|
+
* env proxy turned on, requests go through HTTP_PROXY / HTTPS_PROXY (minus
|
|
38
|
+
* NO_PROXY) as they did through the built-in fetch.
|
|
39
|
+
*/
|
|
40
|
+
export declare function consoleDispatcher(tls: TlsSettings): Dispatcher;
|
|
41
|
+
export {};
|
package/dist/tls.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.pemCertificates = pemCertificates;
|
|
4
|
+
exports.consoleTlsOptions = consoleTlsOptions;
|
|
5
|
+
exports.consoleDispatcher = consoleDispatcher;
|
|
6
|
+
const node_crypto_1 = require("node:crypto");
|
|
7
|
+
const node_tls_1 = require("node:tls");
|
|
8
|
+
const undici_1 = require("undici");
|
|
9
|
+
/** Every certificate in a PEM bundle. Throws on a malformed certificate block. */
|
|
10
|
+
function pemCertificates(pem) {
|
|
11
|
+
const blocks = pem.match(/-----BEGIN CERTIFICATE-----[\s\S]+?-----END CERTIFICATE-----/g) ?? [];
|
|
12
|
+
return blocks.map((block) => new node_crypto_1.X509Certificate(block));
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* TLS options for a connection to the console, shared by requests and the
|
|
16
|
+
* subscription WebSocket. They are scoped to this client, not set in the
|
|
17
|
+
* process-wide NODE_TLS_REJECT_UNAUTHORIZED, which turned verification off for
|
|
18
|
+
* every other TLS connection in the process as well.
|
|
19
|
+
*/
|
|
20
|
+
function consoleTlsOptions({ verifySsl, caCert }) {
|
|
21
|
+
if (!verifySsl)
|
|
22
|
+
return { rejectUnauthorized: false };
|
|
23
|
+
if (caCert === undefined)
|
|
24
|
+
return {};
|
|
25
|
+
// A console's self-signed certificate is issued to a name like unifi.local
|
|
26
|
+
// but reached by IP, so its hostname never matches. Accept the console when
|
|
27
|
+
// it presents exactly a pinned certificate; any other certificate, such as
|
|
28
|
+
// one issued by a pinned CA, still has to match the hostname.
|
|
29
|
+
const pinned = new Set(pemCertificates(caCert).map((cert) => cert.fingerprint256));
|
|
30
|
+
return {
|
|
31
|
+
ca: caCert,
|
|
32
|
+
// `ca` replaces the public roots, and OpenSSL otherwise accepts a chain
|
|
33
|
+
// only when it ends at a self-signed root. A pinned leaf or intermediate
|
|
34
|
+
// issued by a CA would then never verify, and checkServerIdentity (which
|
|
35
|
+
// runs only after the chain has) would never see the pin.
|
|
36
|
+
allowPartialTrustChain: true,
|
|
37
|
+
checkServerIdentity: (host, cert) => pinned.has(cert.fingerprint256) ? undefined : (0, node_tls_1.checkServerIdentity)(host, cert),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* How long an idle connection to the console is kept for the next call, when
|
|
42
|
+
* the server does not say (a Keep-Alive header's timeout wins). It has to end
|
|
43
|
+
* before the server's own idle timeout, or a call reuses a socket the server
|
|
44
|
+
* has just closed and fails with "other side closed"; a write is not retried.
|
|
45
|
+
* Proxies in front of api.ui.com and consoles commonly close at 60 s (AWS
|
|
46
|
+
* load balancers) or 75 s (nginx), so this stays well short of both while
|
|
47
|
+
* still covering the usual gap between a model's calls.
|
|
48
|
+
*/
|
|
49
|
+
const KEEP_ALIVE_MS = 20_000;
|
|
50
|
+
/**
|
|
51
|
+
* Whether Node routes its own fetch through HTTP_PROXY / HTTPS_PROXY. Node
|
|
52
|
+
* does so only when asked (NODE_USE_ENV_PROXY=1 or --use-env-proxy), so a
|
|
53
|
+
* proxy variable set for other tools never captures a local console's traffic.
|
|
54
|
+
*/
|
|
55
|
+
function nodeUsesEnvProxy() {
|
|
56
|
+
const flag = "--use-env-proxy";
|
|
57
|
+
return (process.env.NODE_USE_ENV_PROXY === "1" ||
|
|
58
|
+
process.execArgv.includes(flag) ||
|
|
59
|
+
(process.env.NODE_OPTIONS ?? "").split(/\s+/).includes(flag));
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The dispatcher for requests to the console: its TLS settings, and
|
|
63
|
+
* connections kept open across the gaps between a model's calls instead of
|
|
64
|
+
* paying a new TLS handshake each time. HTTP/1.1 only, as Node's built-in
|
|
65
|
+
* fetch speaks, rather than undici's default of offering HTTP/2. With Node's
|
|
66
|
+
* env proxy turned on, requests go through HTTP_PROXY / HTTPS_PROXY (minus
|
|
67
|
+
* NO_PROXY) as they did through the built-in fetch.
|
|
68
|
+
*/
|
|
69
|
+
function consoleDispatcher(tls) {
|
|
70
|
+
const connect = consoleTlsOptions(tls);
|
|
71
|
+
const options = { keepAliveTimeout: KEEP_ALIVE_MS, allowH2: false, connect };
|
|
72
|
+
return nodeUsesEnvProxy()
|
|
73
|
+
? new undici_1.EnvHttpProxyAgent({ ...options, requestTls: { ...connect, allowH2: false } })
|
|
74
|
+
: new undici_1.Agent(options);
|
|
75
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerAlarmManagerTools = registerAlarmManagerTools;
|
|
4
|
+
const responses_js_1 = require("../utils/responses.js");
|
|
5
|
+
const safety_js_1 = require("../utils/safety.js");
|
|
6
|
+
const url_js_1 = require("../utils/url.js");
|
|
7
|
+
const params_js_1 = require("../utils/params.js");
|
|
8
|
+
// Each gate's confirm input and handler check share one action text.
|
|
9
|
+
const TRIGGER_WEBHOOK = (0, safety_js_1.confirmGate)("trigger the alarm webhook");
|
|
10
|
+
function registerAlarmManagerTools(server, client, readOnly) {
|
|
11
|
+
if (readOnly)
|
|
12
|
+
return;
|
|
13
|
+
server.registerTool("protect_trigger_alarm_webhook", {
|
|
14
|
+
description: "Trigger an alarm manager webhook by ID. This fires the external alarm action configured for it. Requires confirm: true.",
|
|
15
|
+
inputSchema: {
|
|
16
|
+
id: (0, params_js_1.webhookId)()
|
|
17
|
+
.describe("User-defined webhook ID matching an alarm manager configuration"),
|
|
18
|
+
confirm: TRIGGER_WEBHOOK.input,
|
|
19
|
+
dryRun: (0, safety_js_1.dryRunInput)(),
|
|
20
|
+
},
|
|
21
|
+
annotations: safety_js_1.DESTRUCTIVE,
|
|
22
|
+
}, async ({ id, confirm, dryRun }) => {
|
|
23
|
+
if (dryRun) {
|
|
24
|
+
return (0, safety_js_1.formatDryRun)("POST", (0, url_js_1.safePath) `/alarm-manager/webhook/${id}`);
|
|
25
|
+
}
|
|
26
|
+
const denied = TRIGGER_WEBHOOK.check(confirm);
|
|
27
|
+
if (denied)
|
|
28
|
+
return denied;
|
|
29
|
+
await client.post((0, url_js_1.safePath) `/alarm-manager/webhook/${id}`);
|
|
30
|
+
return (0, responses_js_1.formatSuccess)({ triggered: true, webhookId: id });
|
|
31
|
+
});
|
|
32
|
+
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ToolRegistrar } from "./registrar.js";
|
|
2
2
|
import { ProtectClient } from "../client.js";
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Arm profile settings that change what the alarm protects, and when: a
|
|
5
|
+
* longer activationDelay leaves the site unprotected for longer after arming,
|
|
6
|
+
* and recordEverything decides whether an armed site records at all.
|
|
7
|
+
*/
|
|
8
|
+
export declare const ARM_PROFILE_CONFIRM_FIELDS: readonly ["schedules", "automations", "activationDelay", "recordEverything"];
|
|
9
|
+
export declare function registerArmProfileTools(server: ToolRegistrar, client: ProtectClient, readOnly: boolean): void;
|