camstack 1.2.214 → 1.2.215

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.
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ALL_CAPABILITY_DEFINITIONS,
4
+ ActionTargetSchema,
4
5
  AlarmArmModeSchema,
5
6
  AutomationRecipeSchema,
6
7
  DETECTOR_PERF,
@@ -18,7 +19,7 @@ import {
18
19
  prepareRecipeUnits,
19
20
  unitsForQuantity,
20
21
  validateRecipeBounds
21
- } from "./chunk-4Y3CBGOY.js";
22
+ } from "./chunk-WGHOCSCW.js";
22
23
  import {
23
24
  IMAGE_TAG_BY_ACCELERATOR,
24
25
  MUST_NOT_OMIT,
@@ -602,16 +603,29 @@ var ActionAnswerSchema = z4.discriminatedUnion("kind", [
602
603
  z4.object({ kind: z4.literal("wait"), seconds: z4.number().min(0).max(300) }),
603
604
  z4.object({
604
605
  kind: z4.literal("cap"),
605
- deviceId: z4.union([
606
- z4.number().int().nonnegative(),
607
- z4.array(z4.number().int().nonnegative()).min(1)
608
- ]),
606
+ /** WHO the step acts on: named devices, or every device offering `actionId` (optionally in a room / of a type). */
607
+ target: ActionTargetSchema.optional(),
608
+ /** The vocabulary action (`cover.open`); required for a `domain` target. */
609
+ actionId: z4.string().min(1).optional(),
610
+ /** Shorthand for `target: { kind: 'devices', ids }`. */
611
+ deviceId: z4.union([z4.number().int().nonnegative(), z4.array(z4.number().int().nonnegative()).min(1)]).optional(),
609
612
  cap: z4.string().min(1),
610
613
  method: z4.string().min(1),
611
614
  /** A quantity argument is `{ value, unit }`; a bare number is stamped with the declared unit. */
612
615
  args: z4.record(z4.string(), z4.unknown()).optional()
616
+ }).refine((a) => a.target !== void 0 || a.deviceId !== void 0, {
617
+ message: "a cap step needs a target (or a deviceId)",
618
+ path: ["target"]
619
+ }).refine((a) => a.target?.kind !== "domain" || a.actionId !== void 0, {
620
+ message: "a domain target needs the vocabulary action it applies to (actionId)",
621
+ path: ["actionId"]
613
622
  })
614
623
  ]);
624
+ function targetOfAnswer(a) {
625
+ if (a.target !== void 0) return a.target;
626
+ const ids = Array.isArray(a.deviceId) ? [...a.deviceId] : a.deviceId === void 0 ? [] : [a.deviceId];
627
+ return { kind: "devices", ids };
628
+ }
615
629
  var AutomationTriggerAnswerSchema = z4.object({
616
630
  kind: z4.enum(["detection", "device-state", "schedule"]),
617
631
  // detection
@@ -661,7 +675,7 @@ var CONDITIONS_QUESTION = {
661
675
  };
662
676
  var ACTIONS_QUESTION = {
663
677
  field: "actions",
664
- ask: 'What should it do? A list of steps, in order: { kind: "cap", deviceId, cap, method, args? } or { kind: "wait", seconds }. deviceId may be a list to run the same call on several devices.'
678
+ ask: 'What should it do? A list of steps, in order: { kind: "cap", target, actionId?, cap, method, args? } or { kind: "wait", seconds }. target is { kind: "devices", ids: [...] } to name devices, or { kind: "domain", roomId?, deviceType? } with the vocabulary actionId (for example "cover.open") to act on every device that offers it \u2014 resolved when the step runs, so a device added later is included. deviceId (a number or a list) is still accepted as shorthand for named devices.'
665
679
  };
666
680
  function fieldChoices(fields) {
667
681
  return fields.map((f) => {
@@ -949,7 +963,8 @@ async function checkActions(client, actions) {
949
963
  const cache = /* @__PURE__ */ new Map();
950
964
  for (const [idx, action] of actions.entries()) {
951
965
  if (action.kind !== "cap") continue;
952
- const ids = Array.isArray(action.deviceId) ? action.deviceId : [action.deviceId];
966
+ const target = targetOfAnswer(action);
967
+ const ids = target.kind === "devices" ? target.ids : [];
953
968
  for (const id of ids) {
954
969
  let caps = cache.get(id);
955
970
  if (caps === void 0) {
@@ -987,7 +1002,8 @@ function toActions(actions) {
987
1002
  if (a.kind === "wait") return { kind: "wait", seconds: a.seconds };
988
1003
  return {
989
1004
  kind: "cap",
990
- deviceId: Array.isArray(a.deviceId) ? [...a.deviceId] : a.deviceId,
1005
+ target: targetOfAnswer(a),
1006
+ ...a.actionId !== void 0 ? { actionId: a.actionId } : {},
991
1007
  cap: a.cap,
992
1008
  method: a.method,
993
1009
  ...a.args !== void 0 ? { args: a.args } : {}
@@ -1031,9 +1047,10 @@ function summarize(trigger, conditions, actions, cooldown) {
1031
1047
  for (const a of actions) {
1032
1048
  if (a.kind === "wait") lines.push(` then wait ${a.seconds}s`);
1033
1049
  else {
1034
- const ids = Array.isArray(a.deviceId) ? a.deviceId.join(", ") : String(a.deviceId);
1050
+ const t = targetOfAnswer(a);
1051
+ const who = t.kind === "devices" ? `device ${t.ids.join(", ")}` : t.kind === "var" ? `device $${t.name}` : `every device that can ${a.actionId ?? a.method}${t.roomId === void 0 ? "" : ` in ${t.roomId}`}${t.deviceType === void 0 ? "" : ` of type ${t.deviceType}`}`;
1035
1052
  lines.push(
1036
- ` then ${a.cap}.${a.method} on device ${ids}${a.args ? ` with ${JSON.stringify(a.args)}` : ""}`
1053
+ ` then ${a.cap}.${a.method} on ${who}${a.args ? ` with ${JSON.stringify(a.args)}` : ""}`
1037
1054
  );
1038
1055
  }
1039
1056
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camstack",
3
- "version": "1.2.214",
3
+ "version": "1.2.215",
4
4
  "description": "CLI tool for managing and running CamStack server",
5
5
  "keywords": [
6
6
  "camstack",