@camstack/addon-provider-homeassistant 1.2.155 → 1.2.157

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.
@@ -5378,7 +5378,7 @@ var ZodIssueCode = {
5378
5378
  var ZodFirstPartyTypeKind;
5379
5379
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5380
5380
  //#endregion
5381
- //#region ../types/dist/sleep-CDCONfkt.mjs
5381
+ //#region ../types/dist/sleep-DXKLNFvA.mjs
5382
5382
  /**
5383
5383
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5384
5384
  * window to float samples (D455).
@@ -5686,6 +5686,43 @@ function hydrateField(field, values) {
5686
5686
  }
5687
5687
  const rawValue = storedValue !== void 0 ? storedValue : defaultValue !== void 0 ? defaultValue : null;
5688
5688
  const value = field.type === "textarea" && field.isJson && rawValue !== null && typeof rawValue === "object" ? JSON.stringify(rawValue, null, 2) : rawValue;
5689
+ if (field.type === "tags" && typeof field.suggestionsFrom === "string") {
5690
+ const from = values[field.suggestionsFrom];
5691
+ const extra = Array.isArray(from) ? from.filter((s) => typeof s === "string" && s.length > 0) : [];
5692
+ const merged = [...new Set([...field.suggestions ?? [], ...extra])];
5693
+ return {
5694
+ ...field,
5695
+ suggestions: merged,
5696
+ value
5697
+ };
5698
+ }
5699
+ if ((field.type === "select" || field.type === "multiselect") && typeof field.optionsFrom === "string") {
5700
+ const from = values[field.optionsFrom];
5701
+ const byValue = /* @__PURE__ */ new Map();
5702
+ for (const opt of field.options) byValue.set(opt.value, opt);
5703
+ if (Array.isArray(from)) for (const entry of from) {
5704
+ if (typeof entry === "string" && entry.length > 0) {
5705
+ if (!byValue.has(entry)) byValue.set(entry, {
5706
+ value: entry,
5707
+ label: entry
5708
+ });
5709
+ continue;
5710
+ }
5711
+ if (entry === null || typeof entry !== "object") continue;
5712
+ const v = Reflect.get(entry, "value");
5713
+ const lbl = Reflect.get(entry, "label");
5714
+ if (typeof v !== "string" || v.length === 0) continue;
5715
+ if (!byValue.has(v)) byValue.set(v, {
5716
+ value: v,
5717
+ label: typeof lbl === "string" && lbl.length > 0 ? lbl : v
5718
+ });
5719
+ }
5720
+ return {
5721
+ ...field,
5722
+ options: [...byValue.values()],
5723
+ value
5724
+ };
5725
+ }
5689
5726
  return {
5690
5727
  ...field,
5691
5728
  value
@@ -11095,7 +11132,16 @@ var AutomationActionSchema = discriminatedUnion("kind", [
11095
11132
  }),
11096
11133
  object({
11097
11134
  kind: literal("cap"),
11098
- deviceId: union([number().int(), object({ $var: string().min(1) })]),
11135
+ /**
11136
+ * One device, several same-family devices (locks / climate family / …),
11137
+ * or `{ $var }` for the device that triggered the run. An array is
11138
+ * fan-out at codegen — each id gets the same cap.method call.
11139
+ */
11140
+ deviceId: union([
11141
+ number().int(),
11142
+ array(number().int()).min(1),
11143
+ object({ $var: string().min(1) })
11144
+ ]),
11099
11145
  cap: string().min(1),
11100
11146
  method: string().min(1),
11101
11147
  /** Values may carry `{{vars.x}}` slots, which SUBSTITUTE and do not
@@ -14418,7 +14464,7 @@ DeviceType.Camera;
14418
14464
  * This matters here more than anywhere else in the repo, because every provider
14419
14465
  * that knows a device's host knows its PASSWORD too: `{ host, port, username,
14420
14466
  * password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
14421
- * and `http://admin:hunter2@192.168.50.139/` is a URL a browser accepts. The
14467
+ * and `http://admin:hunter2@192.168.x.x/` is a URL a browser accepts. The
14422
14468
  * camera's own page will ask for its own login. That is correct, and pre-
14423
14469
  * filling it is the operator's business, not ours.
14424
14470
  *
@@ -18328,6 +18374,17 @@ var SendResultSchema = object({
18328
18374
  });
18329
18375
  /** Same shape as SendResult — kept as a distinct name for the test panel. */
18330
18376
  var TestResultSchema = SendResultSchema;
18377
+ /**
18378
+ * Pre-save credential probe against a partial (unsaved) target config.
18379
+ * `resolvedUrl` never includes secrets (token stripped from path).
18380
+ */
18381
+ var ProbeTargetConfigResultSchema = object({
18382
+ ok: boolean(),
18383
+ resolvedUrl: string(),
18384
+ httpStatus: number().int().optional(),
18385
+ stateInstance: string().optional(),
18386
+ error: string().optional()
18387
+ });
18331
18388
  var notificationOutputCapability = {
18332
18389
  name: "notification-output",
18333
18390
  scope: "system",
@@ -18335,10 +18392,32 @@ var notificationOutputCapability = {
18335
18392
  methods: {
18336
18393
  listTargetKinds: method(object({}), array(TargetKindSchema)),
18337
18394
  listTargets: method(object({}), array(TargetSchema), { auth: "admin" }),
18395
+ /**
18396
+ * One target WITH secrets — admin edit / duplicate hydration only.
18397
+ * `listTargets` stays redacted; the editor loads this so password fields
18398
+ * are filled (masked in the input) and a save can round-trip the token
18399
+ * when a destination changes (Duplicate with a new chatId, etc.).
18400
+ */
18401
+ getTarget: method(object({ targetId: string() }), TargetSchema, { auth: "admin" }),
18338
18402
  discoverTargets: method(object({
18339
18403
  kind: string(),
18340
- config: record(string(), unknown()).optional()
18404
+ config: record(string(), unknown()).optional(),
18405
+ /**
18406
+ * When editing / duplicating, the blank password field never round-trips
18407
+ * the stored token. Pass the source target id so the provider can restore
18408
+ * secrets server-side before dialling (same merge as upsert).
18409
+ */
18410
+ targetId: string().optional()
18341
18411
  }), array(DiscoveredTargetSchema), { auth: "admin" }),
18412
+ probeTargetConfig: method(object({
18413
+ kind: string(),
18414
+ config: record(string(), unknown()),
18415
+ /** See `discoverTargets.targetId` — restore stored secrets for a blank password. */
18416
+ targetId: string().optional()
18417
+ }), ProbeTargetConfigResultSchema, {
18418
+ kind: "mutation",
18419
+ auth: "admin"
18420
+ }),
18342
18421
  send: method(object({
18343
18422
  targetId: string(),
18344
18423
  notification: NotificationSchema
@@ -18353,7 +18432,16 @@ var notificationOutputCapability = {
18353
18432
  kind: "mutation",
18354
18433
  auth: "admin"
18355
18434
  }),
18356
- upsertTarget: method(object({ target: TargetSchema }), TargetSchema, {
18435
+ upsertTarget: method(object({
18436
+ target: TargetSchema,
18437
+ /**
18438
+ * Duplicate flow: create a NEW target id while copying secrets from an
18439
+ * existing row. The UI never holds the stored token; blank / redacted
18440
+ * password fields are restored from this source (D634 still applies if
18441
+ * destinations diverge without a re-typed secret).
18442
+ */
18443
+ cloneSecretsFrom: string().optional()
18444
+ }), TargetSchema, {
18357
18445
  kind: "mutation",
18358
18446
  auth: "admin"
18359
18447
  }),
@@ -20776,17 +20864,41 @@ var NC_ALARM_TRIGGERED_MAX_SEC = 3600;
20776
20864
  var NcAlarmDelaySecSchema = number().int().min(0).max(600);
20777
20865
  var NcAlarmTriggeredSecSchema = number().int().min(0).max(NC_ALARM_TRIGGERED_MAX_SEC);
20778
20866
  var uniqueModes = (entries) => new Set(entries.map((e) => e.mode)).size === entries.length;
20867
+ /**
20868
+ * What the panel does when a bounded triggered window ends.
20869
+ * - `rearmAfter` — return to the armed mode
20870
+ * - `disableAfter` — auto-disarm
20871
+ * - `doNothing` — stay triggered until a human disarms
20872
+ */
20873
+ var NcAlarmPostTriggeredActionSchema = _enum([
20874
+ "rearmAfter",
20875
+ "disableAfter",
20876
+ "doNothing"
20877
+ ]);
20779
20878
  var NcAlarmModeDelaysListSchema = array(object({
20780
20879
  mode: AlarmArmModeSchema,
20781
20880
  exitDelaySec: NcAlarmDelaySecSchema.optional(),
20782
20881
  entryDelaySec: NcAlarmDelaySecSchema.optional(),
20783
- triggeredDurationSec: NcAlarmTriggeredSecSchema.optional()
20882
+ /**
20883
+ * Duration of `triggered` before {@link postTriggeredAction}. Kept as the
20884
+ * historical field name so older clients still read/write a number.
20885
+ */
20886
+ triggeredDurationSec: NcAlarmTriggeredSecSchema.optional(),
20887
+ postTriggeredAction: NcAlarmPostTriggeredActionSchema.optional(),
20888
+ /**
20889
+ * When this mode may be armed. Absent / null = always allowed (same as a
20890
+ * rule with no `schedule`). Evaluated with {@link isScheduleActive}.
20891
+ */
20892
+ schedule: NcScheduleSchema.optional()
20784
20893
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20785
20894
  var NcAlarmModeDelaysEditListSchema = array(object({
20786
20895
  mode: AlarmArmModeSchema,
20787
20896
  exitDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
20788
20897
  entryDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
20789
- triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional()
20898
+ triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
20899
+ postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
20900
+ /** Set a schedule, or `null` to clear (mode always allowed again). */
20901
+ schedule: NcScheduleSchema.nullable().optional()
20790
20902
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20791
20903
  /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20792
20904
  var NcAlarmNonBlockingEditSchema = object({
@@ -20858,12 +20970,18 @@ var NcAlarmSettingsSchema = object({
20858
20970
  /** Grace period between a trigger and the alarm firing. 0 = immediate. */
20859
20971
  entryDelaySec: NcAlarmDelaySecSchema,
20860
20972
  /**
20861
- * How long `triggered` lasts before the panel re-arms itself.
20862
- * **0 = until an operator disarms it** — the behaviour before this field
20863
- * existed, and therefore what an untouched install keeps doing.
20973
+ * How long `triggered` lasts before {@link postTriggeredAction} runs.
20974
+ * Ignored when the action is `doNothing`. Historical name kept so older
20975
+ * clients still round-trip a number.
20864
20976
  */
20865
20977
  triggeredDurationSec: NcAlarmTriggeredSecSchema,
20866
20978
  /**
20979
+ * What happens when the triggered window ends. Absent on a blob older than
20980
+ * this field → derived from {@link triggeredDurationSec} (`>0` ⇒ rearmAfter,
20981
+ * else doNothing).
20982
+ */
20983
+ postTriggeredAction: NcAlarmPostTriggeredActionSchema.optional(),
20984
+ /**
20867
20985
  * Deprecated by D630 — every transition is announced. Parsed, never read;
20868
20986
  * remove after one release. Optional so an older admin's patch (which still
20869
20987
  * sends it) parses rather than failing the whole save.
@@ -32414,7 +32532,7 @@ var LocalInterfaceSchema = object({
32414
32532
  name: string(),
32415
32533
  family: _enum(["IPv4", "IPv6"]),
32416
32534
  address: string(),
32417
- /** CIDR shorthand (e.g. `192.168.1.10/24`). Empty when OS doesn't expose. */
32535
+ /** CIDR shorthand (e.g. `192.168.x.x/24`). Empty when OS doesn't expose. */
32418
32536
  cidr: string(),
32419
32537
  /** OS netmask. Stable across calls so the SDK can hash on it. */
32420
32538
  netmask: string(),
@@ -32928,7 +33046,7 @@ var MeshPeerSchema = object({
32928
33046
  tags: array(string()).readonly(),
32929
33047
  /** True when the peer advertises itself as an exit-node candidate. */
32930
33048
  exitNodeOption: boolean(),
32931
- /** Subnet routes the peer advertises (e.g. `["192.168.1.0/24"]`). */
33049
+ /** Subnet routes the peer advertises (e.g. `["192.168.x.x/24"]`). */
32932
33050
  advertisedRoutes: array(string()).readonly(),
32933
33051
  /** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
32934
33052
  userLogin: string().nullable(),
@@ -44766,6 +44884,12 @@ Object.freeze({
44766
44884
  addonId: null,
44767
44885
  access: "view"
44768
44886
  },
44887
+ "notificationOutput.getTarget": {
44888
+ capName: "notification-output",
44889
+ capScope: "system",
44890
+ addonId: null,
44891
+ access: "view"
44892
+ },
44769
44893
  "notificationOutput.listTargetKinds": {
44770
44894
  capName: "notification-output",
44771
44895
  capScope: "system",
@@ -44778,6 +44902,12 @@ Object.freeze({
44778
44902
  addonId: null,
44779
44903
  access: "view"
44780
44904
  },
44905
+ "notificationOutput.probeTargetConfig": {
44906
+ capName: "notification-output",
44907
+ capScope: "system",
44908
+ addonId: null,
44909
+ access: "create"
44910
+ },
44781
44911
  "notificationOutput.send": {
44782
44912
  capName: "notification-output",
44783
44913
  capScope: "system",
@@ -48487,6 +48617,7 @@ Object.freeze({
48487
48617
  access: "create"
48488
48618
  }
48489
48619
  });
48620
+ DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder;
48490
48621
  DeviceFeature.BatteryOperated;
48491
48622
  /**
48492
48623
  * The vocabulary, in the order a picker offers it.
@@ -53673,4 +53804,4 @@ function bestLocationMatch(externalName, existing, threshold = .8) {
53673
53804
  var MB = 1024 * 1024;
53674
53805
  1024 * MB, 3072 * MB;
53675
53806
  //#endregion
53676
- export { oauthIntegrationCapability as $, connectivityCapability as A, string as At, floodCapability as B, buildAddonRouteProvider as C, _enum as Ct, carbonMonoxideCapability as D, number as Dt, calendarSourceCapability as E, literal as Et, deviceAdoptionCapability as F, lawnMowerControlCapability as G, humidifierCapability as H, deviceExportCapability as I, motionCapability as J, lockControlCapability as K, enumSensorCapability as L, controlCapability as M, unknown as Mt, coverCapability as N, url as Nt, climateControlCapability as O, object as Ot, deviceAdminLinkCapability as P, EventCategory as Pt, numericSensorCapability as Q, eventEmitterCapability as R, brokerCapability as S, nodePin as St, buttonCapability as T, discriminatedUnion as Tt, humiditySensorCapability as U, gasCapability as V, imageCapability as W, notificationOutputCapability as X, normalizeUnit as Y, notifierCapability as Z, automationControlCapability as _, DeviceRole as _t, COCO_TO_MACRO as a, scriptRunnerCapability as at, binaryCapability as b, BaseAddon as bt, FanDirectionSchema as c, tamperCapability as ct, TargetSchema as d, vacuumControlCapability as dt, parseAdminBase as et, accessoriesCapability as f, valveCapability as ft, ambientLightSensorCapability as g, DeviceFeature as gt, alarmPanelCapability as h, weatherCapability as ht, CAMERA_SWITCH_ORDER as i, pressureSensorCapability as it, contactCapability as j, union as jt, colorCapability as k, record as kt, HvacModeSchema as l, temperatureSensorCapability as lt, airQualitySensorCapability as m, waterHeaterCapability as mt, BaseDevice as n, prepareNotification as nt, CameraSwitchIdSchema as o, smokeCapability as ot, addonRoutesCapability as p, vibrationCapability as pt, mediaPlayerCapability as q, BaseDeviceProvider as r, presenceCapability as rt, EnumSensorDateTimeFormatSchema as s, switchCapability as st, AlarmArmModeSchema as t, powerMeterCapability as tt, MediaPlayerRepeatSchema as u, updateCapability as ut, batteryCapability as v, DeviceType as vt, buildDeviceAdminUrl as w, array as wt, brightnessCapability as x, createEvent as xt, bestLocationMatch as y, errMsg as yt, fanControlCapability as z };
53807
+ export { oauthIntegrationCapability as $, connectivityCapability as A, record as At, floodCapability as B, buildAddonRouteProvider as C, _enum as Ct, carbonMonoxideCapability as D, literal as Dt, calendarSourceCapability as E, discriminatedUnion as Et, deviceAdoptionCapability as F, EventCategory as Ft, lawnMowerControlCapability as G, humidifierCapability as H, deviceExportCapability as I, motionCapability as J, lockControlCapability as K, enumSensorCapability as L, controlCapability as M, union as Mt, coverCapability as N, unknown as Nt, climateControlCapability as O, number as Ot, deviceAdminLinkCapability as P, url as Pt, numericSensorCapability as Q, eventEmitterCapability as R, brokerCapability as S, nodePin as St, buttonCapability as T, boolean as Tt, humiditySensorCapability as U, gasCapability as V, imageCapability as W, notificationOutputCapability as X, normalizeUnit as Y, notifierCapability as Z, automationControlCapability as _, DeviceRole as _t, COCO_TO_MACRO as a, scriptRunnerCapability as at, binaryCapability as b, BaseAddon as bt, FanDirectionSchema as c, tamperCapability as ct, TargetSchema as d, vacuumControlCapability as dt, parseAdminBase as et, accessoriesCapability as f, valveCapability as ft, ambientLightSensorCapability as g, DeviceFeature as gt, alarmPanelCapability as h, weatherCapability as ht, CAMERA_SWITCH_ORDER as i, pressureSensorCapability as it, contactCapability as j, string as jt, colorCapability as k, object as kt, HvacModeSchema as l, temperatureSensorCapability as lt, airQualitySensorCapability as m, waterHeaterCapability as mt, BaseDevice as n, prepareNotification as nt, CameraSwitchIdSchema as o, smokeCapability as ot, addonRoutesCapability as p, vibrationCapability as pt, mediaPlayerCapability as q, BaseDeviceProvider as r, presenceCapability as rt, EnumSensorDateTimeFormatSchema as s, switchCapability as st, AlarmArmModeSchema as t, powerMeterCapability as tt, MediaPlayerRepeatSchema as u, updateCapability as ut, batteryCapability as v, DeviceType as vt, buildDeviceAdminUrl as w, array as wt, brightnessCapability as x, createEvent as xt, bestLocationMatch as y, errMsg as yt, fanControlCapability as z };
@@ -5379,7 +5379,7 @@ var ZodIssueCode = {
5379
5379
  var ZodFirstPartyTypeKind;
5380
5380
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5381
5381
  //#endregion
5382
- //#region ../types/dist/sleep-CDCONfkt.mjs
5382
+ //#region ../types/dist/sleep-DXKLNFvA.mjs
5383
5383
  /**
5384
5384
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5385
5385
  * window to float samples (D455).
@@ -5687,6 +5687,43 @@ function hydrateField(field, values) {
5687
5687
  }
5688
5688
  const rawValue = storedValue !== void 0 ? storedValue : defaultValue !== void 0 ? defaultValue : null;
5689
5689
  const value = field.type === "textarea" && field.isJson && rawValue !== null && typeof rawValue === "object" ? JSON.stringify(rawValue, null, 2) : rawValue;
5690
+ if (field.type === "tags" && typeof field.suggestionsFrom === "string") {
5691
+ const from = values[field.suggestionsFrom];
5692
+ const extra = Array.isArray(from) ? from.filter((s) => typeof s === "string" && s.length > 0) : [];
5693
+ const merged = [...new Set([...field.suggestions ?? [], ...extra])];
5694
+ return {
5695
+ ...field,
5696
+ suggestions: merged,
5697
+ value
5698
+ };
5699
+ }
5700
+ if ((field.type === "select" || field.type === "multiselect") && typeof field.optionsFrom === "string") {
5701
+ const from = values[field.optionsFrom];
5702
+ const byValue = /* @__PURE__ */ new Map();
5703
+ for (const opt of field.options) byValue.set(opt.value, opt);
5704
+ if (Array.isArray(from)) for (const entry of from) {
5705
+ if (typeof entry === "string" && entry.length > 0) {
5706
+ if (!byValue.has(entry)) byValue.set(entry, {
5707
+ value: entry,
5708
+ label: entry
5709
+ });
5710
+ continue;
5711
+ }
5712
+ if (entry === null || typeof entry !== "object") continue;
5713
+ const v = Reflect.get(entry, "value");
5714
+ const lbl = Reflect.get(entry, "label");
5715
+ if (typeof v !== "string" || v.length === 0) continue;
5716
+ if (!byValue.has(v)) byValue.set(v, {
5717
+ value: v,
5718
+ label: typeof lbl === "string" && lbl.length > 0 ? lbl : v
5719
+ });
5720
+ }
5721
+ return {
5722
+ ...field,
5723
+ options: [...byValue.values()],
5724
+ value
5725
+ };
5726
+ }
5690
5727
  return {
5691
5728
  ...field,
5692
5729
  value
@@ -11096,7 +11133,16 @@ var AutomationActionSchema = discriminatedUnion("kind", [
11096
11133
  }),
11097
11134
  object({
11098
11135
  kind: literal("cap"),
11099
- deviceId: union([number().int(), object({ $var: string().min(1) })]),
11136
+ /**
11137
+ * One device, several same-family devices (locks / climate family / …),
11138
+ * or `{ $var }` for the device that triggered the run. An array is
11139
+ * fan-out at codegen — each id gets the same cap.method call.
11140
+ */
11141
+ deviceId: union([
11142
+ number().int(),
11143
+ array(number().int()).min(1),
11144
+ object({ $var: string().min(1) })
11145
+ ]),
11100
11146
  cap: string().min(1),
11101
11147
  method: string().min(1),
11102
11148
  /** Values may carry `{{vars.x}}` slots, which SUBSTITUTE and do not
@@ -14419,7 +14465,7 @@ DeviceType.Camera;
14419
14465
  * This matters here more than anywhere else in the repo, because every provider
14420
14466
  * that knows a device's host knows its PASSWORD too: `{ host, port, username,
14421
14467
  * password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
14422
- * and `http://admin:hunter2@192.168.50.139/` is a URL a browser accepts. The
14468
+ * and `http://admin:hunter2@192.168.x.x/` is a URL a browser accepts. The
14423
14469
  * camera's own page will ask for its own login. That is correct, and pre-
14424
14470
  * filling it is the operator's business, not ours.
14425
14471
  *
@@ -18329,6 +18375,17 @@ var SendResultSchema = object({
18329
18375
  });
18330
18376
  /** Same shape as SendResult — kept as a distinct name for the test panel. */
18331
18377
  var TestResultSchema = SendResultSchema;
18378
+ /**
18379
+ * Pre-save credential probe against a partial (unsaved) target config.
18380
+ * `resolvedUrl` never includes secrets (token stripped from path).
18381
+ */
18382
+ var ProbeTargetConfigResultSchema = object({
18383
+ ok: boolean(),
18384
+ resolvedUrl: string(),
18385
+ httpStatus: number().int().optional(),
18386
+ stateInstance: string().optional(),
18387
+ error: string().optional()
18388
+ });
18332
18389
  var notificationOutputCapability = {
18333
18390
  name: "notification-output",
18334
18391
  scope: "system",
@@ -18336,10 +18393,32 @@ var notificationOutputCapability = {
18336
18393
  methods: {
18337
18394
  listTargetKinds: method(object({}), array(TargetKindSchema)),
18338
18395
  listTargets: method(object({}), array(TargetSchema), { auth: "admin" }),
18396
+ /**
18397
+ * One target WITH secrets — admin edit / duplicate hydration only.
18398
+ * `listTargets` stays redacted; the editor loads this so password fields
18399
+ * are filled (masked in the input) and a save can round-trip the token
18400
+ * when a destination changes (Duplicate with a new chatId, etc.).
18401
+ */
18402
+ getTarget: method(object({ targetId: string() }), TargetSchema, { auth: "admin" }),
18339
18403
  discoverTargets: method(object({
18340
18404
  kind: string(),
18341
- config: record(string(), unknown()).optional()
18405
+ config: record(string(), unknown()).optional(),
18406
+ /**
18407
+ * When editing / duplicating, the blank password field never round-trips
18408
+ * the stored token. Pass the source target id so the provider can restore
18409
+ * secrets server-side before dialling (same merge as upsert).
18410
+ */
18411
+ targetId: string().optional()
18342
18412
  }), array(DiscoveredTargetSchema), { auth: "admin" }),
18413
+ probeTargetConfig: method(object({
18414
+ kind: string(),
18415
+ config: record(string(), unknown()),
18416
+ /** See `discoverTargets.targetId` — restore stored secrets for a blank password. */
18417
+ targetId: string().optional()
18418
+ }), ProbeTargetConfigResultSchema, {
18419
+ kind: "mutation",
18420
+ auth: "admin"
18421
+ }),
18343
18422
  send: method(object({
18344
18423
  targetId: string(),
18345
18424
  notification: NotificationSchema
@@ -18354,7 +18433,16 @@ var notificationOutputCapability = {
18354
18433
  kind: "mutation",
18355
18434
  auth: "admin"
18356
18435
  }),
18357
- upsertTarget: method(object({ target: TargetSchema }), TargetSchema, {
18436
+ upsertTarget: method(object({
18437
+ target: TargetSchema,
18438
+ /**
18439
+ * Duplicate flow: create a NEW target id while copying secrets from an
18440
+ * existing row. The UI never holds the stored token; blank / redacted
18441
+ * password fields are restored from this source (D634 still applies if
18442
+ * destinations diverge without a re-typed secret).
18443
+ */
18444
+ cloneSecretsFrom: string().optional()
18445
+ }), TargetSchema, {
18358
18446
  kind: "mutation",
18359
18447
  auth: "admin"
18360
18448
  }),
@@ -20777,17 +20865,41 @@ var NC_ALARM_TRIGGERED_MAX_SEC = 3600;
20777
20865
  var NcAlarmDelaySecSchema = number().int().min(0).max(600);
20778
20866
  var NcAlarmTriggeredSecSchema = number().int().min(0).max(NC_ALARM_TRIGGERED_MAX_SEC);
20779
20867
  var uniqueModes = (entries) => new Set(entries.map((e) => e.mode)).size === entries.length;
20868
+ /**
20869
+ * What the panel does when a bounded triggered window ends.
20870
+ * - `rearmAfter` — return to the armed mode
20871
+ * - `disableAfter` — auto-disarm
20872
+ * - `doNothing` — stay triggered until a human disarms
20873
+ */
20874
+ var NcAlarmPostTriggeredActionSchema = _enum([
20875
+ "rearmAfter",
20876
+ "disableAfter",
20877
+ "doNothing"
20878
+ ]);
20780
20879
  var NcAlarmModeDelaysListSchema = array(object({
20781
20880
  mode: AlarmArmModeSchema,
20782
20881
  exitDelaySec: NcAlarmDelaySecSchema.optional(),
20783
20882
  entryDelaySec: NcAlarmDelaySecSchema.optional(),
20784
- triggeredDurationSec: NcAlarmTriggeredSecSchema.optional()
20883
+ /**
20884
+ * Duration of `triggered` before {@link postTriggeredAction}. Kept as the
20885
+ * historical field name so older clients still read/write a number.
20886
+ */
20887
+ triggeredDurationSec: NcAlarmTriggeredSecSchema.optional(),
20888
+ postTriggeredAction: NcAlarmPostTriggeredActionSchema.optional(),
20889
+ /**
20890
+ * When this mode may be armed. Absent / null = always allowed (same as a
20891
+ * rule with no `schedule`). Evaluated with {@link isScheduleActive}.
20892
+ */
20893
+ schedule: NcScheduleSchema.optional()
20785
20894
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20786
20895
  var NcAlarmModeDelaysEditListSchema = array(object({
20787
20896
  mode: AlarmArmModeSchema,
20788
20897
  exitDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
20789
20898
  entryDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
20790
- triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional()
20899
+ triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
20900
+ postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
20901
+ /** Set a schedule, or `null` to clear (mode always allowed again). */
20902
+ schedule: NcScheduleSchema.nullable().optional()
20791
20903
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20792
20904
  /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20793
20905
  var NcAlarmNonBlockingEditSchema = object({
@@ -20859,12 +20971,18 @@ var NcAlarmSettingsSchema = object({
20859
20971
  /** Grace period between a trigger and the alarm firing. 0 = immediate. */
20860
20972
  entryDelaySec: NcAlarmDelaySecSchema,
20861
20973
  /**
20862
- * How long `triggered` lasts before the panel re-arms itself.
20863
- * **0 = until an operator disarms it** — the behaviour before this field
20864
- * existed, and therefore what an untouched install keeps doing.
20974
+ * How long `triggered` lasts before {@link postTriggeredAction} runs.
20975
+ * Ignored when the action is `doNothing`. Historical name kept so older
20976
+ * clients still round-trip a number.
20865
20977
  */
20866
20978
  triggeredDurationSec: NcAlarmTriggeredSecSchema,
20867
20979
  /**
20980
+ * What happens when the triggered window ends. Absent on a blob older than
20981
+ * this field → derived from {@link triggeredDurationSec} (`>0` ⇒ rearmAfter,
20982
+ * else doNothing).
20983
+ */
20984
+ postTriggeredAction: NcAlarmPostTriggeredActionSchema.optional(),
20985
+ /**
20868
20986
  * Deprecated by D630 — every transition is announced. Parsed, never read;
20869
20987
  * remove after one release. Optional so an older admin's patch (which still
20870
20988
  * sends it) parses rather than failing the whole save.
@@ -32415,7 +32533,7 @@ var LocalInterfaceSchema = object({
32415
32533
  name: string(),
32416
32534
  family: _enum(["IPv4", "IPv6"]),
32417
32535
  address: string(),
32418
- /** CIDR shorthand (e.g. `192.168.1.10/24`). Empty when OS doesn't expose. */
32536
+ /** CIDR shorthand (e.g. `192.168.x.x/24`). Empty when OS doesn't expose. */
32419
32537
  cidr: string(),
32420
32538
  /** OS netmask. Stable across calls so the SDK can hash on it. */
32421
32539
  netmask: string(),
@@ -32929,7 +33047,7 @@ var MeshPeerSchema = object({
32929
33047
  tags: array(string()).readonly(),
32930
33048
  /** True when the peer advertises itself as an exit-node candidate. */
32931
33049
  exitNodeOption: boolean(),
32932
- /** Subnet routes the peer advertises (e.g. `["192.168.1.0/24"]`). */
33050
+ /** Subnet routes the peer advertises (e.g. `["192.168.x.x/24"]`). */
32933
33051
  advertisedRoutes: array(string()).readonly(),
32934
33052
  /** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
32935
33053
  userLogin: string().nullable(),
@@ -44767,6 +44885,12 @@ Object.freeze({
44767
44885
  addonId: null,
44768
44886
  access: "view"
44769
44887
  },
44888
+ "notificationOutput.getTarget": {
44889
+ capName: "notification-output",
44890
+ capScope: "system",
44891
+ addonId: null,
44892
+ access: "view"
44893
+ },
44770
44894
  "notificationOutput.listTargetKinds": {
44771
44895
  capName: "notification-output",
44772
44896
  capScope: "system",
@@ -44779,6 +44903,12 @@ Object.freeze({
44779
44903
  addonId: null,
44780
44904
  access: "view"
44781
44905
  },
44906
+ "notificationOutput.probeTargetConfig": {
44907
+ capName: "notification-output",
44908
+ capScope: "system",
44909
+ addonId: null,
44910
+ access: "create"
44911
+ },
44782
44912
  "notificationOutput.send": {
44783
44913
  capName: "notification-output",
44784
44914
  capScope: "system",
@@ -48488,6 +48618,7 @@ Object.freeze({
48488
48618
  access: "create"
48489
48619
  }
48490
48620
  });
48621
+ DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder;
48491
48622
  DeviceFeature.BatteryOperated;
48492
48623
  /**
48493
48624
  * The vocabulary, in the order a picker offers it.
@@ -53836,6 +53967,12 @@ Object.defineProperty(exports, "binaryCapability", {
53836
53967
  return binaryCapability;
53837
53968
  }
53838
53969
  });
53970
+ Object.defineProperty(exports, "boolean", {
53971
+ enumerable: true,
53972
+ get: function() {
53973
+ return boolean;
53974
+ }
53975
+ });
53839
53976
  Object.defineProperty(exports, "brightnessCapability", {
53840
53977
  enumerable: true,
53841
53978
  get: function() {