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