@camstack/types 1.2.442 → 1.2.443
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/CHANGELOG.md +12 -0
- package/dist/addon.js +1 -1
- package/dist/addon.mjs +1 -1
- package/dist/capabilities/index.d.ts +4 -1
- package/dist/capabilities/node-removal-hook.cap.d.ts +67 -0
- package/dist/capabilities/pipeline-orchestrator.cap.d.ts +1 -2
- package/dist/generated/addon-api.d.ts +15 -0
- package/dist/generated/capability-router-map.d.ts +5 -2
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/index.js +190 -6
- package/dist/index.mjs +188 -7
- package/dist/{sleep-DJws6ho7.mjs → sleep-C_u6cEAJ.mjs} +1 -0
- package/dist/{sleep-BpwNJ1Su.js → sleep-E7qAQwTE.js} +1 -0
- package/dist/types/agent-pipeline-settings.d.ts +2 -2
- package/dist/utils/oauth-landing.d.ts +1 -1
- package/dist/vendor-login-proxy/flow-trace.d.ts +29 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.2.443] - 2026-10-29
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- The vendor login proxy writes a names-only trace line per proxied sign-in request (parameter, form-field and cookie names, never values) to show where a sign-in loses a parameter
|
|
15
|
+
- Added the no_authorization_code reason to the OAuth result page codes
|
|
16
|
+
- Comments on the placement flags now say a role defaults on for every node
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- A node-removal-hook capability: addons are told when the operator forgets a cluster node
|
|
21
|
+
|
|
10
22
|
## [1.2.442] - 2026-10-29
|
|
11
23
|
|
|
12
24
|
### Changed
|
package/dist/addon.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_sleep = require("./sleep-
|
|
2
|
+
const require_sleep = require("./sleep-E7qAQwTE.js");
|
|
3
3
|
const require_event_category = require("./event-category-E17zaHjN.js");
|
|
4
4
|
const require_err_msg = require("./err-msg-COHgq7Mb.js");
|
|
5
5
|
//#region src/generated/cap-input-defaults.ts
|
package/dist/addon.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as expandCapMethods, $n as REVALIDATE_AFTER_MS, $r as isSecretMarker, $t as RecordFieldPathSchema, A as HF_REPO, An as RecordUniqueViolationError, Ar as buildSecretRef, B as withoutCallerStamp, Bn as RECORD_CLASSES, C as addonSliceHandleApi, Cn as InvalidRecordError, Dn as RecordNotFoundError, En as RECORDS_ERROR_CODES, Fn as UnknownRecordKindError, Fr as parseSecretRef, G as adminUiCapability, Gn as RECORD_MAX_DATA_BYTES, Hn as RECORD_DEFAULT_MAX_DATA_BYTES, I as deviceOpsCapability, In as asRecordsError, Jn as RECORD_QUERY_MAX, Jt as defineEntryKind, Kn as RECORD_MAX_INDEXES, L as viewerUiCapability, Ln as recordsErrorFromMessage, M as CAP_ADVANCE_FIELDS, Mn as RevConflictError, Mr as globalSecretScope, Nn as TransactRefusedError, Nr as isSecretRef, On as RecordSecretUnavailableError, Or as SECRET_REF_SCHEME, P as CAP_STATE_LEAVES, Pn as UnindexedFilterError, Pr as normalizeSecretOwner, Qn as resolveSecretViewsIn, Qr as isSecretFieldView, Qt as EntryDescriptorSchema, R as DEVICE_CHILDREN_BATCH_MAX, Rn as RECORD_BATCH_MAX, Rr as createEvent, Sn as ForeignSecretMarkerError, Tn as PlaintextSecretError, U as describeCustomActions, Un as RECORD_DELETE_BATCH, Vn as RECORD_DATABASES, Wn as RECORD_ID_MAX_LENGTH, Xn as RECORD_SETTINGS_MAX_ROWS, Xr as classifySecretWrite, Xt as createRecordsAccess, Yn as RECORD_SECRET_COLLECTION_PREFIX, Yr as SECRET_CLEAR, Yt as entryBody, Zn as RECORD_SWEEP_INTERVAL_MS, Zr as isSecretClear, Zt as assertTransactScope, _ as readErrorI18n, _n as collectZodSecretPaths, an as assertValidDeclaration, ar as registerKnownSecret, b as isDeviceScopedCap, bn as DeclarationRefusedError, c as asString, cn as REMOVE_LEAF, cr as PEER_BYTES_CHUNK_BYTES, ct as readNodePin, d as parseJsonUnknown, dn as parseSecretPath, dr as PEER_BYTES_TICKET_TTL_MS, dt as ReadinessRegistry, ei as isSecretMarkerLike, en as RecordIndexSchema, er as createSecretsAccess, f as hfModelUrl, fn as recordArrayItemPath, ft as ReadinessTimeoutError, g as ErrorI18nPayloadSchema, gr as BaseAddon, hn as secretArrayPrefixes, hr as DisposerChain, ht as scopeKey, in as StoredRecordKindDeclarationSchema, ir as knownSecretCount, jn as RecordsError, jr as formatSecretScope, kn as RecordTooLargeError, kr as arrayItemFieldPath, ln as collectSecretLeaves, lr as PEER_BYTES_MAX_OUTSTANDING, mn as recordSecretRef, ni as toSecretFieldView, nn as RecordKindNameSchema, nr as clearKnownSecrets, o as asJsonObject, on as declarationsOf, or as scrubKnownSecrets, p as BOOT_RECOVERY_BACKOFF_MS, pn as recordSecretCollection, pr as DATAPLANE_SECRET_HEADER, qn as RECORD_MAX_INDEX_FIELDS, qt as makeInMemoryRecords, r as maskUrlCredentials, rn as RecordRetentionSchema, rr as forgetKnownSecret, sn as defineRecordKinds, sr as shortSecretRefHash, st as nodePin, t as sleep, ti as makeSecretMarker, tn as RecordKindDeclarationSchema, tr as MIN_SCRUBBED_LENGTH, un as mapSecretLeaves, ur as PEER_BYTES_STALL_MS, ut as MODEL_FORMATS, vn as isZodSecret, vr as normalizeAddonInitResult, w as createEventBusSliceSource, wn as NoCallerError, x as createDeviceProxy, xn as FilterRequiredError, y as DEVICE_SCOPED_CAPS, yn as BatchTooLargeError, z as CALLER_STAMPED_CAPABILITIES, zn as RECORD_BATCH_MAX_BYTES, zr as emitReadiness } from "./sleep-
|
|
1
|
+
import { $ as expandCapMethods, $n as REVALIDATE_AFTER_MS, $r as isSecretMarker, $t as RecordFieldPathSchema, A as HF_REPO, An as RecordUniqueViolationError, Ar as buildSecretRef, B as withoutCallerStamp, Bn as RECORD_CLASSES, C as addonSliceHandleApi, Cn as InvalidRecordError, Dn as RecordNotFoundError, En as RECORDS_ERROR_CODES, Fn as UnknownRecordKindError, Fr as parseSecretRef, G as adminUiCapability, Gn as RECORD_MAX_DATA_BYTES, Hn as RECORD_DEFAULT_MAX_DATA_BYTES, I as deviceOpsCapability, In as asRecordsError, Jn as RECORD_QUERY_MAX, Jt as defineEntryKind, Kn as RECORD_MAX_INDEXES, L as viewerUiCapability, Ln as recordsErrorFromMessage, M as CAP_ADVANCE_FIELDS, Mn as RevConflictError, Mr as globalSecretScope, Nn as TransactRefusedError, Nr as isSecretRef, On as RecordSecretUnavailableError, Or as SECRET_REF_SCHEME, P as CAP_STATE_LEAVES, Pn as UnindexedFilterError, Pr as normalizeSecretOwner, Qn as resolveSecretViewsIn, Qr as isSecretFieldView, Qt as EntryDescriptorSchema, R as DEVICE_CHILDREN_BATCH_MAX, Rn as RECORD_BATCH_MAX, Rr as createEvent, Sn as ForeignSecretMarkerError, Tn as PlaintextSecretError, U as describeCustomActions, Un as RECORD_DELETE_BATCH, Vn as RECORD_DATABASES, Wn as RECORD_ID_MAX_LENGTH, Xn as RECORD_SETTINGS_MAX_ROWS, Xr as classifySecretWrite, Xt as createRecordsAccess, Yn as RECORD_SECRET_COLLECTION_PREFIX, Yr as SECRET_CLEAR, Yt as entryBody, Zn as RECORD_SWEEP_INTERVAL_MS, Zr as isSecretClear, Zt as assertTransactScope, _ as readErrorI18n, _n as collectZodSecretPaths, an as assertValidDeclaration, ar as registerKnownSecret, b as isDeviceScopedCap, bn as DeclarationRefusedError, c as asString, cn as REMOVE_LEAF, cr as PEER_BYTES_CHUNK_BYTES, ct as readNodePin, d as parseJsonUnknown, dn as parseSecretPath, dr as PEER_BYTES_TICKET_TTL_MS, dt as ReadinessRegistry, ei as isSecretMarkerLike, en as RecordIndexSchema, er as createSecretsAccess, f as hfModelUrl, fn as recordArrayItemPath, ft as ReadinessTimeoutError, g as ErrorI18nPayloadSchema, gr as BaseAddon, hn as secretArrayPrefixes, hr as DisposerChain, ht as scopeKey, in as StoredRecordKindDeclarationSchema, ir as knownSecretCount, jn as RecordsError, jr as formatSecretScope, kn as RecordTooLargeError, kr as arrayItemFieldPath, ln as collectSecretLeaves, lr as PEER_BYTES_MAX_OUTSTANDING, mn as recordSecretRef, ni as toSecretFieldView, nn as RecordKindNameSchema, nr as clearKnownSecrets, o as asJsonObject, on as declarationsOf, or as scrubKnownSecrets, p as BOOT_RECOVERY_BACKOFF_MS, pn as recordSecretCollection, pr as DATAPLANE_SECRET_HEADER, qn as RECORD_MAX_INDEX_FIELDS, qt as makeInMemoryRecords, r as maskUrlCredentials, rn as RecordRetentionSchema, rr as forgetKnownSecret, sn as defineRecordKinds, sr as shortSecretRefHash, st as nodePin, t as sleep, ti as makeSecretMarker, tn as RecordKindDeclarationSchema, tr as MIN_SCRUBBED_LENGTH, un as mapSecretLeaves, ur as PEER_BYTES_STALL_MS, ut as MODEL_FORMATS, vn as isZodSecret, vr as normalizeAddonInitResult, w as createEventBusSliceSource, wn as NoCallerError, x as createDeviceProxy, xn as FilterRequiredError, y as DEVICE_SCOPED_CAPS, yn as BatchTooLargeError, z as CALLER_STAMPED_CAPABILITIES, zn as RECORD_BATCH_MAX_BYTES, zr as emitReadiness } from "./sleep-C_u6cEAJ.mjs";
|
|
2
2
|
import { t as EventCategory } from "./event-category-DmZDPDf_.mjs";
|
|
3
3
|
import { a as DeviceType, t as errMsg } from "./err-msg-BCdlR2Li.mjs";
|
|
4
4
|
//#region src/generated/cap-input-defaults.ts
|
|
@@ -70,6 +70,8 @@ export { DiscoveredDeviceSchema, deviceProviderCapability, ProviderStatusSchema,
|
|
|
70
70
|
export { type ClaimOutcome, ClaimOutcomeSchema, type ClaimsListing, ClaimsListingSchema, deviceStateCapability, type FieldClaim, type FieldClaimMode, FieldClaimModeSchema, FieldClaimSchema, } from './device-state.cap.js';
|
|
71
71
|
export type { EmbeddingFailedModel, EmbeddingFailedRequirement, EmbeddingModelFailure, EmbeddingRefusal, EmbeddingRefusalCode, EmbeddingTower, IEmbeddingEncoderProvider, } from './embedding-encoder.cap.js';
|
|
72
72
|
export { EMBEDDING_MODEL_FAILED, EMBEDDING_REQUIREMENTS_FAILED, EMBEDDING_REQUIREMENTS_UNAVAILABLE, EmbeddingFailedModelSchema, EmbeddingFailedRequirementSchema, EmbeddingInfoSchema, EmbeddingRefusalCodeSchema, EmbeddingResultSchema, EmbeddingTowerSchema, embeddingEncoderCapability, embeddingModelFailedError, embeddingModelFailedOf, embeddingRefusalOf, embeddingRequirementsFailedError, embeddingRequirementsUnavailableError, isEmbeddingModelFailed, } from './embedding-encoder.cap.js';
|
|
73
|
+
export type { INodeRemovalHookProvider, NodeRemovedInput, NodeRemovedResult, } from './node-removal-hook.cap.js';
|
|
74
|
+
export { NodeRemovedInputSchema, NodeRemovedResultSchema, nodeRemovalHookCapability, } from './node-removal-hook.cap.js';
|
|
73
75
|
export type { DeviceDataEntry, DeviceRemovedInput, DeviceRemovedResult, IDeviceRemovalHookProvider, } from './device-removal-hook.cap.js';
|
|
74
76
|
export { DeviceDataEntrySchema, DeviceRemovedInputSchema, DeviceRemovedResultSchema, deviceRemovalHookCapability, } from './device-removal-hook.cap.js';
|
|
75
77
|
export type { FailureContribution, IFailureContributionProvider, } from './failure-contribution.cap.js';
|
|
@@ -338,6 +340,7 @@ import type { deviceProviderCapability } from './device-provider.cap.js';
|
|
|
338
340
|
import type { deviceStateCapability } from './device-state.cap.js';
|
|
339
341
|
import type { deviceStatusCapability } from './device-status.cap.js';
|
|
340
342
|
import type { deviceRemovalHookCapability } from './device-removal-hook.cap.js';
|
|
343
|
+
import type { nodeRemovalHookCapability } from './node-removal-hook.cap.js';
|
|
341
344
|
import type { dishwasherCapability } from './dishwasher.cap.js';
|
|
342
345
|
import type { doorbellCapability } from './doorbell.cap.js';
|
|
343
346
|
import type { embeddingEncoderCapability } from './embedding-encoder.cap.js';
|
|
@@ -455,6 +458,6 @@ import type { trainingProviderCapability } from './training-provider.cap.js';
|
|
|
455
458
|
import type { zoneAnalyticsCapability } from './zone-analytics.cap.js';
|
|
456
459
|
import type { zoneRulesCapability } from './zone-rules.cap.js';
|
|
457
460
|
import type { zonesCapability } from './zones.cap.js';
|
|
458
|
-
type AnyCapability = typeof streamSignalsCapability | typeof addonSettingsCapability | typeof alertsCapability | typeof storageCapability | typeof storageMigrationCapability | typeof storageProviderCapability | typeof storageEvictableCapability | typeof storageOccupancyCapability | typeof filesystemBrowseCapability | typeof backupCapability | typeof terminalSessionCapability | typeof settingsStoreCapability | typeof dataStoreProviderCapability | typeof databaseSnapshotCapability | typeof storageAdminCapability | typeof recordsCapability | typeof recordEntriesCapability | typeof deviceHistoryCapability | typeof keychainCapability | typeof keychainAdminCapability | typeof deviceCredentialsCapability | typeof nodeCertificatesCapability | typeof logChannelsCapability | typeof logDestinationCapability | typeof loadContributionCapability | typeof failureContributionCapability | typeof deviceRemovalHookCapability | typeof adminUiCapability | typeof viewerUiCapability | typeof ssoBridgeCapability | typeof userPasskeysCapability | typeof smtpProviderCapability | typeof mqttBrokerCapability | typeof brokerCapability | typeof deviceAdoptionCapability | typeof deviceAdminLinkCapability | typeof deviceExportCapability | typeof addonPagesCapability | typeof addonPagesSourceCapability | typeof addonWidgetsCapability | typeof addonWidgetsSourceCapability | typeof customModelRegistryCapability | typeof modelDistributorCapability | typeof modelConvertCapability | typeof addonRoutesCapability | typeof streamBrokerCapability | typeof decoderCapability | typeof webrtcSessionCapability | typeof cameraStreamsCapability | typeof calendarSourceCapability | typeof calendarsCapability | typeof motionDetectionCapability | typeof pipelineExecutorCapability | typeof detectionPipelineCapability | typeof cameraPipelineConfigCapability | typeof pipelineRunnerCapability | typeof pipelineOrchestratorCapability | typeof audioAnalyzerCapability | typeof audioAnalysisCapability | typeof audioCodecCapability | typeof embeddingEncoderCapability | typeof vectorStoreCapability | typeof deviceProviderCapability | typeof deviceManagerCapability | typeof deviceStateCapability | typeof authProviderCapability | typeof loginMethodCapability | typeof networkAccessCapability | typeof turnProviderCapability | typeof snapshotCapability | typeof llmCapability | typeof llmRuntimeCapability | typeof notificationOutputCapability | typeof composerCapability | typeof coreBlocksCapability | typeof notificationRulesCapability | typeof pipelineAnalyticsCapability | typeof metricsProviderCapability | typeof ptzCapability | typeof ptzAutotrackCapability | typeof navigationCapability | typeof consumablesCapability | typeof connectionTestCapability | typeof runningStateCapability | typeof rebootCapability | typeof deviceDiscoveryCapability | typeof brightnessCapability | typeof colorCapability | typeof climateControlCapability | typeof coverCapability | typeof valveCapability | typeof humidifierCapability | typeof waterHeaterCapability | typeof weatherCapability | typeof imageCapability | typeof lockControlCapability | typeof vacuumControlCapability | typeof petFeederCapability | typeof lawnMowerControlCapability | typeof fanControlCapability | typeof controlCapability | typeof notifierCapability | typeof mediaPlayerCapability | typeof meterCapability | typeof alarmPanelCapability | typeof presenceCapability | typeof scriptRunnerCapability | typeof actionSourceCapability | typeof actionsCapability | typeof automationControlCapability | typeof motionTriggerCapability | typeof zonesCapability | typeof zoneRulesCapability | typeof trainingCapability | typeof trainingProviderCapability | typeof zoneAnalyticsCapability | typeof audioMetricsCapability | typeof motionCapability | typeof contactCapability | typeof floodCapability | typeof smokeCapability | typeof carbonMonoxideCapability | typeof gasCapability | typeof groupActiveCapability | typeof groupCommandsCapability | typeof groupStatusCapability | typeof tamperCapability | typeof vibrationCapability | typeof connectivityCapability | typeof binaryCapability | typeof temperatureSensorCapability | typeof heatingValveCapability | typeof humiditySensorCapability | typeof ambientLightSensorCapability | typeof pressureSensorCapability | typeof powerMeterCapability | typeof airQualitySensorCapability | typeof numericSensorCapability | typeof enumSensorCapability | typeof recordingCapability | typeof recordingArchiveCapability | typeof recordingExportCapability | typeof recordingSignalCapability | typeof deviceOpsCapability | typeof displayPaletteCapability | typeof platformProbeCapability | typeof localNetworkCapability | typeof meshNetworkCapability | typeof userManagementCapability | typeof systemCapability | typeof networkQualityCapability | typeof toastCapability | typeof nodesCapability | typeof serverManagementCapability | typeof integrationsCapability | typeof addonsCapability | typeof oauthIntegrationCapability | typeof oidcConnectionsCapability | typeof streamParamsCapability | typeof streamCatalogCapability | typeof motionZonesCapability | typeof cameraGridLayoutCapability | typeof sceneMonitorCapability | typeof privacyMaskCapability | typeof dayNightCapability | typeof recordingOnboardCapability | typeof imageSettingsCapability | typeof osdCapability | typeof osdManagerCapability | typeof accessoriesCapability | typeof batteryCapability | typeof networkLinkCapability | typeof buttonCapability | typeof irTransmitterCapability | typeof remoteCapability | typeof templateCapability | typeof cameraCredentialsCapability | typeof deviceStatusCapability | typeof doorbellCapability | typeof eventEmitterCapability | typeof faceGalleryCapability | typeof featureProbeCapability | typeof intercomCapability | typeof nativeObjectDetectionCapability | typeof plateGalleryCapability | typeof switchCapability | typeof updateCapability | typeof videoclipsCapability | typeof deviceExtensionCapability | typeof dishwasherCapability;
|
|
461
|
+
type AnyCapability = typeof streamSignalsCapability | typeof addonSettingsCapability | typeof alertsCapability | typeof storageCapability | typeof storageMigrationCapability | typeof storageProviderCapability | typeof storageEvictableCapability | typeof storageOccupancyCapability | typeof filesystemBrowseCapability | typeof backupCapability | typeof terminalSessionCapability | typeof settingsStoreCapability | typeof dataStoreProviderCapability | typeof databaseSnapshotCapability | typeof storageAdminCapability | typeof recordsCapability | typeof recordEntriesCapability | typeof deviceHistoryCapability | typeof keychainCapability | typeof keychainAdminCapability | typeof deviceCredentialsCapability | typeof nodeCertificatesCapability | typeof logChannelsCapability | typeof logDestinationCapability | typeof loadContributionCapability | typeof failureContributionCapability | typeof deviceRemovalHookCapability | typeof nodeRemovalHookCapability | typeof adminUiCapability | typeof viewerUiCapability | typeof ssoBridgeCapability | typeof userPasskeysCapability | typeof smtpProviderCapability | typeof mqttBrokerCapability | typeof brokerCapability | typeof deviceAdoptionCapability | typeof deviceAdminLinkCapability | typeof deviceExportCapability | typeof addonPagesCapability | typeof addonPagesSourceCapability | typeof addonWidgetsCapability | typeof addonWidgetsSourceCapability | typeof customModelRegistryCapability | typeof modelDistributorCapability | typeof modelConvertCapability | typeof addonRoutesCapability | typeof streamBrokerCapability | typeof decoderCapability | typeof webrtcSessionCapability | typeof cameraStreamsCapability | typeof calendarSourceCapability | typeof calendarsCapability | typeof motionDetectionCapability | typeof pipelineExecutorCapability | typeof detectionPipelineCapability | typeof cameraPipelineConfigCapability | typeof pipelineRunnerCapability | typeof pipelineOrchestratorCapability | typeof audioAnalyzerCapability | typeof audioAnalysisCapability | typeof audioCodecCapability | typeof embeddingEncoderCapability | typeof vectorStoreCapability | typeof deviceProviderCapability | typeof deviceManagerCapability | typeof deviceStateCapability | typeof authProviderCapability | typeof loginMethodCapability | typeof networkAccessCapability | typeof turnProviderCapability | typeof snapshotCapability | typeof llmCapability | typeof llmRuntimeCapability | typeof notificationOutputCapability | typeof composerCapability | typeof coreBlocksCapability | typeof notificationRulesCapability | typeof pipelineAnalyticsCapability | typeof metricsProviderCapability | typeof ptzCapability | typeof ptzAutotrackCapability | typeof navigationCapability | typeof consumablesCapability | typeof connectionTestCapability | typeof runningStateCapability | typeof rebootCapability | typeof deviceDiscoveryCapability | typeof brightnessCapability | typeof colorCapability | typeof climateControlCapability | typeof coverCapability | typeof valveCapability | typeof humidifierCapability | typeof waterHeaterCapability | typeof weatherCapability | typeof imageCapability | typeof lockControlCapability | typeof vacuumControlCapability | typeof petFeederCapability | typeof lawnMowerControlCapability | typeof fanControlCapability | typeof controlCapability | typeof notifierCapability | typeof mediaPlayerCapability | typeof meterCapability | typeof alarmPanelCapability | typeof presenceCapability | typeof scriptRunnerCapability | typeof actionSourceCapability | typeof actionsCapability | typeof automationControlCapability | typeof motionTriggerCapability | typeof zonesCapability | typeof zoneRulesCapability | typeof trainingCapability | typeof trainingProviderCapability | typeof zoneAnalyticsCapability | typeof audioMetricsCapability | typeof motionCapability | typeof contactCapability | typeof floodCapability | typeof smokeCapability | typeof carbonMonoxideCapability | typeof gasCapability | typeof groupActiveCapability | typeof groupCommandsCapability | typeof groupStatusCapability | typeof tamperCapability | typeof vibrationCapability | typeof connectivityCapability | typeof binaryCapability | typeof temperatureSensorCapability | typeof heatingValveCapability | typeof humiditySensorCapability | typeof ambientLightSensorCapability | typeof pressureSensorCapability | typeof powerMeterCapability | typeof airQualitySensorCapability | typeof numericSensorCapability | typeof enumSensorCapability | typeof recordingCapability | typeof recordingArchiveCapability | typeof recordingExportCapability | typeof recordingSignalCapability | typeof deviceOpsCapability | typeof displayPaletteCapability | typeof platformProbeCapability | typeof localNetworkCapability | typeof meshNetworkCapability | typeof userManagementCapability | typeof systemCapability | typeof networkQualityCapability | typeof toastCapability | typeof nodesCapability | typeof serverManagementCapability | typeof integrationsCapability | typeof addonsCapability | typeof oauthIntegrationCapability | typeof oidcConnectionsCapability | typeof streamParamsCapability | typeof streamCatalogCapability | typeof motionZonesCapability | typeof cameraGridLayoutCapability | typeof sceneMonitorCapability | typeof privacyMaskCapability | typeof dayNightCapability | typeof recordingOnboardCapability | typeof imageSettingsCapability | typeof osdCapability | typeof osdManagerCapability | typeof accessoriesCapability | typeof batteryCapability | typeof networkLinkCapability | typeof buttonCapability | typeof irTransmitterCapability | typeof remoteCapability | typeof templateCapability | typeof cameraCredentialsCapability | typeof deviceStatusCapability | typeof doorbellCapability | typeof eventEmitterCapability | typeof faceGalleryCapability | typeof featureProbeCapability | typeof intercomCapability | typeof nativeObjectDetectionCapability | typeof plateGalleryCapability | typeof switchCapability | typeof updateCapability | typeof videoclipsCapability | typeof deviceExtensionCapability | typeof dishwasherCapability;
|
|
459
462
|
export type CapabilityName = AnyCapability['name'];
|
|
460
463
|
export type ITypedReadinessRegistry = IReadinessRegistry<CapabilityName>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `node-removal-hook` — the reliable way an addon learns a cluster node was
|
|
3
|
+
* FORGOTTEN, so it can remove or re-point what it keeps for that node. The
|
|
4
|
+
* node-scoped twin of `device-removal-hook` (D865); same shape, same rules.
|
|
5
|
+
*
|
|
6
|
+
* ## Why not "the node is absent"
|
|
7
|
+
*
|
|
8
|
+
* A node missing from topology is offline, restarting or not yet re-registered —
|
|
9
|
+
* it is not forgotten. Deleting node-scoped data from absence destroys a live
|
|
10
|
+
* node's configuration on any failed or partial read (D49). So the hook is
|
|
11
|
+
* driven by a TOMBSTONE the hub records when the operator forgets a node
|
|
12
|
+
* (`AgentRegistryService.forgetClusterNode`); nothing else produces one.
|
|
13
|
+
*
|
|
14
|
+
* ## The pieces
|
|
15
|
+
*
|
|
16
|
+
* 1. The hub records a tombstone `{ nodeId, removedAt, pending }` before it calls
|
|
17
|
+
* anyone. `pending` is the set of implementers that have not yet acknowledged.
|
|
18
|
+
* 2. The hub calls `onNodeRemoved` on EVERY provider of this collection, one by
|
|
19
|
+
* one, with bounded retries, logged; an acknowledgement removes the
|
|
20
|
+
* implementer from `pending`.
|
|
21
|
+
* 3. The hub re-drives still-pending tombstones at boot, so an implementer that
|
|
22
|
+
* was down at forget time is told when it is back.
|
|
23
|
+
*
|
|
24
|
+
* ## Contract for an implementer
|
|
25
|
+
*
|
|
26
|
+
* - **Idempotent.** Called again by a retry and by the boot re-drive. A node with
|
|
27
|
+
* nothing left answers zero counts.
|
|
28
|
+
* - **One key per store** in `counts`, rows changed per store, so the log line
|
|
29
|
+
* can say where the data was.
|
|
30
|
+
* - **Re-point or remove, never guess.** A row that merely MENTIONS the node as
|
|
31
|
+
* a preference is re-pointed to "unset"; a row that only means something on
|
|
32
|
+
* that node (a runtime bound to it) is removed.
|
|
33
|
+
* - A provider that cannot tell is allowed to throw; the caller retries it.
|
|
34
|
+
*/
|
|
35
|
+
import { z } from 'zod';
|
|
36
|
+
import { type InferProvider } from './capability-definition.js';
|
|
37
|
+
/** What a hook is told about the removal. */
|
|
38
|
+
export declare const NodeRemovedInputSchema: z.ZodObject<{
|
|
39
|
+
nodeId: z.ZodString;
|
|
40
|
+
removedAt: z.ZodNumber;
|
|
41
|
+
}, z.core.$strip>;
|
|
42
|
+
export type NodeRemovedInput = z.infer<typeof NodeRemovedInputSchema>;
|
|
43
|
+
/** Rows changed (removed or re-pointed), per store this implementer owns. */
|
|
44
|
+
export declare const NodeRemovedResultSchema: z.ZodObject<{
|
|
45
|
+
counts: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
46
|
+
}, z.core.$strip>;
|
|
47
|
+
export type NodeRemovedResult = z.infer<typeof NodeRemovedResultSchema>;
|
|
48
|
+
export declare const nodeRemovalHookCapability: {
|
|
49
|
+
readonly name: 'node-removal-hook';
|
|
50
|
+
readonly scope: 'system';
|
|
51
|
+
readonly mode: 'collection';
|
|
52
|
+
readonly internal: true;
|
|
53
|
+
readonly methods: {
|
|
54
|
+
/** Remove or re-point everything this addon keeps for the forgotten node. Idempotent. */
|
|
55
|
+
readonly onNodeRemoved: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
56
|
+
nodeId: z.ZodString;
|
|
57
|
+
removedAt: z.ZodNumber;
|
|
58
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
59
|
+
counts: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
60
|
+
}, z.core.$strip>, "mutation">;
|
|
61
|
+
};
|
|
62
|
+
/** In-process only — enumerated through `addons.listCapabilityProviders`. */
|
|
63
|
+
readonly mount: {
|
|
64
|
+
readonly kind: 'skip';
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
export type INodeRemovalHookProvider = InferProvider<typeof nodeRemovalHookCapability>;
|
|
@@ -1164,8 +1164,7 @@ export declare const pipelineOrchestratorCapability: {
|
|
|
1164
1164
|
* replaced the four flat orchestrator lists (`enabledNodes`,
|
|
1165
1165
|
* `enabledDecoderNodes`, `enabledAudioNodes`, `remoteSourcingNodes`).
|
|
1166
1166
|
* Each flag is optional in the patch: omit a flag to leave it unchanged,
|
|
1167
|
-
* pass `null` to reset it to the
|
|
1168
|
-
* other node → not). Detection/audio eligibility is derived from these
|
|
1167
|
+
* pass `null` to reset it to the default (ON for every node). Detection/audio eligibility is derived from these
|
|
1169
1168
|
* flags across the cluster; changing them re-derives the enabled sets
|
|
1170
1169
|
* and reconciles dispatch immediately. There is NO separate decode flag:
|
|
1171
1170
|
* decode is always co-located with its frame consumer, so decode
|
|
@@ -91,6 +91,7 @@ import type { navigationCapability } from '../capabilities/navigation.cap.js';
|
|
|
91
91
|
import type { networkAccessCapability } from '../capabilities/network-access.cap.js';
|
|
92
92
|
import type { networkQualityCapability } from '../capabilities/network-quality.cap.js';
|
|
93
93
|
import type { nodeCertificatesCapability } from '../capabilities/node-certificates.cap.js';
|
|
94
|
+
import type { nodeRemovalHookCapability } from '../capabilities/node-removal-hook.cap.js';
|
|
94
95
|
import type { nodesCapability } from '../capabilities/nodes.cap.js';
|
|
95
96
|
import type { notificationOutputCapability } from '../capabilities/notification-output.cap.js';
|
|
96
97
|
import type { notificationRulesCapability } from '../capabilities/notification-rules.cap.js';
|
|
@@ -5694,6 +5695,20 @@ export type AppRouter = TrpcCoreRouter<{
|
|
|
5694
5695
|
meta: object;
|
|
5695
5696
|
}>;
|
|
5696
5697
|
}>>;
|
|
5698
|
+
nodeRemovalHook: TRPCBuiltRouter<{
|
|
5699
|
+
ctx: TrpcContext;
|
|
5700
|
+
meta: object;
|
|
5701
|
+
errorShape: AugmentedErrorShape;
|
|
5702
|
+
transformer: true;
|
|
5703
|
+
}, TRPCDecorateCreateRouterOptions<{
|
|
5704
|
+
onNodeRemoved: TRPCMutationProcedure<{
|
|
5705
|
+
input: {
|
|
5706
|
+
[x: string]: unknown;
|
|
5707
|
+
} & z.input<typeof nodeRemovalHookCapability.methods.onNodeRemoved.input>;
|
|
5708
|
+
output: z.infer<typeof nodeRemovalHookCapability.methods.onNodeRemoved.output>;
|
|
5709
|
+
meta: object;
|
|
5710
|
+
}>;
|
|
5711
|
+
}>>;
|
|
5697
5712
|
nodes: TRPCBuiltRouter<{
|
|
5698
5713
|
ctx: TrpcContext;
|
|
5699
5714
|
meta: object;
|
|
@@ -113,6 +113,7 @@ export { networkAccessCapability } from '../capabilities/network-access.cap.js';
|
|
|
113
113
|
export { networkLinkCapability } from '../capabilities/network-link.cap.js';
|
|
114
114
|
export { networkQualityCapability } from '../capabilities/network-quality.cap.js';
|
|
115
115
|
export { nodeCertificatesCapability } from '../capabilities/node-certificates.cap.js';
|
|
116
|
+
export { nodeRemovalHookCapability } from '../capabilities/node-removal-hook.cap.js';
|
|
116
117
|
export { nodesCapability } from '../capabilities/nodes.cap.js';
|
|
117
118
|
export { notificationOutputCapability } from '../capabilities/notification-output.cap.js';
|
|
118
119
|
export { notificationRulesCapability } from '../capabilities/notification-rules.cap.js';
|
|
@@ -304,6 +305,7 @@ export declare const CAPABILITY_NAMES: {
|
|
|
304
305
|
readonly networkLink: 'network-link';
|
|
305
306
|
readonly networkQuality: 'network-quality';
|
|
306
307
|
readonly nodeCertificates: 'node-certificates';
|
|
308
|
+
readonly nodeRemovalHook: 'node-removal-hook';
|
|
307
309
|
readonly nodes: 'nodes';
|
|
308
310
|
readonly notificationOutput: 'notification-output';
|
|
309
311
|
readonly notificationRules: 'notification-rules';
|
|
@@ -508,6 +510,7 @@ export interface CapabilityRouterMap<TRouter = unknown> {
|
|
|
508
510
|
readonly networkLink: TRouter;
|
|
509
511
|
readonly networkQuality: TRouter;
|
|
510
512
|
readonly nodeCertificates: TRouter;
|
|
513
|
+
readonly nodeRemovalHook: TRouter;
|
|
511
514
|
readonly nodes: TRouter;
|
|
512
515
|
readonly notificationOutput: TRouter;
|
|
513
516
|
readonly notificationRules: TRouter;
|
|
@@ -588,8 +591,8 @@ export interface CapabilityRouterMap<TRouter = unknown> {
|
|
|
588
591
|
export declare const SINGLETON_CAPABILITY_NAMES: readonly ['accessories', 'actions', 'addon-pages', 'addon-settings', 'addon-widgets', 'addons', 'admin-ui', 'air-quality-sensor', 'alarm-panel', 'alerts', 'ambient-light-sensor', 'audio-analysis', 'audio-analyzer', 'audio-codec', 'audio-metrics', 'automation-control', 'backup', 'battery', 'binary', 'brightness', 'button', 'calendars', 'camera-credentials', 'camera-grid-layout', 'camera-pipeline-config', 'camera-streams', 'carbon-monoxide', 'climate-control', 'color', 'composer', 'connectivity', 'consumables', 'contact', 'control', 'core-blocks', 'cover', 'database-snapshot', 'day-night', 'decoder', 'detection-pipeline', 'device-admin-link', 'device-credentials', 'device-discovery', 'device-history', 'device-manager', 'device-ops', 'device-state', 'device-status', 'dishwasher', 'display-palette', 'doorbell', 'enum-sensor', 'event-emitter', 'face-gallery', 'fan-control', 'feature-probe', 'filesystem-browse', 'flood', 'gas', 'group-active', 'group-commands', 'group-status', 'heating-valve', 'humidifier', 'humidity-sensor', 'image', 'image-settings', 'integrations', 'intercom', 'ir-transmitter', 'keychain', 'keychain-admin', 'lawn-mower-control', 'llm-runtime', 'local-network', 'lock-control', 'media-player', 'meter', 'metrics-provider', 'model-convert', 'model-distributor', 'motion', 'motion-detection', 'motion-trigger', 'motion-zones', 'native-object-detection', 'navigation', 'network-link', 'network-quality', 'node-certificates', 'nodes', 'notification-rules', 'notifier', 'numeric-sensor', 'oidc-connections', 'osd', 'osd-manager', 'pet-feeder', 'pipeline-analytics', 'pipeline-executor', 'pipeline-orchestrator', 'pipeline-runner', 'plate-gallery', 'platform-probe', 'power-meter', 'presence', 'pressure-sensor', 'privacy-mask', 'ptz', 'ptz-autotrack', 'reboot', 'record-entries', 'recording-archive', 'recording-export', 'recording-onboard', 'recording-signal', 'records', 'remote', 'running-state', 'scene-monitor', 'script-runner', 'server-management', 'settings-store', 'smoke', 'snapshot', 'sso-bridge', 'storage', 'storage-admin', 'storage-migration', 'stream-broker', 'stream-catalog', 'stream-params', 'stream-signals', 'switch', 'system', 'tamper', 'temperature-sensor', 'terminal-session', 'toast', 'training', 'update', 'user-management', 'vacuum-control', 'valve', 'vector-store', 'vibration', 'viewer-ui', 'water-heater', 'weather', 'webrtc-session', 'zone-analytics', 'zone-rules', 'zones'];
|
|
589
592
|
/** Union of singleton capability names (literal string union). */
|
|
590
593
|
export type SingletonCapabilityName = typeof SINGLETON_CAPABILITY_NAMES[number];
|
|
591
|
-
/** Capability names whose mode is `collection` (
|
|
592
|
-
export declare const COLLECTION_CAPABILITY_NAMES: readonly ['action-source', 'addon-pages-source', 'addon-routes', 'addon-widgets-source', 'auth-provider', 'broker', 'calendar-source', 'connection-test', 'custom-model-registry', 'data-store-provider', 'device-adoption', 'device-export', 'device-extension', 'device-provider', 'device-removal-hook', 'embedding-encoder', 'failure-contribution', 'llm', 'load-contribution', 'log-channels', 'log-destination', 'login-method', 'mesh-network', 'mqtt-broker', 'network-access', 'notification-output', 'oauth-integration', 'recording', 'smtp-provider', 'storage-evictable', 'storage-occupancy', 'storage-provider', 'template', 'training-provider', 'turn-provider', 'user-passkeys', 'videoclips'];
|
|
594
|
+
/** Capability names whose mode is `collection` (38 caps). */
|
|
595
|
+
export declare const COLLECTION_CAPABILITY_NAMES: readonly ['action-source', 'addon-pages-source', 'addon-routes', 'addon-widgets-source', 'auth-provider', 'broker', 'calendar-source', 'connection-test', 'custom-model-registry', 'data-store-provider', 'device-adoption', 'device-export', 'device-extension', 'device-provider', 'device-removal-hook', 'embedding-encoder', 'failure-contribution', 'llm', 'load-contribution', 'log-channels', 'log-destination', 'login-method', 'mesh-network', 'mqtt-broker', 'network-access', 'node-removal-hook', 'notification-output', 'oauth-integration', 'recording', 'smtp-provider', 'storage-evictable', 'storage-occupancy', 'storage-provider', 'template', 'training-provider', 'turn-provider', 'user-passkeys', 'videoclips'];
|
|
593
596
|
/** Union of collection capability names (literal string union). */
|
|
594
597
|
export type CollectionCapabilityName = typeof COLLECTION_CAPABILITY_NAMES[number];
|
|
595
598
|
/** Capability mode lookup at runtime — mirrors the `.cap.ts` definitions. */
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* scope+access check inside `protectedProcedure` (see
|
|
7
7
|
* `server/backend/src/api/trpc/trpc.middleware.ts`).
|
|
8
8
|
*
|
|
9
|
-
* Coverage:
|
|
9
|
+
* Coverage: 1417 method paths across 191 capabilities.
|
|
10
10
|
*/
|
|
11
11
|
import type { MethodRole } from '../auth/viewer-access.js';
|
|
12
12
|
import type { CapabilityMethodAccess } from '../capabilities/capability-definition.js';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_sleep = require("./sleep-
|
|
2
|
+
const require_sleep = require("./sleep-E7qAQwTE.js");
|
|
3
3
|
const require_event_category = require("./event-category-E17zaHjN.js");
|
|
4
4
|
const require_composition = require("./composition-C0dlyG9U.js");
|
|
5
5
|
const require_node_color = require("./node-color.js");
|
|
@@ -43463,6 +43463,64 @@ var embeddingEncoderCapability = {
|
|
|
43463
43463
|
}
|
|
43464
43464
|
};
|
|
43465
43465
|
//#endregion
|
|
43466
|
+
//#region src/capabilities/node-removal-hook.cap.ts
|
|
43467
|
+
/**
|
|
43468
|
+
* `node-removal-hook` — the reliable way an addon learns a cluster node was
|
|
43469
|
+
* FORGOTTEN, so it can remove or re-point what it keeps for that node. The
|
|
43470
|
+
* node-scoped twin of `device-removal-hook` (D865); same shape, same rules.
|
|
43471
|
+
*
|
|
43472
|
+
* ## Why not "the node is absent"
|
|
43473
|
+
*
|
|
43474
|
+
* A node missing from topology is offline, restarting or not yet re-registered —
|
|
43475
|
+
* it is not forgotten. Deleting node-scoped data from absence destroys a live
|
|
43476
|
+
* node's configuration on any failed or partial read (D49). So the hook is
|
|
43477
|
+
* driven by a TOMBSTONE the hub records when the operator forgets a node
|
|
43478
|
+
* (`AgentRegistryService.forgetClusterNode`); nothing else produces one.
|
|
43479
|
+
*
|
|
43480
|
+
* ## The pieces
|
|
43481
|
+
*
|
|
43482
|
+
* 1. The hub records a tombstone `{ nodeId, removedAt, pending }` before it calls
|
|
43483
|
+
* anyone. `pending` is the set of implementers that have not yet acknowledged.
|
|
43484
|
+
* 2. The hub calls `onNodeRemoved` on EVERY provider of this collection, one by
|
|
43485
|
+
* one, with bounded retries, logged; an acknowledgement removes the
|
|
43486
|
+
* implementer from `pending`.
|
|
43487
|
+
* 3. The hub re-drives still-pending tombstones at boot, so an implementer that
|
|
43488
|
+
* was down at forget time is told when it is back.
|
|
43489
|
+
*
|
|
43490
|
+
* ## Contract for an implementer
|
|
43491
|
+
*
|
|
43492
|
+
* - **Idempotent.** Called again by a retry and by the boot re-drive. A node with
|
|
43493
|
+
* nothing left answers zero counts.
|
|
43494
|
+
* - **One key per store** in `counts`, rows changed per store, so the log line
|
|
43495
|
+
* can say where the data was.
|
|
43496
|
+
* - **Re-point or remove, never guess.** A row that merely MENTIONS the node as
|
|
43497
|
+
* a preference is re-pointed to "unset"; a row that only means something on
|
|
43498
|
+
* that node (a runtime bound to it) is removed.
|
|
43499
|
+
* - A provider that cannot tell is allowed to throw; the caller retries it.
|
|
43500
|
+
*/
|
|
43501
|
+
/** What a hook is told about the removal. */
|
|
43502
|
+
var NodeRemovedInputSchema = zod.z.object({
|
|
43503
|
+
nodeId: zod.z.string().min(1),
|
|
43504
|
+
/** Epoch ms the node was forgotten (the tombstone's `removedAt`). */
|
|
43505
|
+
removedAt: zod.z.number()
|
|
43506
|
+
});
|
|
43507
|
+
/** Rows changed (removed or re-pointed), per store this implementer owns. */
|
|
43508
|
+
var NodeRemovedResultSchema = zod.z.object({ counts: zod.z.record(zod.z.string(), zod.z.number().int().nonnegative()) });
|
|
43509
|
+
var nodeRemovalHookCapability = {
|
|
43510
|
+
name: "node-removal-hook",
|
|
43511
|
+
scope: "system",
|
|
43512
|
+
mode: "collection",
|
|
43513
|
+
internal: true,
|
|
43514
|
+
methods: {
|
|
43515
|
+
/** Remove or re-point everything this addon keeps for the forgotten node. Idempotent. */
|
|
43516
|
+
onNodeRemoved: require_sleep.method(NodeRemovedInputSchema, NodeRemovedResultSchema, {
|
|
43517
|
+
kind: "mutation",
|
|
43518
|
+
auth: "admin"
|
|
43519
|
+
}) },
|
|
43520
|
+
/** In-process only — enumerated through `addons.listCapabilityProviders`. */
|
|
43521
|
+
mount: { kind: "skip" }
|
|
43522
|
+
};
|
|
43523
|
+
//#endregion
|
|
43466
43524
|
//#region src/capabilities/device-removal-hook.cap.ts
|
|
43467
43525
|
/**
|
|
43468
43526
|
* `device-removal-hook` — the reliable way an addon learns a device was DELETED,
|
|
@@ -59120,8 +59178,7 @@ var pipelineOrchestratorCapability = {
|
|
|
59120
59178
|
* replaced the four flat orchestrator lists (`enabledNodes`,
|
|
59121
59179
|
* `enabledDecoderNodes`, `enabledAudioNodes`, `remoteSourcingNodes`).
|
|
59122
59180
|
* Each flag is optional in the patch: omit a flag to leave it unchanged,
|
|
59123
|
-
* pass `null` to reset it to the
|
|
59124
|
-
* other node → not). Detection/audio eligibility is derived from these
|
|
59181
|
+
* pass `null` to reset it to the default (ON for every node). Detection/audio eligibility is derived from these
|
|
59125
59182
|
* flags across the cluster; changing them re-derives the enabled sets
|
|
59126
59183
|
* and reconciles dispatch immediately. There is NO separate decode flag:
|
|
59127
59184
|
* decode is always co-located with its frame consumer, so decode
|
|
@@ -92880,6 +92937,13 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
92880
92937
|
access: "create",
|
|
92881
92938
|
role: "admin"
|
|
92882
92939
|
},
|
|
92940
|
+
"nodeRemovalHook.onNodeRemoved": {
|
|
92941
|
+
capName: "node-removal-hook",
|
|
92942
|
+
capScope: "system",
|
|
92943
|
+
addonId: null,
|
|
92944
|
+
access: "create",
|
|
92945
|
+
role: "admin"
|
|
92946
|
+
},
|
|
92883
92947
|
"nodes.clusterAddonStatus": {
|
|
92884
92948
|
capName: "nodes",
|
|
92885
92949
|
capScope: "system",
|
|
@@ -98115,6 +98179,7 @@ var KNOWN_CAP_NAMES = [
|
|
|
98115
98179
|
"network-link",
|
|
98116
98180
|
"network-quality",
|
|
98117
98181
|
"node-certificates",
|
|
98182
|
+
"node-removal-hook",
|
|
98118
98183
|
"nodes",
|
|
98119
98184
|
"notification-output",
|
|
98120
98185
|
"notification-rules",
|
|
@@ -98348,6 +98413,7 @@ var SYSTEM_CAP_NAMES = [
|
|
|
98348
98413
|
"network-access",
|
|
98349
98414
|
"network-quality",
|
|
98350
98415
|
"node-certificates",
|
|
98416
|
+
"node-removal-hook",
|
|
98351
98417
|
"nodes",
|
|
98352
98418
|
"notification-output",
|
|
98353
98419
|
"notification-rules",
|
|
@@ -102224,6 +102290,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
102224
102290
|
"device-manager": system("the device registry itself — rename, move and remove are administration"),
|
|
102225
102291
|
"device-provider": system(INTERNAL),
|
|
102226
102292
|
"device-removal-hook": system(INTERNAL),
|
|
102293
|
+
"node-removal-hook": system(INTERNAL),
|
|
102227
102294
|
"device-state": system("the runtime-state mirror every trigger already reads through"),
|
|
102228
102295
|
"display-palette": system("the cluster display palette — one colour table for every client, not a device action"),
|
|
102229
102296
|
"embedding-encoder": system(ML),
|
|
@@ -104216,6 +104283,7 @@ var CAPABILITY_NAMES = {
|
|
|
104216
104283
|
networkLink: "network-link",
|
|
104217
104284
|
networkQuality: "network-quality",
|
|
104218
104285
|
nodeCertificates: "node-certificates",
|
|
104286
|
+
nodeRemovalHook: "node-removal-hook",
|
|
104219
104287
|
nodes: "nodes",
|
|
104220
104288
|
notificationOutput: "notification-output",
|
|
104221
104289
|
notificationRules: "notification-rules",
|
|
@@ -104754,6 +104822,10 @@ var CAPABILITY_ROUTER_KEYS = [
|
|
|
104754
104822
|
key: "nodeCertificates",
|
|
104755
104823
|
name: "node-certificates"
|
|
104756
104824
|
},
|
|
104825
|
+
{
|
|
104826
|
+
key: "nodeRemovalHook",
|
|
104827
|
+
name: "node-removal-hook"
|
|
104828
|
+
},
|
|
104757
104829
|
{
|
|
104758
104830
|
key: "nodes",
|
|
104759
104831
|
name: "nodes"
|
|
@@ -105180,6 +105252,7 @@ var ALL_CAPABILITY_DEFINITIONS = [
|
|
|
105180
105252
|
networkLinkCapability,
|
|
105181
105253
|
networkQualityCapability,
|
|
105182
105254
|
nodeCertificatesCapability,
|
|
105255
|
+
nodeRemovalHookCapability,
|
|
105183
105256
|
nodesCapability,
|
|
105184
105257
|
notificationOutputCapability,
|
|
105185
105258
|
notificationRulesCapability,
|
|
@@ -119078,6 +119151,7 @@ var OAUTH_LANDING_REASONS = [
|
|
|
119078
119151
|
"unknown_broker",
|
|
119079
119152
|
"not_configured",
|
|
119080
119153
|
"exchange_failed",
|
|
119154
|
+
"no_authorization_code",
|
|
119081
119155
|
"no_refresh_token",
|
|
119082
119156
|
"unavailable",
|
|
119083
119157
|
"unknown"
|
|
@@ -119305,6 +119379,83 @@ function filterForwardedCookies(cookieHeader) {
|
|
|
119305
119379
|
return cookieHeader.split(";").map((part) => part.trim()).filter((part) => part.length > 0 && !part.toLowerCase().startsWith("camstack_")).join("; ");
|
|
119306
119380
|
}
|
|
119307
119381
|
//#endregion
|
|
119382
|
+
//#region src/vendor-login-proxy/flow-trace.ts
|
|
119383
|
+
/** A short stable label for the attempt: enough to group lines, useless as a capability. */
|
|
119384
|
+
function attemptLabel(attemptId) {
|
|
119385
|
+
let hash = 2166136261;
|
|
119386
|
+
for (let i = 0; i < attemptId.length; i += 1) hash = Math.imul(hash ^ attemptId.charCodeAt(i), 16777619) >>> 0;
|
|
119387
|
+
return hash.toString(16).padStart(8, "0");
|
|
119388
|
+
}
|
|
119389
|
+
/** Distinct parameter names of a `?a=1&b=2` string (or of a urlencoded body), in order. */
|
|
119390
|
+
function paramNames(query) {
|
|
119391
|
+
const names = [];
|
|
119392
|
+
const raw = query.startsWith("?") ? query.slice(1) : query;
|
|
119393
|
+
for (const pair of raw.split("&")) {
|
|
119394
|
+
if (pair.length === 0) continue;
|
|
119395
|
+
const eq = pair.indexOf("=");
|
|
119396
|
+
const rawName = eq === -1 ? pair : pair.slice(0, eq);
|
|
119397
|
+
let name;
|
|
119398
|
+
try {
|
|
119399
|
+
name = decodeURIComponent(rawName.replace(/\+/g, " "));
|
|
119400
|
+
} catch {
|
|
119401
|
+
name = rawName;
|
|
119402
|
+
}
|
|
119403
|
+
if (!names.includes(name)) names.push(name);
|
|
119404
|
+
}
|
|
119405
|
+
return names;
|
|
119406
|
+
}
|
|
119407
|
+
function hasOa2(names) {
|
|
119408
|
+
return names.some((name) => name.startsWith("openid.oa2.") || name === "openid.ns.oa2");
|
|
119409
|
+
}
|
|
119410
|
+
function cookieNamesOf(setCookies) {
|
|
119411
|
+
return setCookies.map((c) => c.split(";")[0]?.split("=")[0]?.trim() ?? "");
|
|
119412
|
+
}
|
|
119413
|
+
function mediaType(contentType) {
|
|
119414
|
+
return (contentType ?? "none").split(";")[0]?.trim().toLowerCase() || "none";
|
|
119415
|
+
}
|
|
119416
|
+
/** Host and path of a Location (no query), or 'unparsable'. */
|
|
119417
|
+
function locationShape(location, base) {
|
|
119418
|
+
try {
|
|
119419
|
+
const url = new URL(location, base);
|
|
119420
|
+
return {
|
|
119421
|
+
target: `${url.host}${url.pathname}`,
|
|
119422
|
+
names: paramNames(url.search)
|
|
119423
|
+
};
|
|
119424
|
+
} catch {
|
|
119425
|
+
return {
|
|
119426
|
+
target: "unparsable",
|
|
119427
|
+
names: []
|
|
119428
|
+
};
|
|
119429
|
+
}
|
|
119430
|
+
}
|
|
119431
|
+
/** The `meta` of one trace line. Values: never. */
|
|
119432
|
+
function flowTraceMeta(input) {
|
|
119433
|
+
const queryNames = paramNames(input.requestSearch);
|
|
119434
|
+
const formNames = input.formBody === null ? null : paramNames(input.formBody);
|
|
119435
|
+
const meta = {
|
|
119436
|
+
session: attemptLabel(input.attemptId),
|
|
119437
|
+
method: input.method,
|
|
119438
|
+
upstream: `${input.upstreamHost}${input.upstreamPath}`,
|
|
119439
|
+
queryNames: queryNames.join(",") || "none",
|
|
119440
|
+
oa2InQuery: hasOa2(queryNames),
|
|
119441
|
+
status: input.status,
|
|
119442
|
+
setCookieNames: cookieNamesOf(input.setCookies).join(",") || "none",
|
|
119443
|
+
cookiesSent: (input.cookieHeader ?? "").split(";").filter((p) => p.trim().length > 0).length
|
|
119444
|
+
};
|
|
119445
|
+
if (formNames !== null) {
|
|
119446
|
+
meta["contentType"] = mediaType(input.contentType);
|
|
119447
|
+
meta["formNames"] = formNames.join(",") || "none";
|
|
119448
|
+
meta["oa2InForm"] = hasOa2(formNames);
|
|
119449
|
+
}
|
|
119450
|
+
if (input.location !== null) {
|
|
119451
|
+
const loc = locationShape(input.location, `http://${input.upstreamHost}/`);
|
|
119452
|
+
meta["location"] = loc.target;
|
|
119453
|
+
meta["locationQueryNames"] = loc.names.join(",") || "none";
|
|
119454
|
+
meta["oa2InLocation"] = hasOa2(loc.names);
|
|
119455
|
+
}
|
|
119456
|
+
return meta;
|
|
119457
|
+
}
|
|
119458
|
+
//#endregion
|
|
119308
119459
|
//#region src/vendor-login-proxy/login-proxy.ts
|
|
119309
119460
|
var MAX_REQUEST_BODY_BYTES = 2 * 1024 * 1024;
|
|
119310
119461
|
var MAX_TEXT_BODY_BYTES = 4 * 1024 * 1024;
|
|
@@ -119410,6 +119561,8 @@ var VendorLoginProxy = class {
|
|
|
119410
119561
|
#now;
|
|
119411
119562
|
#fetch;
|
|
119412
119563
|
#attempts = /* @__PURE__ */ new Map();
|
|
119564
|
+
/** Trace lines written per attempt (bounded by FLOW_TRACE_MAX_LINES). */
|
|
119565
|
+
#traced = /* @__PURE__ */ new Map();
|
|
119413
119566
|
constructor(options) {
|
|
119414
119567
|
this.#addonId = options.addonId;
|
|
119415
119568
|
this.#logger = options.logger;
|
|
@@ -119436,6 +119589,7 @@ var VendorLoginProxy = class {
|
|
|
119436
119589
|
}
|
|
119437
119590
|
close(attemptId) {
|
|
119438
119591
|
this.#attempts.delete(attemptId);
|
|
119592
|
+
this.#traced.delete(attemptId);
|
|
119439
119593
|
}
|
|
119440
119594
|
isOpen(attemptId) {
|
|
119441
119595
|
const attempt = this.#attempts.get(attemptId);
|
|
@@ -119482,7 +119636,7 @@ var VendorLoginProxy = class {
|
|
|
119482
119636
|
const forwardedPrefix = (firstHeader(req.headers["x-forwarded-prefix"]) ?? "").replace(/\/+$/, "");
|
|
119483
119637
|
const attempt = this.#attempts.get(parsed.attemptId);
|
|
119484
119638
|
if (attempt === void 0 || this.#now() > attempt.expiresAtMs) {
|
|
119485
|
-
if (attempt !== void 0) this
|
|
119639
|
+
if (attempt !== void 0) this.close(parsed.attemptId);
|
|
119486
119640
|
this.#logger.info("vendor login proxy: attempt refused", { meta: {
|
|
119487
119641
|
addonId: this.#addonId,
|
|
119488
119642
|
reason: attempt === void 0 ? "missing" : "expired"
|
|
@@ -119507,13 +119661,17 @@ var VendorLoginProxy = class {
|
|
|
119507
119661
|
}
|
|
119508
119662
|
const method = (req.method ?? "GET").toUpperCase();
|
|
119509
119663
|
let body;
|
|
119664
|
+
let formBodyRaw = null;
|
|
119510
119665
|
if (method !== "GET" && method !== "HEAD") {
|
|
119511
119666
|
const read = await readRequestBody(req);
|
|
119512
119667
|
if (read === "too-large") {
|
|
119513
119668
|
sendPlain(res, 413, "Request too large");
|
|
119514
119669
|
return;
|
|
119515
119670
|
}
|
|
119516
|
-
|
|
119671
|
+
if (isFormEncoded(req.headers["content-type"])) {
|
|
119672
|
+
formBodyRaw = read.toString("utf8");
|
|
119673
|
+
body = Buffer.from(rewriteFormBody(formBodyRaw, route), "utf8");
|
|
119674
|
+
} else body = read;
|
|
119517
119675
|
}
|
|
119518
119676
|
const headers = this.#requestHeaders(req, route, upstream);
|
|
119519
119677
|
const upstreamRes = await this.#fetch(target, {
|
|
@@ -119538,6 +119696,19 @@ var VendorLoginProxy = class {
|
|
|
119538
119696
|
sentNames: cookieNames(headers["cookie"]),
|
|
119539
119697
|
vendorSets: setCookies.map(setCookieShape).join(" | ")
|
|
119540
119698
|
} });
|
|
119699
|
+
this.#trace(parsed.attemptId, {
|
|
119700
|
+
attemptId: parsed.attemptId,
|
|
119701
|
+
method,
|
|
119702
|
+
upstreamHost: upstream.host,
|
|
119703
|
+
upstreamPath: target.pathname,
|
|
119704
|
+
requestSearch: target.search,
|
|
119705
|
+
formBody: formBodyRaw,
|
|
119706
|
+
contentType: firstHeader(req.headers["content-type"]),
|
|
119707
|
+
status: upstreamRes.status,
|
|
119708
|
+
location,
|
|
119709
|
+
setCookies,
|
|
119710
|
+
cookieHeader: headers["cookie"]
|
|
119711
|
+
});
|
|
119541
119712
|
const settled = await attempt.evaluate({
|
|
119542
119713
|
status: upstreamRes.status,
|
|
119543
119714
|
url: target.toString(),
|
|
@@ -119546,7 +119717,7 @@ var VendorLoginProxy = class {
|
|
|
119546
119717
|
bodyText: text
|
|
119547
119718
|
});
|
|
119548
119719
|
if (settled.kind === "done") {
|
|
119549
|
-
this
|
|
119720
|
+
this.close(parsed.attemptId);
|
|
119550
119721
|
this.#logger.info("vendor login proxy: sign-in finished", { meta: {
|
|
119551
119722
|
addonId: this.#addonId,
|
|
119552
119723
|
status: settled.landing.status
|
|
@@ -119570,6 +119741,16 @@ var VendorLoginProxy = class {
|
|
|
119570
119741
|
res.writeHead(upstreamRes.status, out);
|
|
119571
119742
|
await this.#pipeBody(upstreamRes, res);
|
|
119572
119743
|
}
|
|
119744
|
+
/** One names-only line per proxied request, at most FLOW_TRACE_MAX_LINES per attempt. */
|
|
119745
|
+
#trace(attemptId, input) {
|
|
119746
|
+
const written = this.#traced.get(attemptId) ?? 0;
|
|
119747
|
+
if (written >= 200) return;
|
|
119748
|
+
this.#traced.set(attemptId, written + 1);
|
|
119749
|
+
this.#logger.info("vendor login proxy: flow", { meta: {
|
|
119750
|
+
addonId: this.#addonId,
|
|
119751
|
+
...flowTraceMeta(input)
|
|
119752
|
+
} });
|
|
119753
|
+
}
|
|
119573
119754
|
#requestHeaders(req, route, upstream) {
|
|
119574
119755
|
const headers = {};
|
|
119575
119756
|
for (const [name, value] of Object.entries(req.headers)) {
|
|
@@ -122125,6 +122306,8 @@ exports.NodeDirectoryEntrySchema = NodeDirectoryEntrySchema;
|
|
|
122125
122306
|
exports.NodeDirectorySchema = NodeDirectorySchema;
|
|
122126
122307
|
exports.NodeHttpsStateSchema = NodeHttpsStateSchema;
|
|
122127
122308
|
exports.NodeRecommendationSchema = NodeRecommendationSchema;
|
|
122309
|
+
exports.NodeRemovedInputSchema = NodeRemovedInputSchema;
|
|
122310
|
+
exports.NodeRemovedResultSchema = NodeRemovedResultSchema;
|
|
122128
122311
|
exports.NotificationActionIconSchema = NotificationActionIconSchema;
|
|
122129
122312
|
exports.NotificationActionSchema = NotificationActionSchema;
|
|
122130
122313
|
exports.NotificationFormatSchema = NotificationFormatSchema;
|
|
@@ -123559,6 +123742,7 @@ exports.nodeBenchmarkRefusals = nodeBenchmarkRefusals;
|
|
|
123559
123742
|
exports.nodeCertificatesCapability = nodeCertificatesCapability;
|
|
123560
123743
|
exports.nodePickerItems = nodePickerItems;
|
|
123561
123744
|
exports.nodePin = require_sleep.nodePin;
|
|
123745
|
+
exports.nodeRemovalHookCapability = nodeRemovalHookCapability;
|
|
123562
123746
|
exports.nodesCapability = nodesCapability;
|
|
123563
123747
|
exports.normalizeAddonInitResult = require_sleep.normalizeAddonInitResult;
|
|
123564
123748
|
exports.normalizeAudioLabel = normalizeAudioLabel;
|