@camstack/addon-pipeline-orchestrator 0.1.14 → 0.1.15
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/dist/@mf-types/compiled-types/widgets/MotionZonesEditor.d.ts +19 -0
- package/dist/@mf-types/compiled-types/widgets/MotionZonesEditor.d.ts.map +1 -0
- package/dist/@mf-types/compiled-types/widgets/index.d.ts +2 -0
- package/dist/@mf-types/compiled-types/widgets/index.d.ts.map +1 -1
- package/dist/@mf-types/compiled-types/widgets/motion-zones/MotionGridCanvas.d.ts +20 -0
- package/dist/@mf-types/compiled-types/widgets/motion-zones/MotionGridCanvas.d.ts.map +1 -0
- package/dist/@mf-types/compiled-types/widgets/motion-zones/MotionZonesOverlay.d.ts +14 -0
- package/dist/@mf-types/compiled-types/widgets/motion-zones/MotionZonesOverlay.d.ts.map +1 -0
- package/dist/@mf-types/compiled-types/widgets/motion-zones/MotionZonesTab.d.ts +5 -0
- package/dist/@mf-types/compiled-types/widgets/motion-zones/MotionZonesTab.d.ts.map +1 -0
- package/dist/@mf-types.zip +0 -0
- package/dist/__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-UNj4rttw.mjs +20 -0
- package/dist/{__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-DFjvaOLq.mjs → __mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-Ue-jHwF0.mjs} +6 -5
- package/dist/_stub.js +4592 -4319
- package/dist/{hostInit-ClDM91fS.mjs → hostInit-DMdjwivI.mjs} +3 -3
- package/dist/{index-culBovFl.mjs → index-BIlr4dIX.mjs} +1 -1
- package/dist/{index-BP0-1QYT.mjs → index-BK5-EWzN.mjs} +2792 -2506
- package/dist/{index-D3EnGJOk.mjs → index-BUn7hM0v.mjs} +2514 -2404
- package/dist/index.js +334 -79
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +334 -79
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/__mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-DJg6MN3o.mjs +0 -20
package/dist/index.js
CHANGED
|
@@ -5136,6 +5136,9 @@ function hydrateField(field, values) {
|
|
|
5136
5136
|
return { ...field, value: items };
|
|
5137
5137
|
}
|
|
5138
5138
|
const rawValue = storedValue !== void 0 ? storedValue : defaultValue !== void 0 ? defaultValue : null;
|
|
5139
|
+
if (field.type === "password") {
|
|
5140
|
+
return { ...field, value: "" };
|
|
5141
|
+
}
|
|
5139
5142
|
const value = field.type === "textarea" && field.isJson && rawValue !== null && typeof rawValue === "object" ? JSON.stringify(rawValue, null, 2) : rawValue;
|
|
5140
5143
|
const hydrated = { ...field, value };
|
|
5141
5144
|
return hydrated;
|
|
@@ -7345,6 +7348,34 @@ MotionTriggerStatusSchema.extend({
|
|
|
7345
7348
|
}) }
|
|
7346
7349
|
}
|
|
7347
7350
|
});
|
|
7351
|
+
object({
|
|
7352
|
+
enabled: boolean(),
|
|
7353
|
+
sensitivity: number(),
|
|
7354
|
+
/** Row-major active-cell grid. Length = gridWidth*gridHeight (see getOptions). */
|
|
7355
|
+
cells: array(boolean()),
|
|
7356
|
+
lastFetchedAt: number()
|
|
7357
|
+
});
|
|
7358
|
+
const MotionZoneOptionsSchema = object({
|
|
7359
|
+
gridWidth: number(),
|
|
7360
|
+
gridHeight: number(),
|
|
7361
|
+
sensitivity: object({ min: number(), max: number(), step: number() })
|
|
7362
|
+
});
|
|
7363
|
+
const MotionZonePatchSchema = object({
|
|
7364
|
+
enabled: boolean().optional(),
|
|
7365
|
+
sensitivity: number().optional(),
|
|
7366
|
+
cells: array(boolean()).optional()
|
|
7367
|
+
});
|
|
7368
|
+
({
|
|
7369
|
+
deviceTypes: [DeviceType.Camera],
|
|
7370
|
+
methods: {
|
|
7371
|
+
getOptions: method(object({ deviceId: number() }), MotionZoneOptionsSchema),
|
|
7372
|
+
setZone: method(
|
|
7373
|
+
object({ deviceId: number(), patch: MotionZonePatchSchema }),
|
|
7374
|
+
_void(),
|
|
7375
|
+
{ kind: "mutation", auth: "admin" }
|
|
7376
|
+
)
|
|
7377
|
+
}
|
|
7378
|
+
});
|
|
7348
7379
|
const AutotrackTargetTypeSchema = string().describe("Vendor target string (people/vehicle/pet); empty = camera default");
|
|
7349
7380
|
const PtzAutotrackSettingsSchema = object({
|
|
7350
7381
|
targetType: AutotrackTargetTypeSchema,
|
|
@@ -7433,6 +7464,72 @@ PtzAutotrackStatusSchema.extend({
|
|
|
7433
7464
|
}) }
|
|
7434
7465
|
}
|
|
7435
7466
|
});
|
|
7467
|
+
const StreamProfileSchema = _enum(["main", "sub", "ext"]);
|
|
7468
|
+
const StreamProfileConfigSchema = object({
|
|
7469
|
+
width: number(),
|
|
7470
|
+
height: number(),
|
|
7471
|
+
codec: _enum(["h264", "h265"]),
|
|
7472
|
+
framerate: number(),
|
|
7473
|
+
bitrate: number(),
|
|
7474
|
+
// kbps
|
|
7475
|
+
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
7476
|
+
encoderProfile: _enum(["high", "main", "baseline"]).optional(),
|
|
7477
|
+
gop: number().optional(),
|
|
7478
|
+
audio: boolean().optional()
|
|
7479
|
+
});
|
|
7480
|
+
object({
|
|
7481
|
+
/** Per-profile current config. A profile absent = the camera doesn't have it. */
|
|
7482
|
+
main: StreamProfileConfigSchema.optional(),
|
|
7483
|
+
sub: StreamProfileConfigSchema.optional(),
|
|
7484
|
+
ext: StreamProfileConfigSchema.optional(),
|
|
7485
|
+
lastFetchedAt: number()
|
|
7486
|
+
});
|
|
7487
|
+
const StreamProfileOptionsSchema = object({
|
|
7488
|
+
resolutions: array(object({ width: number(), height: number() })),
|
|
7489
|
+
codecs: array(_enum(["h264", "h265"])),
|
|
7490
|
+
framerates: array(number()),
|
|
7491
|
+
/** Allowed bitrate values (kbps). Empty if the camera takes a free range. */
|
|
7492
|
+
bitrates: array(number()),
|
|
7493
|
+
/** Optional [min,max] kbps when the camera accepts a continuous range. */
|
|
7494
|
+
bitrateRange: tuple([number(), number()]).optional(),
|
|
7495
|
+
supportsBitrateMode: boolean(),
|
|
7496
|
+
supportsEncoderProfile: boolean(),
|
|
7497
|
+
supportsGop: boolean()
|
|
7498
|
+
});
|
|
7499
|
+
const StreamParamsOptionsSchema = object({
|
|
7500
|
+
main: StreamProfileOptionsSchema.optional(),
|
|
7501
|
+
sub: StreamProfileOptionsSchema.optional(),
|
|
7502
|
+
ext: StreamProfileOptionsSchema.optional()
|
|
7503
|
+
});
|
|
7504
|
+
const StreamProfilePatchSchema = object({
|
|
7505
|
+
width: number().optional(),
|
|
7506
|
+
height: number().optional(),
|
|
7507
|
+
codec: _enum(["h264", "h265"]).optional(),
|
|
7508
|
+
framerate: number().optional(),
|
|
7509
|
+
bitrate: number().optional(),
|
|
7510
|
+
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
7511
|
+
encoderProfile: _enum(["high", "main", "baseline"]).optional(),
|
|
7512
|
+
gop: number().optional(),
|
|
7513
|
+
audio: boolean().optional()
|
|
7514
|
+
});
|
|
7515
|
+
({
|
|
7516
|
+
deviceTypes: [DeviceType.Camera],
|
|
7517
|
+
methods: {
|
|
7518
|
+
getOptions: method(
|
|
7519
|
+
object({ deviceId: number() }),
|
|
7520
|
+
StreamParamsOptionsSchema
|
|
7521
|
+
),
|
|
7522
|
+
setProfile: method(
|
|
7523
|
+
object({
|
|
7524
|
+
deviceId: number(),
|
|
7525
|
+
profile: StreamProfileSchema,
|
|
7526
|
+
patch: StreamProfilePatchSchema
|
|
7527
|
+
}),
|
|
7528
|
+
_void(),
|
|
7529
|
+
{ kind: "mutation", auth: "admin" }
|
|
7530
|
+
)
|
|
7531
|
+
}
|
|
7532
|
+
});
|
|
7436
7533
|
object({
|
|
7437
7534
|
on: boolean(),
|
|
7438
7535
|
/** Ms epoch of the last state change. Useful for UI "X minutes ago". */
|
|
@@ -8373,6 +8470,83 @@ const VersionOutputSchema = object({ version: string() });
|
|
|
8373
8470
|
getVersion: method(_void(), VersionOutputSchema)
|
|
8374
8471
|
}
|
|
8375
8472
|
});
|
|
8473
|
+
const MethodAccessSchema = _enum(["view", "create", "delete"]);
|
|
8474
|
+
const AllowedProviderSchema = union([literal("*"), array(string())]);
|
|
8475
|
+
const AllowedDevicesSchema = record(string(), union([literal("*"), array(string())]));
|
|
8476
|
+
const CapScopeSchema = _enum(["device", "system"]);
|
|
8477
|
+
const TokenScopeSchema = discriminatedUnion("type", [
|
|
8478
|
+
object({
|
|
8479
|
+
type: literal("category"),
|
|
8480
|
+
target: CapScopeSchema,
|
|
8481
|
+
access: array(MethodAccessSchema).min(1)
|
|
8482
|
+
}),
|
|
8483
|
+
object({
|
|
8484
|
+
type: literal("capability"),
|
|
8485
|
+
target: string(),
|
|
8486
|
+
access: array(MethodAccessSchema).min(1)
|
|
8487
|
+
}),
|
|
8488
|
+
object({
|
|
8489
|
+
type: literal("addon"),
|
|
8490
|
+
target: string(),
|
|
8491
|
+
access: array(MethodAccessSchema).min(1)
|
|
8492
|
+
}),
|
|
8493
|
+
object({
|
|
8494
|
+
type: literal("device"),
|
|
8495
|
+
/**
|
|
8496
|
+
* One or more deviceIds (serialised as strings for wire-format
|
|
8497
|
+
* consistency with the rest of the union). Matcher accepts if
|
|
8498
|
+
* `input.deviceId` ∈ `targets`. Array shape avoids the row-explosion
|
|
8499
|
+
* of one scope-per-device when granting access to a set of cameras.
|
|
8500
|
+
*/
|
|
8501
|
+
targets: array(string()).min(1),
|
|
8502
|
+
access: array(MethodAccessSchema).min(1)
|
|
8503
|
+
})
|
|
8504
|
+
]);
|
|
8505
|
+
object({
|
|
8506
|
+
id: string(),
|
|
8507
|
+
username: string(),
|
|
8508
|
+
passwordHash: string(),
|
|
8509
|
+
/**
|
|
8510
|
+
* Admin bypass. When true, the middleware skips the scope-access
|
|
8511
|
+
* check entirely. There is no other axis of privilege; the legacy
|
|
8512
|
+
* role enum collapsed onto this boolean in v2.
|
|
8513
|
+
*/
|
|
8514
|
+
isAdmin: boolean().default(false),
|
|
8515
|
+
allowedProviders: AllowedProviderSchema,
|
|
8516
|
+
allowedDevices: AllowedDevicesSchema,
|
|
8517
|
+
/**
|
|
8518
|
+
* Scopes granted to this user. Admins bypass; their `scopes` is
|
|
8519
|
+
* ignored. Non-admins without scopes are locked out of every
|
|
8520
|
+
* protected call.
|
|
8521
|
+
*/
|
|
8522
|
+
scopes: array(TokenScopeSchema).default([]),
|
|
8523
|
+
createdAt: number(),
|
|
8524
|
+
updatedAt: number()
|
|
8525
|
+
});
|
|
8526
|
+
object({
|
|
8527
|
+
id: string(),
|
|
8528
|
+
label: string(),
|
|
8529
|
+
isAdmin: boolean().default(false),
|
|
8530
|
+
allowedProviders: AllowedProviderSchema,
|
|
8531
|
+
allowedDevices: AllowedDevicesSchema,
|
|
8532
|
+
tokenHash: string(),
|
|
8533
|
+
tokenPrefix: string(),
|
|
8534
|
+
createdAt: number(),
|
|
8535
|
+
lastUsedAt: number().optional()
|
|
8536
|
+
});
|
|
8537
|
+
object({
|
|
8538
|
+
id: string(),
|
|
8539
|
+
userId: string(),
|
|
8540
|
+
name: string(),
|
|
8541
|
+
tokenHash: string(),
|
|
8542
|
+
tokenPrefix: string(),
|
|
8543
|
+
scopes: array(TokenScopeSchema),
|
|
8544
|
+
// SQLite/JSON storage round-trips undefined → null. Use `nullish` so the
|
|
8545
|
+
// schema accepts both `null` (read from disk) and `undefined` (in-memory).
|
|
8546
|
+
expiresAt: number().nullish(),
|
|
8547
|
+
lastUsedAt: number().nullish(),
|
|
8548
|
+
createdAt: number()
|
|
8549
|
+
});
|
|
8376
8550
|
const SsoBridgeClaimsSchema = object({
|
|
8377
8551
|
userId: string(),
|
|
8378
8552
|
username: string(),
|
|
@@ -8388,7 +8562,18 @@ const SsoBridgeClaimsSchema = object({
|
|
|
8388
8562
|
* JWT WITHOUT verifying the signature — the hub re-verifies on every
|
|
8389
8563
|
* inbound call so trust still rests with the signing hub.
|
|
8390
8564
|
*/
|
|
8391
|
-
hubUrl: string().optional()
|
|
8565
|
+
hubUrl: string().optional(),
|
|
8566
|
+
/** Permission scopes baked into the token. Set by the OAuth
|
|
8567
|
+
* account-linking grant; absent on ordinary SSO-login tokens. */
|
|
8568
|
+
scopes: array(TokenScopeSchema).optional(),
|
|
8569
|
+
/** OAuth authorization-code binding — set only on `oauth-code` tokens. */
|
|
8570
|
+
redirectUri: string().optional(),
|
|
8571
|
+
integrationId: string().optional(),
|
|
8572
|
+
/** JWT ID — unique per issued code; consumed-set enforces single-use. */
|
|
8573
|
+
jti: string().optional(),
|
|
8574
|
+
/** OAuth session registry id — set on `oauth-access`/`oauth-refresh`
|
|
8575
|
+
* tokens so the verify path can check the session is not revoked. */
|
|
8576
|
+
sessionId: string().optional()
|
|
8392
8577
|
});
|
|
8393
8578
|
({
|
|
8394
8579
|
methods: {
|
|
@@ -8405,6 +8590,23 @@ const SsoBridgeClaimsSchema = object({
|
|
|
8405
8590
|
)
|
|
8406
8591
|
}
|
|
8407
8592
|
});
|
|
8593
|
+
const OauthIntegrationDescriptorSchema = object({
|
|
8594
|
+
/** Stable id used as the `integration=` query param, e.g. 'export-alexa'. */
|
|
8595
|
+
integrationId: string(),
|
|
8596
|
+
/** Human label rendered on the consent page. */
|
|
8597
|
+
displayName: string(),
|
|
8598
|
+
/** Scopes baked into every token issued for this integration. */
|
|
8599
|
+
requestedScopes: array(TokenScopeSchema),
|
|
8600
|
+
/** Allowed redirect_uri prefixes. /oauth2/authorize rejects any
|
|
8601
|
+
* redirect_uri that does not start with one of these. Required —
|
|
8602
|
+
* an empty list means the integration can never complete linking. */
|
|
8603
|
+
allowedRedirectPrefixes: array(string()).min(1)
|
|
8604
|
+
});
|
|
8605
|
+
({
|
|
8606
|
+
methods: {
|
|
8607
|
+
getDescriptor: method(_void(), OauthIntegrationDescriptorSchema)
|
|
8608
|
+
}
|
|
8609
|
+
});
|
|
8408
8610
|
const PasskeySummarySchema = object({
|
|
8409
8611
|
credentialId: string(),
|
|
8410
8612
|
label: string(),
|
|
@@ -11078,6 +11280,14 @@ const PtzMoveCommandSchema = object({
|
|
|
11078
11280
|
zoom: number().optional(),
|
|
11079
11281
|
speed: number().optional()
|
|
11080
11282
|
});
|
|
11283
|
+
const PtzOptionsSchema = object({
|
|
11284
|
+
hasPan: boolean(),
|
|
11285
|
+
hasTilt: boolean(),
|
|
11286
|
+
hasZoom: boolean(),
|
|
11287
|
+
supportsPresets: boolean(),
|
|
11288
|
+
/** Max number of named presets the camera supports, when known. */
|
|
11289
|
+
maxPresets: number().optional()
|
|
11290
|
+
});
|
|
11081
11291
|
({
|
|
11082
11292
|
deviceTypes: [DeviceType.Camera],
|
|
11083
11293
|
methods: {
|
|
@@ -11105,6 +11315,20 @@ const PtzMoveCommandSchema = object({
|
|
|
11105
11315
|
_void(),
|
|
11106
11316
|
{ kind: "mutation" }
|
|
11107
11317
|
),
|
|
11318
|
+
savePreset: method(
|
|
11319
|
+
object({ deviceId: number(), presetId: string(), name: string() }),
|
|
11320
|
+
_void(),
|
|
11321
|
+
{ kind: "mutation", auth: "admin" }
|
|
11322
|
+
),
|
|
11323
|
+
deletePreset: method(
|
|
11324
|
+
object({ deviceId: number(), presetId: string() }),
|
|
11325
|
+
_void(),
|
|
11326
|
+
{ kind: "mutation", auth: "admin" }
|
|
11327
|
+
),
|
|
11328
|
+
getOptions: method(
|
|
11329
|
+
object({ deviceId: number() }),
|
|
11330
|
+
PtzOptionsSchema
|
|
11331
|
+
),
|
|
11108
11332
|
goHome: method(
|
|
11109
11333
|
object({ deviceId: number() }),
|
|
11110
11334
|
_void(),
|
|
@@ -12054,83 +12278,6 @@ const MeshStatusSchema = object({
|
|
|
12054
12278
|
// tabs driven by this cap.
|
|
12055
12279
|
}
|
|
12056
12280
|
});
|
|
12057
|
-
const MethodAccessSchema = _enum(["view", "create", "delete"]);
|
|
12058
|
-
const AllowedProviderSchema = union([literal("*"), array(string())]);
|
|
12059
|
-
const AllowedDevicesSchema = record(string(), union([literal("*"), array(string())]));
|
|
12060
|
-
const CapScopeSchema = _enum(["device", "system"]);
|
|
12061
|
-
const TokenScopeSchema = discriminatedUnion("type", [
|
|
12062
|
-
object({
|
|
12063
|
-
type: literal("category"),
|
|
12064
|
-
target: CapScopeSchema,
|
|
12065
|
-
access: array(MethodAccessSchema).min(1)
|
|
12066
|
-
}),
|
|
12067
|
-
object({
|
|
12068
|
-
type: literal("capability"),
|
|
12069
|
-
target: string(),
|
|
12070
|
-
access: array(MethodAccessSchema).min(1)
|
|
12071
|
-
}),
|
|
12072
|
-
object({
|
|
12073
|
-
type: literal("addon"),
|
|
12074
|
-
target: string(),
|
|
12075
|
-
access: array(MethodAccessSchema).min(1)
|
|
12076
|
-
}),
|
|
12077
|
-
object({
|
|
12078
|
-
type: literal("device"),
|
|
12079
|
-
/**
|
|
12080
|
-
* One or more deviceIds (serialised as strings for wire-format
|
|
12081
|
-
* consistency with the rest of the union). Matcher accepts if
|
|
12082
|
-
* `input.deviceId` ∈ `targets`. Array shape avoids the row-explosion
|
|
12083
|
-
* of one scope-per-device when granting access to a set of cameras.
|
|
12084
|
-
*/
|
|
12085
|
-
targets: array(string()).min(1),
|
|
12086
|
-
access: array(MethodAccessSchema).min(1)
|
|
12087
|
-
})
|
|
12088
|
-
]);
|
|
12089
|
-
object({
|
|
12090
|
-
id: string(),
|
|
12091
|
-
username: string(),
|
|
12092
|
-
passwordHash: string(),
|
|
12093
|
-
/**
|
|
12094
|
-
* Admin bypass. When true, the middleware skips the scope-access
|
|
12095
|
-
* check entirely. There is no other axis of privilege; the legacy
|
|
12096
|
-
* role enum collapsed onto this boolean in v2.
|
|
12097
|
-
*/
|
|
12098
|
-
isAdmin: boolean().default(false),
|
|
12099
|
-
allowedProviders: AllowedProviderSchema,
|
|
12100
|
-
allowedDevices: AllowedDevicesSchema,
|
|
12101
|
-
/**
|
|
12102
|
-
* Scopes granted to this user. Admins bypass; their `scopes` is
|
|
12103
|
-
* ignored. Non-admins without scopes are locked out of every
|
|
12104
|
-
* protected call.
|
|
12105
|
-
*/
|
|
12106
|
-
scopes: array(TokenScopeSchema).default([]),
|
|
12107
|
-
createdAt: number(),
|
|
12108
|
-
updatedAt: number()
|
|
12109
|
-
});
|
|
12110
|
-
object({
|
|
12111
|
-
id: string(),
|
|
12112
|
-
label: string(),
|
|
12113
|
-
isAdmin: boolean().default(false),
|
|
12114
|
-
allowedProviders: AllowedProviderSchema,
|
|
12115
|
-
allowedDevices: AllowedDevicesSchema,
|
|
12116
|
-
tokenHash: string(),
|
|
12117
|
-
tokenPrefix: string(),
|
|
12118
|
-
createdAt: number(),
|
|
12119
|
-
lastUsedAt: number().optional()
|
|
12120
|
-
});
|
|
12121
|
-
object({
|
|
12122
|
-
id: string(),
|
|
12123
|
-
userId: string(),
|
|
12124
|
-
name: string(),
|
|
12125
|
-
tokenHash: string(),
|
|
12126
|
-
tokenPrefix: string(),
|
|
12127
|
-
scopes: array(TokenScopeSchema),
|
|
12128
|
-
// SQLite/JSON storage round-trips undefined → null. Use `nullish` so the
|
|
12129
|
-
// schema accepts both `null` (read from disk) and `undefined` (in-memory).
|
|
12130
|
-
expiresAt: number().nullish(),
|
|
12131
|
-
lastUsedAt: number().nullish(),
|
|
12132
|
-
createdAt: number()
|
|
12133
|
-
});
|
|
12134
12281
|
const UserSummarySchema = object({
|
|
12135
12282
|
id: string(),
|
|
12136
12283
|
username: string(),
|
|
@@ -12203,6 +12350,16 @@ const CreateScopedTokenResultSchema = object({
|
|
|
12203
12350
|
token: string(),
|
|
12204
12351
|
record: ScopedTokenSummarySchema
|
|
12205
12352
|
});
|
|
12353
|
+
const OauthSessionSummarySchema = object({
|
|
12354
|
+
id: string(),
|
|
12355
|
+
userId: string(),
|
|
12356
|
+
username: string(),
|
|
12357
|
+
integrationId: string(),
|
|
12358
|
+
scopes: array(TokenScopeSchema),
|
|
12359
|
+
createdAt: number(),
|
|
12360
|
+
lastUsedAt: number(),
|
|
12361
|
+
revokedAt: number().nullable()
|
|
12362
|
+
});
|
|
12206
12363
|
const TotpSetupResultSchema = object({
|
|
12207
12364
|
secret: string(),
|
|
12208
12365
|
otpauthUrl: string()
|
|
@@ -12278,6 +12435,66 @@ const TotpStatusSchema = object({
|
|
|
12278
12435
|
object({ userId: string(), code: string() }),
|
|
12279
12436
|
object({ valid: boolean() }),
|
|
12280
12437
|
{ kind: "mutation", access: "view" }
|
|
12438
|
+
),
|
|
12439
|
+
// ── OAuth account-linking grant ────────────────────────────────
|
|
12440
|
+
//
|
|
12441
|
+
// Core's /oauth2/* endpoints delegate here. Tokens are sso-bridge
|
|
12442
|
+
// JWTs (kinds oauth-code / oauth-access / oauth-refresh) and ALWAYS
|
|
12443
|
+
// carry isAdmin:false — the operator login proves hub control; the
|
|
12444
|
+
// issued token is minimal (device scope only).
|
|
12445
|
+
oauthIssueCode: method(
|
|
12446
|
+
object({
|
|
12447
|
+
integrationId: string(),
|
|
12448
|
+
userId: string(),
|
|
12449
|
+
username: string(),
|
|
12450
|
+
scopes: array(TokenScopeSchema),
|
|
12451
|
+
redirectUri: string(),
|
|
12452
|
+
hubUrl: string()
|
|
12453
|
+
}),
|
|
12454
|
+
object({ code: string() }),
|
|
12455
|
+
{ kind: "mutation", access: "create" }
|
|
12456
|
+
),
|
|
12457
|
+
oauthExchangeCode: method(
|
|
12458
|
+
object({ code: string(), redirectUri: string() }),
|
|
12459
|
+
object({
|
|
12460
|
+
accessToken: string(),
|
|
12461
|
+
refreshToken: string(),
|
|
12462
|
+
expiresIn: number()
|
|
12463
|
+
}).nullable(),
|
|
12464
|
+
{ kind: "mutation", access: "view" }
|
|
12465
|
+
),
|
|
12466
|
+
oauthRefresh: method(
|
|
12467
|
+
object({ refreshToken: string() }),
|
|
12468
|
+
object({
|
|
12469
|
+
accessToken: string(),
|
|
12470
|
+
refreshToken: string(),
|
|
12471
|
+
expiresIn: number()
|
|
12472
|
+
}).nullable(),
|
|
12473
|
+
{ kind: "mutation", access: "view" }
|
|
12474
|
+
),
|
|
12475
|
+
oauthVerifyAccessToken: method(
|
|
12476
|
+
object({ token: string() }),
|
|
12477
|
+
object({
|
|
12478
|
+
userId: string(),
|
|
12479
|
+
username: string(),
|
|
12480
|
+
scopes: array(TokenScopeSchema)
|
|
12481
|
+
}).nullable(),
|
|
12482
|
+
{ access: "view" }
|
|
12483
|
+
),
|
|
12484
|
+
// ── OAuth linked-session management (Phase D) ──────────────────
|
|
12485
|
+
//
|
|
12486
|
+
// The admin UI lists active account-linking sessions and revokes
|
|
12487
|
+
// them; revocation makes the linked integration's tokens fail
|
|
12488
|
+
// verification immediately.
|
|
12489
|
+
listOauthSessions: method(
|
|
12490
|
+
_void(),
|
|
12491
|
+
array(OauthSessionSummarySchema),
|
|
12492
|
+
{ auth: "admin" }
|
|
12493
|
+
),
|
|
12494
|
+
revokeOauthSession: method(
|
|
12495
|
+
object({ id: string() }),
|
|
12496
|
+
object({ success: boolean() }),
|
|
12497
|
+
{ kind: "mutation", auth: "admin", access: "delete" }
|
|
12281
12498
|
)
|
|
12282
12499
|
}
|
|
12283
12500
|
});
|
|
@@ -14780,6 +14997,24 @@ class PipelineOrchestratorAddon extends BaseAddon {
|
|
|
14780
14997
|
allowedSizes: ["lg", "xl"],
|
|
14781
14998
|
defaultColumns: 12,
|
|
14782
14999
|
defaultRows: 4
|
|
15000
|
+
},
|
|
15001
|
+
{
|
|
15002
|
+
// On-camera motion-detection grid editor. The `motion-zones`
|
|
15003
|
+
// cap is owned by the camera provider addons; the widget only
|
|
15004
|
+
// talks to it over tRPC, so hosting the React surface here
|
|
15005
|
+
// (one bundle) avoids duplicating it per provider.
|
|
15006
|
+
stableId: "motion-zones-editor",
|
|
15007
|
+
label: "Motion Zones",
|
|
15008
|
+
description: "On-camera motion-detection grid editor (live-frame overlay).",
|
|
15009
|
+
icon: "grid-3x3",
|
|
15010
|
+
remoteName: "addon_pipeline_orchestrator_widgets",
|
|
15011
|
+
bundle: "remoteEntry.js",
|
|
15012
|
+
hosts: ["device-tab"],
|
|
15013
|
+
requires: { deviceContext: true, integrationContext: false },
|
|
15014
|
+
defaultSize: "lg",
|
|
15015
|
+
allowedSizes: ["md", "lg"],
|
|
15016
|
+
defaultColumns: 12,
|
|
15017
|
+
defaultRows: 1
|
|
14783
15018
|
}
|
|
14784
15019
|
]
|
|
14785
15020
|
};
|
|
@@ -16951,8 +17186,28 @@ class PipelineOrchestratorAddon extends BaseAddon {
|
|
|
16951
17186
|
}
|
|
16952
17187
|
]
|
|
16953
17188
|
};
|
|
17189
|
+
const motionZonesSection = {
|
|
17190
|
+
id: "motion-zones",
|
|
17191
|
+
title: "Motion Zones",
|
|
17192
|
+
tab: "motion",
|
|
17193
|
+
location: "settings",
|
|
17194
|
+
columns: 1,
|
|
17195
|
+
order: 0,
|
|
17196
|
+
fields: [
|
|
17197
|
+
{
|
|
17198
|
+
// Widget fields manage their own state via DeviceProxy —
|
|
17199
|
+
// `ConfigWidgetField` carries no `value` (unlike the legacy
|
|
17200
|
+
// `zone-editor` field type which still does).
|
|
17201
|
+
type: "widget",
|
|
17202
|
+
key: "motion-zones",
|
|
17203
|
+
label: "Motion Zones",
|
|
17204
|
+
widgetId: "pipeline-orchestrator/motion-zones-editor",
|
|
17205
|
+
span: 1
|
|
17206
|
+
}
|
|
17207
|
+
]
|
|
17208
|
+
};
|
|
16954
17209
|
return {
|
|
16955
|
-
sections: [...baseSections, zonesSection]
|
|
17210
|
+
sections: [...baseSections, zonesSection, motionZonesSection]
|
|
16956
17211
|
};
|
|
16957
17212
|
}
|
|
16958
17213
|
// `getCameraPipelineWithFallback` was a thin wrapper over
|