@attraccess/plugin-wago 0.1.0-nightly.1004.1 → 0.1.0-nightly.1006.1

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/index.js CHANGED
@@ -48140,12 +48140,12 @@ var require_auditTime = __commonJS({
48140
48140
  var async_1 = require_async();
48141
48141
  var audit_1 = require_audit();
48142
48142
  var timer_1 = require_timer();
48143
- function auditTime(duration, scheduler) {
48143
+ function auditTime(duration2, scheduler) {
48144
48144
  if (scheduler === void 0) {
48145
48145
  scheduler = async_1.asyncScheduler;
48146
48146
  }
48147
48147
  return audit_1.audit(function() {
48148
- return timer_1.timer(duration, scheduler);
48148
+ return timer_1.timer(duration2, scheduler);
48149
48149
  });
48150
48150
  }
48151
48151
  exports2.auditTime = auditTime;
@@ -49118,9 +49118,9 @@ var require_delay = __commonJS({
49118
49118
  if (scheduler === void 0) {
49119
49119
  scheduler = async_1.asyncScheduler;
49120
49120
  }
49121
- var duration = timer_1.timer(due, scheduler);
49121
+ var duration2 = timer_1.timer(due, scheduler);
49122
49122
  return delayWhen_1.delayWhen(function() {
49123
- return duration;
49123
+ return duration2;
49124
49124
  });
49125
49125
  }
49126
49126
  exports2.delay = delay;
@@ -49546,13 +49546,13 @@ var require_groupBy = __commonJS({
49546
49546
  var Subject_1 = require_Subject();
49547
49547
  var lift_1 = require_lift();
49548
49548
  var OperatorSubscriber_1 = require_OperatorSubscriber();
49549
- function groupBy(keySelector, elementOrOptions, duration, connector) {
49549
+ function groupBy(keySelector, elementOrOptions, duration2, connector) {
49550
49550
  return lift_1.operate(function(source, subscriber) {
49551
49551
  var element;
49552
49552
  if (!elementOrOptions || typeof elementOrOptions === "function") {
49553
49553
  element = elementOrOptions;
49554
49554
  } else {
49555
- duration = elementOrOptions.duration, element = elementOrOptions.element, connector = elementOrOptions.connector;
49555
+ duration2 = elementOrOptions.duration, element = elementOrOptions.element, connector = elementOrOptions.connector;
49556
49556
  }
49557
49557
  var groups = /* @__PURE__ */ new Map();
49558
49558
  var notify = function(cb) {
@@ -49574,14 +49574,14 @@ var require_groupBy = __commonJS({
49574
49574
  groups.set(key_1, group_1 = connector ? connector() : new Subject_1.Subject());
49575
49575
  var grouped = createGroupedObservable(key_1, group_1);
49576
49576
  subscriber.next(grouped);
49577
- if (duration) {
49577
+ if (duration2) {
49578
49578
  var durationSubscriber_1 = OperatorSubscriber_1.createOperatorSubscriber(group_1, function() {
49579
49579
  group_1.complete();
49580
49580
  durationSubscriber_1 === null || durationSubscriber_1 === void 0 ? void 0 : durationSubscriber_1.unsubscribe();
49581
49581
  }, void 0, void 0, function() {
49582
49582
  return groups.delete(key_1);
49583
49583
  });
49584
- groupBySourceSubscriber.add(innerFrom_1.innerFrom(duration(grouped)).subscribe(durationSubscriber_1));
49584
+ groupBySourceSubscriber.add(innerFrom_1.innerFrom(duration2(grouped)).subscribe(durationSubscriber_1));
49585
49585
  }
49586
49586
  }
49587
49587
  group_1.next(element ? element(value) : value);
@@ -51102,11 +51102,11 @@ var require_throttleTime = __commonJS({
51102
51102
  var async_1 = require_async();
51103
51103
  var throttle_1 = require_throttle();
51104
51104
  var timer_1 = require_timer();
51105
- function throttleTime(duration, scheduler, config) {
51105
+ function throttleTime(duration2, scheduler, config) {
51106
51106
  if (scheduler === void 0) {
51107
51107
  scheduler = async_1.asyncScheduler;
51108
51108
  }
51109
- var duration$ = timer_1.timer(duration, scheduler);
51109
+ var duration$ = timer_1.timer(duration2, scheduler);
51110
51110
  return throttle_1.throttle(function() {
51111
51111
  return duration$;
51112
51112
  }, config);
@@ -52496,8 +52496,8 @@ function supportsOutputAction(channel, action) {
52496
52496
  }
52497
52497
  function pulseBehaviorError(capabilities, pulse) {
52498
52498
  if (!capabilities.includes("pulse") && pulse === void 0) return void 0;
52499
- const duration = pulse && typeof pulse === "object" && !Array.isArray(pulse) ? pulse.durationMs : void 0;
52500
- if (!capabilities.includes("output") || !capabilities.includes("pulse") || typeof duration !== "number" || !Number.isSafeInteger(duration) || duration <= 0)
52499
+ const duration2 = pulse && typeof pulse === "object" && !Array.isArray(pulse) ? pulse.durationMs : void 0;
52500
+ if (!capabilities.includes("output") || !capabilities.includes("pulse") || typeof duration2 !== "number" || !Number.isSafeInteger(duration2) || duration2 <= 0)
52501
52501
  return "Pulsed behavior requires output and pulse capabilities and a positive integer durationMs.";
52502
52502
  return void 0;
52503
52503
  }
@@ -53911,6 +53911,66 @@ WagoConfigurationRevision = __decorateClass([
53911
53911
  // backend/wago-command-handler.ts
53912
53912
  var import_node_crypto4 = require("node:crypto");
53913
53913
  var import_plugins_backend_sdk7 = require("@attraccess/plugins-backend-sdk");
53914
+
53915
+ // backend/wago-flow-preview.ts
53916
+ var WAGO_FLOW_PREVIEW_SCHEMA = { dynamic: true, type: "object", properties: {}, preview: [] };
53917
+ function wagoFlowPreview(config, kind, controller, snapshot, names) {
53918
+ const english = localizedPreview(config, kind, controller, snapshot, names, false);
53919
+ const german = localizedPreview(config, kind, controller, snapshot, names, true);
53920
+ return english.map((row, index) => ({ ...row, translations: { de: german[index] } }));
53921
+ }
53922
+ function localizedPreview(config, kind, controller, snapshot, names, german) {
53923
+ const text = (english, translated) => german ? translated : english;
53924
+ const channel = snapshot?.logicalChannels.find((item) => item.id === config.channelId);
53925
+ const point = snapshot?.physicalPoints?.find((item) => item.id === channel?.physicalPointId);
53926
+ let channelName = channel ? typeof names[channel.id] === "string" ? String(names[channel.id]) : channel.id : typeof config.channelId === "string" ? `${config.channelId} (${text("unavailable", "nicht verf\xFCgbar")})` : text("Not selected", "Nicht ausgew\xE4hlt");
53927
+ if (point?.modbus) {
53928
+ const device = snapshot?.modbus?.devices.find((item) => item.id === point.modbus?.deviceId);
53929
+ if (device) channelName = `${channelName} \xB7 ${device.name}`;
53930
+ } else if (point?.hardwareProfile === "751-9301") {
53931
+ const terminal = DIGITAL_TERMINALS.find((item) => item.channel === point.channel)?.label;
53932
+ if (terminal && !channelName.includes(terminal)) channelName += ` \xB7 ${terminal}`;
53933
+ }
53934
+ const rows = [
53935
+ {
53936
+ label: text("Device", "Ger\xE4t"),
53937
+ value: controller?.name || controller?.hardwareId || (typeof config.controllerId === "number" ? `Controller ${config.controllerId} (${text("unavailable", "nicht verf\xFCgbar")})` : text("Not selected", "Nicht ausgew\xE4hlt"))
53938
+ },
53939
+ { label: text("Channel", "Kanal"), value: channelName }
53940
+ ];
53941
+ if (kind === "command") {
53942
+ const action = config.action === "set" ? config.value === true ? text("Turn ON", "Einschalten") : config.value === false ? text("Turn OFF", "Ausschalten") : text("Select ON/OFF", "EIN/AUS ausw\xE4hlen") : config.action === "pulse" ? `${text("Pulse", "Impuls")}${channel?.pulse ? ` \xB7 ${duration(channel.pulse.durationMs)}` : ""}` : text("Not selected", "Nicht ausgew\xE4hlt");
53943
+ return [...rows, { label: text("Action", "Aktion"), value: action }];
53944
+ }
53945
+ const category = config.category === "measurement" ? text("Measurement", "Messwert") : config.category === "fault" ? text("Fault", "Fehler") : config.category === "state" ? channel?.capabilities.includes("input") ? text("Input state", "Eingangszustand") : text("Output state", "Ausgangszustand") : void 0;
53946
+ if (kind === "event")
53947
+ return [
53948
+ ...rows,
53949
+ {
53950
+ label: text("When", "Wenn"),
53951
+ value: category ? `${category} ${text("received", "empfangen")}` : text("Not selected", "Nicht ausgew\xE4hlt")
53952
+ }
53953
+ ];
53954
+ if (kind === "read")
53955
+ return [...rows, { label: text("Read", "Lesen"), value: category ?? text("Not selected", "Nicht ausgew\xE4hlt") }];
53956
+ const expected = typeof config.equals === "boolean" ? config.equals ? text("ON", "EIN") : text("OFF", "AUS") : typeof config.equals === "number" && Number.isFinite(config.equals) ? `${config.equals} (${text("wire value", "Rohwert")})` : text("Not set", "Nicht festgelegt");
53957
+ return [
53958
+ ...rows,
53959
+ {
53960
+ label: text("Wait for", "Warten auf"),
53961
+ value: `${category ?? text("Not selected", "Nicht ausgew\xE4hlt")} = ${expected}`
53962
+ },
53963
+ {
53964
+ label: text("Timeout", "Zeitlimit"),
53965
+ value: duration(typeof config.timeoutMs === "number" ? config.timeoutMs : 3e4)
53966
+ }
53967
+ ];
53968
+ }
53969
+ function duration(milliseconds) {
53970
+ return milliseconds < 1e3 ? `${milliseconds} ms` : `${milliseconds / 1e3} s`;
53971
+ }
53972
+
53973
+ // backend/wago-command-handler.ts
53914
53974
  var DEFAULT_COMMAND_TIMEOUT_SECONDS = 30;
53915
53975
  var MAX_COMMAND_TIMEOUT_SECONDS = 300;
53916
53976
  var WagoCommandError = class extends Error {
@@ -53925,10 +53985,10 @@ var WagoCommandHandler = class {
53925
53985
  __publicField(this, "dependencies", dependencies);
53926
53986
  __publicField(this, "pending", /* @__PURE__ */ new Map());
53927
53987
  }
53928
- async channelNames(controllerId, revision2) {
53988
+ async channelNames(controllerId, revision2, appliedOnly = false) {
53929
53989
  let names = {};
53930
53990
  if (controllerId) {
53931
- const draft = await this.dependencies.context.getRepository(WagoConfigurationDraft).findOneBy({ controllerId });
53991
+ const draft = appliedOnly ? null : await this.dependencies.context.getRepository(WagoConfigurationDraft).findOneBy({ controllerId });
53932
53992
  try {
53933
53993
  const storedNames = JSON.parse(revision2?.presetProvenance ?? draft?.presetProvenance ?? "null")?.editor?.names;
53934
53994
  if (storedNames && typeof storedNames === "object" && !Array.isArray(storedNames)) names = storedNames;
@@ -53937,14 +53997,30 @@ var WagoCommandHandler = class {
53937
53997
  }
53938
53998
  return names;
53939
53999
  }
53940
- async schema(config, resourceId) {
53941
- const controllers = await this.dependencies.controllers().find({ where: { trustState: "claimed" }, order: { name: "ASC" } });
54000
+ async schema(config, resourceId, previewOnly = false) {
53942
54001
  const controllerId = positiveInteger2(config.controllerId);
54002
+ const controllers = previewOnly && !controllerId ? [] : await this.dependencies.controllers().find({
54003
+ where: { trustState: "claimed", ...previewOnly ? { id: controllerId } : {} },
54004
+ order: { name: "ASC" }
54005
+ });
53943
54006
  const revision2 = controllerId ? await this.dependencies.appliedRevision(controllerId) : null;
53944
54007
  const snapshot = revision2 ? JSON.parse(revision2.snapshot) : null;
53945
54008
  const channelId2 = typeof config.channelId === "string" ? config.channelId : void 0;
53946
54009
  const outputChannels = snapshot?.logicalChannels.filter((item) => item.capabilities.includes("output")) ?? [];
53947
- const names = await this.channelNames(controllerId, revision2);
54010
+ const names = await this.channelNames(controllerId, revision2, previewOnly);
54011
+ if (previewOnly)
54012
+ return {
54013
+ dynamic: true,
54014
+ type: "object",
54015
+ properties: {},
54016
+ preview: wagoFlowPreview(
54017
+ config,
54018
+ "command",
54019
+ controllers.find((item) => item.id === controllerId),
54020
+ snapshot,
54021
+ names
54022
+ )
54023
+ };
53948
54024
  const channel = outputChannels.find((item) => item.id === channelId2);
53949
54025
  const references = channelId2 && controllerId ? await this.references(controllerId, channelId2, resourceId) : [];
53950
54026
  const properties = {
@@ -54024,6 +54100,13 @@ var WagoCommandHandler = class {
54024
54100
  return {
54025
54101
  dynamic: true,
54026
54102
  type: "object",
54103
+ preview: wagoFlowPreview(
54104
+ config,
54105
+ "command",
54106
+ controllers.find((item) => item.id === controllerId),
54107
+ snapshot,
54108
+ names
54109
+ ),
54027
54110
  properties,
54028
54111
  required: [
54029
54112
  .../* @__PURE__ */ new Set([
@@ -54708,8 +54791,8 @@ var WagoService = class {
54708
54791
  if (this.subscriptionRetryTimer) clearTimeout(this.subscriptionRetryTimer);
54709
54792
  this.commands.destroy();
54710
54793
  }
54711
- async commandSchema(config, resourceId) {
54712
- return this.commands.schema(config, resourceId);
54794
+ async commandSchema(config, resourceId, previewOnly = false) {
54795
+ return this.commands.schema(config, resourceId, previewOnly);
54713
54796
  }
54714
54797
  async validateCommandConfig(config, validationContext = /* @__PURE__ */ new Map()) {
54715
54798
  return this.commands.validate(config, validationContext);
@@ -56645,11 +56728,11 @@ async function commissionClock(execute, confirmInstall, report, now = Date.now,
56645
56728
  const start = monotonic();
56646
56729
  const observed = parseSample(await execute(CLOCK_INSPECTION_SCRIPT, CLOCK_LIMITS));
56647
56730
  const received = now();
56648
- const duration = monotonic() - start;
56649
- if (!validEpoch(Math.floor(received / 1e3)) || duration < 0 || duration > 4e3 || Math.abs(received - hostStarted - (monotonic() - started)) > 1e3)
56731
+ const duration2 = monotonic() - start;
56732
+ if (!validEpoch(Math.floor(received / 1e3)) || duration2 < 0 || duration2 > 4e3 || Math.abs(received - hostStarted - (monotonic() - started)) > 1e3)
56650
56733
  throw new Error("Application clock changed or controller clock observation expired.");
56651
- const host = received - duration / 2;
56652
- const uncertaintySeconds = Math.ceil(duration / 2e3) + 1;
56734
+ const host = received - duration2 / 2;
56735
+ const uncertaintySeconds = Math.ceil(duration2 / 2e3) + 1;
56653
56736
  const skew = observed.epoch - Math.floor(host / 1e3);
56654
56737
  if (Math.abs(skew) > MAX_SKEW_SECONDS)
56655
56738
  throw new Error("Controller clock skew exceeds the supported ten-year bound.");
@@ -62252,6 +62335,13 @@ function diagnosticReferences(nodes, channelIds, revision2, capabilities) {
62252
62335
  return nodes.map((node) => {
62253
62336
  const channelId2 = typeof node.data.channelId === "string" ? node.data.channelId : "";
62254
62337
  const control = node.type === "plugin.wago.command";
62338
+ const conflictResourceIds = control ? [
62339
+ ...new Set(
62340
+ nodes.filter(
62341
+ (other) => other.type === "plugin.wago.command" && other.resourceId !== node.resourceId && other.data.channelId === channelId2
62342
+ ).map((other) => other.resourceId)
62343
+ )
62344
+ ] : [];
62255
62345
  return {
62256
62346
  nodeId: node.id,
62257
62347
  resourceId: node.resourceId,
@@ -62259,9 +62349,8 @@ function diagnosticReferences(nodes, channelIds, revision2, capabilities) {
62259
62349
  control,
62260
62350
  href: `/resources/${node.resourceId}/flows?node=${encodeURIComponent(node.id)}`,
62261
62351
  invalid: !channelIds.includes(channelId2) || control && (node.data.expectedConfigurationRevision !== revision2 || capabilities && (!own(capabilities, channelId2)?.includes("output") || node.data.action === "pulse" && !own(capabilities, channelId2)?.includes("pulse"))),
62262
- conflict: control && nodes.some(
62263
- (other) => other.type === "plugin.wago.command" && other.resourceId !== node.resourceId && other.data.channelId === channelId2
62264
- )
62352
+ conflict: conflictResourceIds.length > 0,
62353
+ conflictResourceIds
62265
62354
  };
62266
62355
  });
62267
62356
  }
@@ -62304,12 +62393,16 @@ var WagoDiagnosticsService = class {
62304
62393
  const referencesTruncated = conflictNodes.length > 1e3;
62305
62394
  const conflictNodesByControllerId = /* @__PURE__ */ new Map();
62306
62395
  for (const node of conflictNodes.slice(0, 1e3)) {
62396
+ if (node.resourceId === resourceId) continue;
62307
62397
  const controllerId = node.data.controllerId;
62308
62398
  if (typeof controllerId !== "number") continue;
62309
62399
  const matchingNodes = conflictNodesByControllerId.get(controllerId) ?? [];
62310
62400
  matchingNodes.push(node);
62311
62401
  conflictNodesByControllerId.set(controllerId, matchingNodes);
62312
62402
  }
62403
+ const conflictResourceIds = [...new Set([...conflictNodesByControllerId.values()].flat().map((n) => n.resourceId))];
62404
+ const conflictResources = conflictResourceIds.length ? await this.context.dataSource.getRepository(import_plugins_backend_sdk16.Resource).createQueryBuilder("resource").select(["resource.id", "resource.name"]).where("resource.id IN (:...ids)", { ids: conflictResourceIds }).getMany() : [];
62405
+ const resourceNames = new Map(conflictResources.map((resource) => [resource.id, resource.name]));
62313
62406
  const controllersResult = selectedControllerIds.map((controllerId) => {
62314
62407
  const controller = controllersById.get(controllerId);
62315
62408
  if (!controller)
@@ -62331,7 +62424,13 @@ var WagoDiagnosticsService = class {
62331
62424
  Object.fromEntries(
62332
62425
  appliedSnapshot?.logicalChannels.map((channel) => [channel.id, channel.capabilities]) ?? []
62333
62426
  )
62334
- ).filter((reference) => reference.resourceId === resourceId);
62427
+ ).filter((reference) => reference.resourceId === resourceId).map((reference) => ({
62428
+ ...reference,
62429
+ conflictResources: reference.conflictResourceIds.map((id) => ({
62430
+ id,
62431
+ name: resourceNames.get(id) ?? `Resource ${id}`
62432
+ }))
62433
+ }));
62335
62434
  return {
62336
62435
  controllerId,
62337
62436
  name: controller.name ?? controller.hardwareId,
@@ -62470,10 +62569,11 @@ function createWagoCommandNode(service) {
62470
62569
  type: WAGO_COMMAND_NODE_TYPE,
62471
62570
  label: "WAGO command",
62472
62571
  description: "Control a configured WAGO Logical Channel.",
62572
+ configSchema: WAGO_FLOW_PREVIEW_SCHEMA,
62473
62573
  inputs: ["input"],
62474
62574
  outputs: ["output", "failure"],
62475
62575
  isOutput: true,
62476
- resolveConfigSchema: (config, schemaContext) => service().commandSchema(config, schemaContext.resourceId),
62576
+ resolveConfigSchema: (config, schemaContext) => service().commandSchema(config, schemaContext.resourceId, schemaContext.purpose === "preview"),
62477
62577
  validateConfig: (config, validationContext) => service().validateCommandConfig(config, validationContext),
62478
62578
  getFailureBehavior: (config) => service().commandFailureBehavior(config),
62479
62579
  getFailureKind: (error) => service().commandFailureKind(error),
@@ -62495,19 +62595,21 @@ function createWagoStateNodes(service) {
62495
62595
  type: WAGO_EVENT_NODE_TYPE,
62496
62596
  label: "WAGO event received",
62497
62597
  description: "Start a flow when a channel reports state, a measurement, or a fault. Data is available in wago.",
62598
+ configSchema: WAGO_FLOW_PREVIEW_SCHEMA,
62498
62599
  isInput: true,
62499
62600
  inputs: [],
62500
62601
  outputs: ["output"],
62501
- resolveConfigSchema: (config) => service().resolveConfigSchema(config, "event"),
62602
+ resolveConfigSchema: (config, context) => service().resolveConfigSchema(config, "event", void 0, context.purpose === "preview"),
62502
62603
  validateConfig: (config, context) => service().validateConfig(config, "event", context)
62503
62604
  },
62504
62605
  {
62505
62606
  type: "plugin.wago.read-state",
62506
62607
  label: "WAGO read state",
62507
62608
  description: "Read the latest channel state or measurement into wago. Unavailable data uses the unavailable output.",
62609
+ configSchema: WAGO_FLOW_PREVIEW_SCHEMA,
62508
62610
  inputs: ["input"],
62509
62611
  outputs: ["output", "unavailable"],
62510
- resolveConfigSchema: (config) => service().resolveConfigSchema(config, "read"),
62612
+ resolveConfigSchema: (config, context) => service().resolveConfigSchema(config, "read", void 0, context.purpose === "preview"),
62511
62613
  validateConfig: (config, context) => service().validateConfig(config, "read", context),
62512
62614
  execute: async (node, input) => {
62513
62615
  const state = service().read(node.data);
@@ -62519,9 +62621,10 @@ function createWagoStateNodes(service) {
62519
62621
  type: "plugin.wago.wait-for-state",
62520
62622
  label: "WAGO wait for state",
62521
62623
  description: "Wait for an available channel value to match, then continue with the value in wago.",
62624
+ configSchema: WAGO_FLOW_PREVIEW_SCHEMA,
62522
62625
  inputs: ["input"],
62523
62626
  outputs: ["output", "timeout"],
62524
- resolveConfigSchema: (config) => service().resolveConfigSchema(config, "wait"),
62627
+ resolveConfigSchema: (config, context) => service().resolveConfigSchema(config, "wait", void 0, context.purpose === "preview"),
62525
62628
  validateConfig: (config, context) => service().validateConfig(config, "wait", context),
62526
62629
  execute: async (node, input) => {
62527
62630
  const state = await service().wait(node.data);
@@ -62653,11 +62756,15 @@ var WagoFlowService = class {
62653
62756
  this.subscriptions.push(...replacements);
62654
62757
  this.controllerByHardwareId = controllerByHardwareId;
62655
62758
  }
62656
- async resolveConfigSchema(config, kind, validationContext = /* @__PURE__ */ new Map()) {
62759
+ async resolveConfigSchema(config, kind, validationContext = /* @__PURE__ */ new Map(), previewOnly = false) {
62760
+ const controllerCacheKey = previewOnly ? `wago-flow-controllers:preview:${config.controllerId}` : "wago-flow-controllers";
62657
62761
  const controllers = await this.cached(
62658
62762
  validationContext,
62659
- "wago-flow-controllers",
62660
- () => this.controllers.find({ where: { trustState: "claimed" }, order: { name: "ASC" } })
62763
+ controllerCacheKey,
62764
+ () => previewOnly && typeof config.controllerId !== "number" ? Promise.resolve([]) : this.controllers.find({
62765
+ where: { trustState: "claimed", ...previewOnly ? { id: config.controllerId } : {} },
62766
+ order: { name: "ASC" }
62767
+ })
62661
62768
  );
62662
62769
  const selected = typeof config.controllerId === "number" ? controllers.find((controller) => controller.id === config.controllerId) : void 0;
62663
62770
  const revision2 = selected ? await this.cached(validationContext, `wago-applied-revision:${selected.id}`, async () => {
@@ -62668,12 +62775,19 @@ var WagoFlowService = class {
62668
62775
  });
62669
62776
  return latest ?? null;
62670
62777
  }) : null;
62671
- const channels = revision2 ? JSON.parse(revision2.snapshot).logicalChannels : [];
62778
+ const snapshot = revision2 ? JSON.parse(revision2.snapshot) : null;
62779
+ const channels = snapshot?.logicalChannels ?? [];
62672
62780
  let names = {};
62673
62781
  try {
62674
62782
  names = JSON.parse(revision2?.presetProvenance ?? "null")?.editor?.names ?? {};
62675
62783
  } catch {
62676
62784
  }
62785
+ if (previewOnly) return {
62786
+ dynamic: true,
62787
+ type: "object",
62788
+ properties: {},
62789
+ preview: wagoFlowPreview(config, kind, selected, snapshot, names)
62790
+ };
62677
62791
  const channel = channels.find((item) => item.id === config.channelId);
62678
62792
  const properties = {
62679
62793
  controllerId: {
@@ -62729,6 +62843,7 @@ var WagoFlowService = class {
62729
62843
  return {
62730
62844
  dynamic: true,
62731
62845
  type: "object",
62846
+ preview: wagoFlowPreview(config, kind, selected, snapshot, names),
62732
62847
  properties,
62733
62848
  required: ["controllerId", "channelId", "category", ...kind === "wait" ? ["equals", "timeoutMs"] : []]
62734
62849
  };