@camstack/addon-model-studio 1.1.51 → 1.1.52

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/_stub.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import "./virtualExposes-CWSi4E_g.mjs";
2
- import "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DOi9vT32.mjs";
2
+ import "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-CZmB5SRo.mjs";
3
3
  import { _ as e, c as t, d as n, h as r, i, l as a, m as o, p as s, r as c, t as l, u, y as d } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DJDHChgO.mjs";
4
4
  import { a as f, i as p, o as m, r as h, s as g } from "./responsive-BWVkSjgC.mjs";
5
5
  import { c as _, l as v, u as y } from "./use-device-snapshot-CkQG2lkA.mjs";
@@ -1739,7 +1739,7 @@ function ln() {
1739
1739
  isLoading: t
1740
1740
  };
1741
1741
  }
1742
- L.accessories.setChildHidden.useMutation, L.accessories.getStatus.useQuery, L.addonPages.listPages.useQuery, L.addons.list.useQuery, L.addons.getLogs.useQuery, L.addons.listPackages.useQuery, L.addons.installPackage.useMutation, L.addons.installFromWorkspace.useMutation, L.addons.isWorkspaceAvailable.useQuery, L.addons.listWorkspacePackages.useQuery, L.addons.uninstallPackage.useMutation, L.addons.reloadPackages.useMutation, L.addons.searchAvailable.useQuery, L.addons.listUpdates.useQuery, L.addons.updatePackage.useMutation, L.addons.rollbackPackage.useMutation, L.addons.forceRefresh.useMutation, L.addons.restartServer.useMutation, L.addons.getLastRestart.useQuery, L.addons.listFrameworkPackages.useQuery, L.addons.listCapabilityProviders.useQuery, L.addons.setCapabilityProviderEnabled.useMutation, L.addons.getVersions.useQuery, L.addons.restartAddon.useMutation, L.addons.retryLoad.useMutation, L.addons.getAutoUpdateSettings.useQuery, L.addons.setAutoUpdateSettings.useMutation, L.addons.getAddonAutoUpdate.useQuery, L.addons.setAddonAutoUpdate.useMutation, L.addons.applyAutoUpdateToAll.useMutation, L.addons.custom.useMutation, L.addons.startJob.useMutation, L.addons.getJob.useQuery, L.addons.listJobs.useQuery, L.addons.cancelJob.useMutation, L.addons.onAddonLogs.useSubscription, L.addonSettings.getGlobalSettings.useQuery, L.addonSettings.updateGlobalSettings.useMutation, L.addonSettings.getDeviceSettings.useQuery, L.addonSettings.updateDeviceSettings.useMutation, L.addonWidgets.listWidgets.useQuery, L.airQualitySensor.getStatus.useQuery, L.alarmPanel.arm.useMutation, L.alarmPanel.disarm.useMutation, L.alarmPanel.trigger.useMutation, L.alarmPanel.getStatus.useQuery, L.alerts.emit.useMutation, L.alerts.update.useMutation, L.alerts.list.useQuery, L.alerts.getUnreadCount.useQuery, L.alerts.markRead.useMutation, L.alerts.markAllRead.useMutation, L.alerts.dismiss.useMutation, L.ambientLightSensor.getStatus.useQuery, L.audioAnalysis.resolveDeviceSettings.useQuery, L.audioAnalysis.getDeviceSettingsContribution.useQuery, L.audioAnalysis.getDeviceLiveContribution.useQuery, L.audioAnalysis.applyDeviceSettingsPatch.useMutation, L.audioAnalyzer.analyseChunk.useMutation, L.audioAnalyzer.classify.useQuery, L.audioAnalyzer.isReady.useQuery, L.audioAnalyzer.dispose.useMutation, L.audioAnalyzer.reprobeAudioEngine.useMutation, L.audioCodec.listSupportedCodecs.useQuery, L.audioCodec.canHandle.useQuery, L.audioCodec.createDecodeSession.useMutation, L.audioCodec.createEncodeSession.useMutation, L.audioCodec.closeSession.useMutation, L.audioCodec.pushEncodedFrame.useMutation, L.audioCodec.pullPcm.useQuery, L.audioCodec.pushPcm.useMutation, L.audioCodec.pullEncoded.useQuery, L.audioCodec.flushEncode.useMutation, L.audioCodec.listActiveSessions.useQuery, L.audioMetrics.getCurrentSnapshot.useQuery, L.audioMetrics.getHistory.useQuery, L.automationControl.enable.useMutation, L.automationControl.disable.useMutation, L.automationControl.trigger.useMutation, L.automationControl.getStatus.useQuery, L.backup.listDestinations.useQuery, L.backup.trigger.useMutation, L.backup.list.useQuery, L.backup.listLocations.useQuery, L.backup.getEntries.useQuery, L.backup.restore.useMutation, L.backup.delete.useMutation, L.backup.listArchives.useQuery, L.backup.upsertDestinationPolicy.useMutation, L.backup.previewSchedule.useQuery, L.backup.listSchedules.useQuery, L.backup.upsertSchedule.useMutation, L.backup.deleteSchedule.useMutation, L.battery.wakeForStream.useMutation, L.battery.getStatus.useQuery, L.binary.getStatus.useQuery, L.brightness.setBrightness.useMutation, L.brightness.getStatus.useQuery, L.broker.list.useQuery, L.broker.get.useQuery, L.broker.listProviders.useQuery, L.broker.add.useMutation, L.broker.remove.useMutation, L.broker.testConnection.useMutation, L.broker.getSettings.useQuery, L.broker.setSettings.useMutation, L.broker.getBrokerConfig.useQuery, L.broker.getSettingsSchema.useQuery, L.broker.testSettings.useMutation, L.broker.publish.useMutation, L.broker.subscribe.useMutation, L.broker.unsubscribe.useMutation, L.broker.getState.useQuery, L.broker.getStatus.useQuery, L.button.press.useMutation, L.cameraCredentials.getCredentials.useQuery, L.cameraCredentials.getStatus.useQuery, L.cameraPipelineConfig.getDeviceSettingsContribution.useQuery, L.cameraPipelineConfig.getDeviceLiveContribution.useQuery, L.cameraPipelineConfig.applyDeviceSettingsPatch.useMutation, L.cameraStreams.getCameraStreams.useQuery, L.cameraStreams.getBrokerStreams.useQuery, L.cameraStreams.getRtspEntries.useQuery, L.cameraStreams.getProfileRtspEntries.useQuery, L.cameraStreams.pickStream.useQuery, L.carbonMonoxide.getStatus.useQuery, L.climateControl.setMode.useMutation, L.climateControl.setFanMode.useMutation, L.climateControl.setPreset.useMutation, L.climateControl.setTarget.useMutation, L.climateControl.setTargetRange.useMutation, L.climateControl.setTargetHumidity.useMutation, L.climateControl.setSwingVertical.useMutation, L.climateControl.setSwingHorizontal.useMutation, L.climateControl.getStatus.useQuery, L.color.setColor.useMutation, L.color.getStatus.useQuery, L.connectionTest.testSettings.useMutation, L.connectionTest.describeTest.useQuery, L.connectivity.getStatus.useQuery, L.consumables.reset.useMutation, L.consumables.getStatus.useQuery, L.contact.getStatus.useQuery, L.control.setValue.useMutation, L.control.getStatus.useQuery, L.coreBlocks.list.useQuery, L.coreBlocks.get.useQuery, L.coreBlocks.create.useMutation, L.coreBlocks.update.useMutation, L.coreBlocks.delete.useMutation, L.coreBlocks.setEnabled.useMutation, L.coreBlocks.restart.useMutation, L.coreBlocks.compile.useMutation, L.coreBlocks.getTypeDefs.useQuery, L.cover.open.useMutation, L.cover.close.useMutation, L.cover.stop.useMutation, L.cover.setPosition.useMutation, L.cover.setTiltPosition.useMutation, L.cover.getStatus.useQuery, L.dayNight.getOptions.useQuery, L.dayNight.setSettings.useMutation, L.dayNight.getStatus.useQuery, L.decoder.supportsCodec.useQuery, L.decoder.getInfo.useQuery, L.decoder.createSession.useQuery, L.decoder.destroySession.useQuery, L.decoder.pushPacket.useQuery, L.decoder.openStream.useQuery, L.decoder.pullFrames.useQuery, L.decoder.pullHandles.useQuery, L.decoder.getFrame.useQuery, L.decoder.getShmStats.useQuery, L.decoder.updateConfig.useQuery, L.decoder.getStats.useQuery, L.decoder.listActiveSessions.useQuery, L.decoder.reprobeHwaccel.useMutation, L.detectionPipeline.getDeviceSettingsContribution.useQuery, L.detectionPipeline.getDeviceLiveContribution.useQuery, L.detectionPipeline.applyDeviceSettingsPatch.useMutation, L.deviceAdoption.listCandidateFilters.useQuery, L.deviceAdoption.listCandidates.useQuery, L.deviceAdoption.getCandidate.useQuery, L.deviceAdoption.refresh.useMutation, L.deviceAdoption.adopt.useMutation, L.deviceAdoption.release.useMutation, L.deviceAdoption.resync.useMutation, L.deviceAdoption.getStatus.useQuery, L.deviceDiscovery.listDiscovered.useQuery, L.deviceDiscovery.refreshDiscovery.useMutation, L.deviceDiscovery.adoptDevice.useMutation, L.deviceDiscovery.releaseDevice.useMutation, L.deviceDiscovery.getStatus.useQuery, L.deviceExport.getStatus.useQuery, L.deviceExport.listSupportedDeviceKinds.useQuery, L.deviceExport.listExposedDevices.useQuery, L.deviceExport.exposeDevice.useMutation, L.deviceExport.unexposeDevice.useMutation, L.deviceExport.getDeviceSettingsContribution.useQuery, L.deviceExport.getDeviceLiveContribution.useQuery, L.deviceExport.applyDeviceSettingsPatch.useMutation, L.deviceManager.allocateDeviceId.useMutation, L.deviceManager.registerDevice.useMutation, L.deviceManager.removeDevice.useMutation, L.deviceManager.persistConfig.useMutation, L.deviceManager.loadConfig.useQuery, L.deviceManager.loadRuntimeState.useQuery, L.deviceManager.loadMeta.useQuery, L.deviceManager.setName.useMutation, L.deviceManager.setLocation.useMutation, L.deviceManager.setType.useMutation, L.deviceManager.setIntegrationId.useMutation, L.deviceManager.setLinkDeviceId.useMutation, L.deviceManager.setPrimaryChildEntityId.useMutation, L.deviceManager.setChildLayout.useMutation, L.deviceManager.setDisplay.useMutation;
1742
+ L.accessories.setChildHidden.useMutation, L.accessories.getStatus.useQuery, L.addonPages.listPages.useQuery, L.addons.list.useQuery, L.addons.getLogs.useQuery, L.addons.listPackages.useQuery, L.addons.installPackage.useMutation, L.addons.installFromWorkspace.useMutation, L.addons.isWorkspaceAvailable.useQuery, L.addons.listWorkspacePackages.useQuery, L.addons.uninstallPackage.useMutation, L.addons.reloadPackages.useMutation, L.addons.searchAvailable.useQuery, L.addons.listUpdates.useQuery, L.addons.updatePackage.useMutation, L.addons.rollbackPackage.useMutation, L.addons.forceRefresh.useMutation, L.addons.restartServer.useMutation, L.addons.getLastRestart.useQuery, L.addons.listFrameworkPackages.useQuery, L.addons.listCapabilityProviders.useQuery, L.addons.setCapabilityProviderEnabled.useMutation, L.addons.getVersions.useQuery, L.addons.restartAddon.useMutation, L.addons.retryLoad.useMutation, L.addons.getAutoUpdateSettings.useQuery, L.addons.setAutoUpdateSettings.useMutation, L.addons.getAddonAutoUpdate.useQuery, L.addons.setAddonAutoUpdate.useMutation, L.addons.applyAutoUpdateToAll.useMutation, L.addons.custom.useMutation, L.addons.startJob.useMutation, L.addons.getJob.useQuery, L.addons.listJobs.useQuery, L.addons.cancelJob.useMutation, L.addons.onAddonLogs.useSubscription, L.addonSettings.getGlobalSettings.useQuery, L.addonSettings.updateGlobalSettings.useMutation, L.addonSettings.getIntegrationSettings.useQuery, L.addonSettings.getDeviceSettings.useQuery, L.addonSettings.updateDeviceSettings.useMutation, L.addonWidgets.listWidgets.useQuery, L.airQualitySensor.getStatus.useQuery, L.alarmPanel.arm.useMutation, L.alarmPanel.disarm.useMutation, L.alarmPanel.trigger.useMutation, L.alarmPanel.getStatus.useQuery, L.alerts.emit.useMutation, L.alerts.update.useMutation, L.alerts.list.useQuery, L.alerts.getUnreadCount.useQuery, L.alerts.markRead.useMutation, L.alerts.markAllRead.useMutation, L.alerts.dismiss.useMutation, L.ambientLightSensor.getStatus.useQuery, L.audioAnalysis.resolveDeviceSettings.useQuery, L.audioAnalysis.getDeviceSettingsContribution.useQuery, L.audioAnalysis.getDeviceLiveContribution.useQuery, L.audioAnalysis.applyDeviceSettingsPatch.useMutation, L.audioAnalyzer.analyseChunk.useMutation, L.audioAnalyzer.classify.useQuery, L.audioAnalyzer.isReady.useQuery, L.audioAnalyzer.dispose.useMutation, L.audioAnalyzer.reprobeAudioEngine.useMutation, L.audioCodec.listSupportedCodecs.useQuery, L.audioCodec.canHandle.useQuery, L.audioCodec.createDecodeSession.useMutation, L.audioCodec.createEncodeSession.useMutation, L.audioCodec.closeSession.useMutation, L.audioCodec.pushEncodedFrame.useMutation, L.audioCodec.pullPcm.useQuery, L.audioCodec.pushPcm.useMutation, L.audioCodec.pullEncoded.useQuery, L.audioCodec.flushEncode.useMutation, L.audioCodec.listActiveSessions.useQuery, L.audioMetrics.getCurrentSnapshot.useQuery, L.audioMetrics.getHistory.useQuery, L.automationControl.enable.useMutation, L.automationControl.disable.useMutation, L.automationControl.trigger.useMutation, L.automationControl.getStatus.useQuery, L.backup.listDestinations.useQuery, L.backup.trigger.useMutation, L.backup.list.useQuery, L.backup.listLocations.useQuery, L.backup.getEntries.useQuery, L.backup.restore.useMutation, L.backup.delete.useMutation, L.backup.listArchives.useQuery, L.backup.upsertDestinationPolicy.useMutation, L.backup.previewSchedule.useQuery, L.backup.listSchedules.useQuery, L.backup.upsertSchedule.useMutation, L.backup.deleteSchedule.useMutation, L.battery.wakeForStream.useMutation, L.battery.getStatus.useQuery, L.binary.getStatus.useQuery, L.brightness.setBrightness.useMutation, L.brightness.getStatus.useQuery, L.broker.list.useQuery, L.broker.get.useQuery, L.broker.listProviders.useQuery, L.broker.add.useMutation, L.broker.remove.useMutation, L.broker.testConnection.useMutation, L.broker.getSettings.useQuery, L.broker.setSettings.useMutation, L.broker.getBrokerConfig.useQuery, L.broker.getSettingsSchema.useQuery, L.broker.testSettings.useMutation, L.broker.publish.useMutation, L.broker.subscribe.useMutation, L.broker.unsubscribe.useMutation, L.broker.getState.useQuery, L.broker.getStatus.useQuery, L.button.press.useMutation, L.cameraCredentials.getCredentials.useQuery, L.cameraCredentials.getStatus.useQuery, L.cameraPipelineConfig.getDeviceSettingsContribution.useQuery, L.cameraPipelineConfig.getDeviceLiveContribution.useQuery, L.cameraPipelineConfig.applyDeviceSettingsPatch.useMutation, L.cameraStreams.getCameraStreams.useQuery, L.cameraStreams.getBrokerStreams.useQuery, L.cameraStreams.getRtspEntries.useQuery, L.cameraStreams.getProfileRtspEntries.useQuery, L.cameraStreams.pickStream.useQuery, L.carbonMonoxide.getStatus.useQuery, L.climateControl.setMode.useMutation, L.climateControl.setFanMode.useMutation, L.climateControl.setPreset.useMutation, L.climateControl.setTarget.useMutation, L.climateControl.setTargetRange.useMutation, L.climateControl.setTargetHumidity.useMutation, L.climateControl.setSwingVertical.useMutation, L.climateControl.setSwingHorizontal.useMutation, L.climateControl.getStatus.useQuery, L.color.setColor.useMutation, L.color.getStatus.useQuery, L.connectionTest.testSettings.useMutation, L.connectionTest.describeTest.useQuery, L.connectivity.getStatus.useQuery, L.consumables.reset.useMutation, L.consumables.getStatus.useQuery, L.contact.getStatus.useQuery, L.control.setValue.useMutation, L.control.getStatus.useQuery, L.coreBlocks.list.useQuery, L.coreBlocks.get.useQuery, L.coreBlocks.create.useMutation, L.coreBlocks.update.useMutation, L.coreBlocks.delete.useMutation, L.coreBlocks.setEnabled.useMutation, L.coreBlocks.restart.useMutation, L.coreBlocks.compile.useMutation, L.coreBlocks.getTypeDefs.useQuery, L.cover.open.useMutation, L.cover.close.useMutation, L.cover.stop.useMutation, L.cover.setPosition.useMutation, L.cover.setTiltPosition.useMutation, L.cover.getStatus.useQuery, L.dayNight.getOptions.useQuery, L.dayNight.setSettings.useMutation, L.dayNight.getStatus.useQuery, L.decoder.supportsCodec.useQuery, L.decoder.getInfo.useQuery, L.decoder.createSession.useQuery, L.decoder.destroySession.useQuery, L.decoder.pushPacket.useQuery, L.decoder.openStream.useQuery, L.decoder.pullFrames.useQuery, L.decoder.pullHandles.useQuery, L.decoder.getFrame.useQuery, L.decoder.getShmStats.useQuery, L.decoder.updateConfig.useQuery, L.decoder.getStats.useQuery, L.decoder.listActiveSessions.useQuery, L.decoder.reprobeHwaccel.useMutation, L.detectionPipeline.getDeviceSettingsContribution.useQuery, L.detectionPipeline.getDeviceLiveContribution.useQuery, L.detectionPipeline.applyDeviceSettingsPatch.useMutation, L.deviceAdoption.listCandidateFilters.useQuery, L.deviceAdoption.listCandidates.useQuery, L.deviceAdoption.getCandidate.useQuery, L.deviceAdoption.refresh.useMutation, L.deviceAdoption.adopt.useMutation, L.deviceAdoption.release.useMutation, L.deviceAdoption.resync.useMutation, L.deviceAdoption.getStatus.useQuery, L.deviceDiscovery.listDiscovered.useQuery, L.deviceDiscovery.refreshDiscovery.useMutation, L.deviceDiscovery.adoptDevice.useMutation, L.deviceDiscovery.releaseDevice.useMutation, L.deviceDiscovery.getStatus.useQuery, L.deviceExport.getStatus.useQuery, L.deviceExport.listSupportedDeviceKinds.useQuery, L.deviceExport.listExposedDevices.useQuery, L.deviceExport.exposeDevice.useMutation, L.deviceExport.unexposeDevice.useMutation, L.deviceExport.getDeviceSettingsContribution.useQuery, L.deviceExport.getDeviceLiveContribution.useQuery, L.deviceExport.applyDeviceSettingsPatch.useMutation, L.deviceManager.allocateDeviceId.useMutation, L.deviceManager.registerDevice.useMutation, L.deviceManager.removeDevice.useMutation, L.deviceManager.persistConfig.useMutation, L.deviceManager.loadConfig.useQuery, L.deviceManager.loadRuntimeState.useQuery, L.deviceManager.loadMeta.useQuery, L.deviceManager.setName.useMutation, L.deviceManager.setLocation.useMutation, L.deviceManager.setType.useMutation, L.deviceManager.setIntegrationId.useMutation, L.deviceManager.setLinkDeviceId.useMutation, L.deviceManager.setPrimaryChildEntityId.useMutation, L.deviceManager.setChildLayout.useMutation, L.deviceManager.setDisplay.useMutation;
1743
1743
  var un = L.deviceManager.getRoleDisplayDefaults.useQuery;
1744
1744
  L.deviceManager.setRoleDisplayDefaults.useMutation, L.deviceManager.getWireableFields.useQuery, L.deviceManager.setRole.useMutation, L.deviceManager.applyInitialMeta.useMutation, L.deviceManager.setMetadata.useMutation, L.deviceManager.listLocations.useQuery, L.deviceManager.addLocation.useMutation, L.deviceManager.removeLocation.useMutation, L.deviceManager.setDisabled.useMutation, L.deviceManager.listPersistedByAddon.useQuery, L.deviceManager.listAll.useQuery;
1745
1745
  var dn = L.deviceManager.getDevice.useQuery;
@@ -1,9 +1,9 @@
1
- import "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DOi9vT32.mjs";
1
+ import "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-CZmB5SRo.mjs";
2
2
  //#region \0virtual:mf-localSharedImportMap:__mfe_internal__addon_model_studio_page
3
3
  var e = {
4
4
  "@camstack/sdk": {
5
5
  name: "@camstack/sdk",
6
- version: "1.2.40",
6
+ version: "1.2.41",
7
7
  scope: ["default"],
8
8
  loaded: !1,
9
9
  from: "addon_model_studio_page",
@@ -18,7 +18,7 @@ var e = {
18
18
  },
19
19
  "@camstack/types": {
20
20
  name: "@camstack/types",
21
- version: "1.2.118",
21
+ version: "1.2.119",
22
22
  scope: ["default"],
23
23
  loaded: !1,
24
24
  from: "addon_model_studio_page",
@@ -33,7 +33,7 @@ var e = {
33
33
  },
34
34
  "@camstack/ui-library": {
35
35
  name: "@camstack/ui-library",
36
- version: "1.2.81",
36
+ version: "1.2.82",
37
37
  scope: ["default"],
38
38
  loaded: !1,
39
39
  from: "addon_model_studio_page",
@@ -36,7 +36,7 @@ async function r() {
36
36
  }
37
37
  },
38
38
  "@camstack/types": {
39
- version: "1.2.118",
39
+ version: "1.2.119",
40
40
  scope: "default",
41
41
  shareConfig: {
42
42
  singleton: !0,
@@ -45,7 +45,7 @@ async function r() {
45
45
  }
46
46
  },
47
47
  "@camstack/sdk": {
48
- version: "1.2.40",
48
+ version: "1.2.41",
49
49
  scope: "default",
50
50
  shareConfig: {
51
51
  singleton: !0,
@@ -81,7 +81,7 @@ async function r() {
81
81
  }
82
82
  },
83
83
  "@camstack/ui-library": {
84
- version: "1.2.81",
84
+ version: "1.2.82",
85
85
  scope: "default",
86
86
  shareConfig: {
87
87
  singleton: !0,
@@ -6440,6 +6440,40 @@ var BaseAddon = class {
6440
6440
  deviceSettingsSchema() {
6441
6441
  return null;
6442
6442
  }
6443
+ /**
6444
+ * INTEGRATION-LEVEL SETTINGS — declare which of this addon's global sections
6445
+ * ARE the configuration of its integration.
6446
+ *
6447
+ * Return the `ConfigSection.id`s, from {@link globalSettingsSchema}, that an
6448
+ * operator should find on the addon's integration page (System →
6449
+ * Integrations → <name>) rather than only in the cluster-wide list of every
6450
+ * addon. Empty (the default) means the addon has no integration-level
6451
+ * settings and no such surface is offered — this is opt-in, because whether
6452
+ * an addon's configuration IS its integration's configuration depends on the
6453
+ * nature of the integration.
6454
+ *
6455
+ * WHAT THIS IS NOT. It is not a scope. The selected sections keep living in
6456
+ * the ONE global schema, in the ONE addon store, written by the ONE
6457
+ * `updateGlobalSettings` path. There is deliberately no
6458
+ * `updateIntegrationSettings`: a second write path is how a surface acquires
6459
+ * a second store key, and this repo has shipped that twice (`btmPath@hub`,
6460
+ * D266). Selecting sections cannot introduce a key that selecting cannot.
6461
+ *
6462
+ * WHY IT IS A LIST OF SECTION IDS AND NOT A MARKER ON THE SECTION.
6463
+ * `ConfigFieldBase` used to carry `scope?: 'device' | 'global'` and it was
6464
+ * removed with the reason recorded at
6465
+ * `packages/types/src/interfaces/config-ui.ts:249` — *"a field's scope is
6466
+ * determined by WHICH schema it lives in, not by a field-level marker."* A
6467
+ * marker sprinkled across sections also has to borrow a field that already
6468
+ * means something else; borrowing `section.tab` put the literal word
6469
+ * "integration" into an operator-facing tab bar, because `tab` means "how to
6470
+ * GROUP this visually" and cannot also mean "where this lives" (D269
6471
+ * supersedes D268). One declaration, in one place, next to the schema whose
6472
+ * ids it names.
6473
+ */
6474
+ integrationSettingSections() {
6475
+ return [];
6476
+ }
6443
6477
  async getGlobalSettings(overlay, cap, nodeId) {
6444
6478
  const schema = this.globalSettingsSchema(cap);
6445
6479
  if (!schema) return { sections: [] };
@@ -6450,6 +6484,55 @@ var BaseAddon = class {
6450
6484
  } : projected);
6451
6485
  }
6452
6486
  /**
6487
+ * The integration-level view of this addon's settings: exactly the sections
6488
+ * named by {@link integrationSettingSections}, hydrated from the SAME store
6489
+ * `getGlobalSettings` reads, and narrowed to cluster-scoped fields.
6490
+ *
6491
+ * Returns `null` when the addon declared nothing — an addon that opts out has
6492
+ * no integration settings surface at all, rather than an empty one that reads
6493
+ * as a failed load.
6494
+ *
6495
+ * Three properties hold BY CONSTRUCTION, which is why they are here in core
6496
+ * and not in whichever UI happens to render this:
6497
+ *
6498
+ * 1. **One key.** The payload is a SUBSET of the global schema, so a field
6499
+ * shown here is the same field, with the same bare key, that the addon's
6500
+ * own page shows. There is no integration-specific writer — callers save
6501
+ * through `updateGlobalSettings` — so a second store key is unreachable,
6502
+ * not merely discouraged.
6503
+ * 2. **No node scope.** `perNode: true` fields are DROPPED. Their store key
6504
+ * is `<key>@<nodeId>` and an integration is not a node; whichever node
6505
+ * such a field silently picked would be a wrong answer for the operator
6506
+ * who opened the page (D266).
6507
+ * 3. **No silent typo.** A declared id that names no section throws. The
6508
+ * alternative — skip it — turns a rename into a surface that quietly
6509
+ * empties, which looks exactly like an addon with nothing to configure.
6510
+ */
6511
+ async getIntegrationSettings(nodeId) {
6512
+ const declared = this.integrationSettingSections();
6513
+ if (declared.length === 0) return null;
6514
+ const schema = this.globalSettingsSchema();
6515
+ if (!schema) throw new Error(`${this.constructor.name}: integrationSettingSections() names [${declared.join(", ")}] but globalSettingsSchema() returns null.`);
6516
+ const byId = new Map(schema.sections.map((section) => [section.id, section]));
6517
+ const sections = [];
6518
+ for (const id of declared) {
6519
+ const section = byId.get(id);
6520
+ if (!section) throw new Error(`${this.constructor.name}: integrationSettingSections() names unknown section "${id}". Known sections: [${[...byId.keys()].join(", ")}].`);
6521
+ const fields = dropPerNodeFields(section.fields);
6522
+ if (fields.length === 0) continue;
6523
+ sections.push({
6524
+ ...section,
6525
+ fields
6526
+ });
6527
+ }
6528
+ if (sections.length === 0) return null;
6529
+ const projected = await this.resolveGlobalStore(nodeId);
6530
+ return hydrateSchema({
6531
+ ...schema,
6532
+ sections
6533
+ }, projected);
6534
+ }
6535
+ /**
6453
6536
  * The raw addon store PROJECTED onto the target node's bare per-node keys:
6454
6537
  * every `perNode: true` field carries THAT node's scoped value on its bare
6455
6538
  * key (absent scoped key ⇒ key absent, so the schema `default` wins — no
@@ -6753,6 +6836,41 @@ var BaseAddon = class {
6753
6836
  * `hydrateSchema` does. Valueless structural fields (separator/info/…)
6754
6837
  * don't declare `perNode` and are excluded by the `in` narrowing.
6755
6838
  */
6839
+ /**
6840
+ * The same fields with every `perNode: true` one removed, recursing into layout
6841
+ * containers exactly as {@link collectPerNodeFieldKeys} does. A container left
6842
+ * with no child is dropped rather than rendered empty.
6843
+ *
6844
+ * Used by `getIntegrationSettings`: an integration is not a node, so a field
6845
+ * whose store key is `<key>@<nodeId>` has no node to belong to there.
6846
+ */
6847
+ function dropPerNodeFields(fields) {
6848
+ const kept = [];
6849
+ for (const field of fields) {
6850
+ if (field.type === "group") {
6851
+ const inner = dropPerNodeFields(field.fields);
6852
+ if (inner.length > 0) kept.push({
6853
+ ...field,
6854
+ fields: inner
6855
+ });
6856
+ continue;
6857
+ }
6858
+ if (field.type === "sub-tabs") {
6859
+ const tabs = field.tabs.map((tab) => ({
6860
+ ...tab,
6861
+ fields: dropPerNodeFields(tab.fields)
6862
+ })).filter((tab) => tab.fields.length > 0);
6863
+ if (tabs.length > 0) kept.push({
6864
+ ...field,
6865
+ tabs
6866
+ });
6867
+ continue;
6868
+ }
6869
+ if ("perNode" in field && field.perNode === true) continue;
6870
+ kept.push(field);
6871
+ }
6872
+ return kept;
6873
+ }
6756
6874
  function collectPerNodeFieldKeys(fields) {
6757
6875
  const collected = [];
6758
6876
  for (const field of fields) {
@@ -9983,6 +10101,9 @@ method(object({
9983
10101
  kind: "mutation",
9984
10102
  auth: "admin"
9985
10103
  }), method(object({
10104
+ addonId: string(),
10105
+ nodeId: string().optional()
10106
+ }), SettingsSchemaWithValuesSchema.nullable()), method(object({
9986
10107
  addonId: string(),
9987
10108
  deviceId: number(),
9988
10109
  nodeId: string().optional()
@@ -28421,6 +28542,12 @@ Object.freeze({
28421
28542
  addonId: null,
28422
28543
  access: "view"
28423
28544
  },
28545
+ "addonSettings.getIntegrationSettings": {
28546
+ capName: "addon-settings",
28547
+ capScope: "system",
28548
+ addonId: null,
28549
+ access: "view"
28550
+ },
28424
28551
  "addonSettings.updateDeviceSettings": {
28425
28552
  capName: "addon-settings",
28426
28553
  capScope: "system",
@@ -6419,6 +6419,40 @@ var BaseAddon = class {
6419
6419
  deviceSettingsSchema() {
6420
6420
  return null;
6421
6421
  }
6422
+ /**
6423
+ * INTEGRATION-LEVEL SETTINGS — declare which of this addon's global sections
6424
+ * ARE the configuration of its integration.
6425
+ *
6426
+ * Return the `ConfigSection.id`s, from {@link globalSettingsSchema}, that an
6427
+ * operator should find on the addon's integration page (System →
6428
+ * Integrations → <name>) rather than only in the cluster-wide list of every
6429
+ * addon. Empty (the default) means the addon has no integration-level
6430
+ * settings and no such surface is offered — this is opt-in, because whether
6431
+ * an addon's configuration IS its integration's configuration depends on the
6432
+ * nature of the integration.
6433
+ *
6434
+ * WHAT THIS IS NOT. It is not a scope. The selected sections keep living in
6435
+ * the ONE global schema, in the ONE addon store, written by the ONE
6436
+ * `updateGlobalSettings` path. There is deliberately no
6437
+ * `updateIntegrationSettings`: a second write path is how a surface acquires
6438
+ * a second store key, and this repo has shipped that twice (`btmPath@hub`,
6439
+ * D266). Selecting sections cannot introduce a key that selecting cannot.
6440
+ *
6441
+ * WHY IT IS A LIST OF SECTION IDS AND NOT A MARKER ON THE SECTION.
6442
+ * `ConfigFieldBase` used to carry `scope?: 'device' | 'global'` and it was
6443
+ * removed with the reason recorded at
6444
+ * `packages/types/src/interfaces/config-ui.ts:249` — *"a field's scope is
6445
+ * determined by WHICH schema it lives in, not by a field-level marker."* A
6446
+ * marker sprinkled across sections also has to borrow a field that already
6447
+ * means something else; borrowing `section.tab` put the literal word
6448
+ * "integration" into an operator-facing tab bar, because `tab` means "how to
6449
+ * GROUP this visually" and cannot also mean "where this lives" (D269
6450
+ * supersedes D268). One declaration, in one place, next to the schema whose
6451
+ * ids it names.
6452
+ */
6453
+ integrationSettingSections() {
6454
+ return [];
6455
+ }
6422
6456
  async getGlobalSettings(overlay, cap, nodeId) {
6423
6457
  const schema = this.globalSettingsSchema(cap);
6424
6458
  if (!schema) return { sections: [] };
@@ -6429,6 +6463,55 @@ var BaseAddon = class {
6429
6463
  } : projected);
6430
6464
  }
6431
6465
  /**
6466
+ * The integration-level view of this addon's settings: exactly the sections
6467
+ * named by {@link integrationSettingSections}, hydrated from the SAME store
6468
+ * `getGlobalSettings` reads, and narrowed to cluster-scoped fields.
6469
+ *
6470
+ * Returns `null` when the addon declared nothing — an addon that opts out has
6471
+ * no integration settings surface at all, rather than an empty one that reads
6472
+ * as a failed load.
6473
+ *
6474
+ * Three properties hold BY CONSTRUCTION, which is why they are here in core
6475
+ * and not in whichever UI happens to render this:
6476
+ *
6477
+ * 1. **One key.** The payload is a SUBSET of the global schema, so a field
6478
+ * shown here is the same field, with the same bare key, that the addon's
6479
+ * own page shows. There is no integration-specific writer — callers save
6480
+ * through `updateGlobalSettings` — so a second store key is unreachable,
6481
+ * not merely discouraged.
6482
+ * 2. **No node scope.** `perNode: true` fields are DROPPED. Their store key
6483
+ * is `<key>@<nodeId>` and an integration is not a node; whichever node
6484
+ * such a field silently picked would be a wrong answer for the operator
6485
+ * who opened the page (D266).
6486
+ * 3. **No silent typo.** A declared id that names no section throws. The
6487
+ * alternative — skip it — turns a rename into a surface that quietly
6488
+ * empties, which looks exactly like an addon with nothing to configure.
6489
+ */
6490
+ async getIntegrationSettings(nodeId) {
6491
+ const declared = this.integrationSettingSections();
6492
+ if (declared.length === 0) return null;
6493
+ const schema = this.globalSettingsSchema();
6494
+ if (!schema) throw new Error(`${this.constructor.name}: integrationSettingSections() names [${declared.join(", ")}] but globalSettingsSchema() returns null.`);
6495
+ const byId = new Map(schema.sections.map((section) => [section.id, section]));
6496
+ const sections = [];
6497
+ for (const id of declared) {
6498
+ const section = byId.get(id);
6499
+ if (!section) throw new Error(`${this.constructor.name}: integrationSettingSections() names unknown section "${id}". Known sections: [${[...byId.keys()].join(", ")}].`);
6500
+ const fields = dropPerNodeFields(section.fields);
6501
+ if (fields.length === 0) continue;
6502
+ sections.push({
6503
+ ...section,
6504
+ fields
6505
+ });
6506
+ }
6507
+ if (sections.length === 0) return null;
6508
+ const projected = await this.resolveGlobalStore(nodeId);
6509
+ return hydrateSchema({
6510
+ ...schema,
6511
+ sections
6512
+ }, projected);
6513
+ }
6514
+ /**
6432
6515
  * The raw addon store PROJECTED onto the target node's bare per-node keys:
6433
6516
  * every `perNode: true` field carries THAT node's scoped value on its bare
6434
6517
  * key (absent scoped key ⇒ key absent, so the schema `default` wins — no
@@ -6732,6 +6815,41 @@ var BaseAddon = class {
6732
6815
  * `hydrateSchema` does. Valueless structural fields (separator/info/…)
6733
6816
  * don't declare `perNode` and are excluded by the `in` narrowing.
6734
6817
  */
6818
+ /**
6819
+ * The same fields with every `perNode: true` one removed, recursing into layout
6820
+ * containers exactly as {@link collectPerNodeFieldKeys} does. A container left
6821
+ * with no child is dropped rather than rendered empty.
6822
+ *
6823
+ * Used by `getIntegrationSettings`: an integration is not a node, so a field
6824
+ * whose store key is `<key>@<nodeId>` has no node to belong to there.
6825
+ */
6826
+ function dropPerNodeFields(fields) {
6827
+ const kept = [];
6828
+ for (const field of fields) {
6829
+ if (field.type === "group") {
6830
+ const inner = dropPerNodeFields(field.fields);
6831
+ if (inner.length > 0) kept.push({
6832
+ ...field,
6833
+ fields: inner
6834
+ });
6835
+ continue;
6836
+ }
6837
+ if (field.type === "sub-tabs") {
6838
+ const tabs = field.tabs.map((tab) => ({
6839
+ ...tab,
6840
+ fields: dropPerNodeFields(tab.fields)
6841
+ })).filter((tab) => tab.fields.length > 0);
6842
+ if (tabs.length > 0) kept.push({
6843
+ ...field,
6844
+ tabs
6845
+ });
6846
+ continue;
6847
+ }
6848
+ if ("perNode" in field && field.perNode === true) continue;
6849
+ kept.push(field);
6850
+ }
6851
+ return kept;
6852
+ }
6735
6853
  function collectPerNodeFieldKeys(fields) {
6736
6854
  const collected = [];
6737
6855
  for (const field of fields) {
@@ -9962,6 +10080,9 @@ method(object({
9962
10080
  kind: "mutation",
9963
10081
  auth: "admin"
9964
10082
  }), method(object({
10083
+ addonId: string(),
10084
+ nodeId: string().optional()
10085
+ }), SettingsSchemaWithValuesSchema.nullable()), method(object({
9965
10086
  addonId: string(),
9966
10087
  deviceId: number(),
9967
10088
  nodeId: string().optional()
@@ -28400,6 +28521,12 @@ Object.freeze({
28400
28521
  addonId: null,
28401
28522
  access: "view"
28402
28523
  },
28524
+ "addonSettings.getIntegrationSettings": {
28525
+ capName: "addon-settings",
28526
+ capScope: "system",
28527
+ addonId: null,
28528
+ access: "view"
28529
+ },
28403
28530
  "addonSettings.updateDeviceSettings": {
28404
28531
  capName: "addon-settings",
28405
28532
  capScope: "system",
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DOi9vT32.mjs";
1
+ import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-CZmB5SRo.mjs";
2
2
  export { t as get, e as init };
@@ -2753,7 +2753,7 @@ async function rr(e) {
2753
2753
  }
2754
2754
  }
2755
2755
  async function ir() {
2756
- return tr ||= rr(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-Co3sb2DR.mjs")).catch((e) => {
2756
+ return tr ||= rr(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-DCDHH2z9.mjs")).catch((e) => {
2757
2757
  throw tr = void 0, e;
2758
2758
  }), tr;
2759
2759
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-model-studio",
3
- "version": "1.1.51",
3
+ "version": "1.1.52",
4
4
  "description": "Custom detection model registry, conversion & distribution for CamStack",
5
5
  "keywords": [
6
6
  "camstack",