@camstack/types 1.2.51 → 1.2.53
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/addon.js +1 -1
- package/dist/addon.mjs +1 -1
- package/dist/capabilities/connection-test.cap.d.ts +103 -0
- package/dist/capabilities/device-manager.cap.d.ts +67 -0
- package/dist/capabilities/index.d.ts +4 -2
- package/dist/capabilities/integrations.cap.d.ts +48 -1
- package/dist/capabilities/snapshot.cap.d.ts +56 -0
- package/dist/generated/addon-api.d.ts +51 -0
- package/dist/generated/capability-router-map.d.ts +5 -2
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/system-proxy.d.ts +3 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +396 -2
- package/dist/index.mjs +387 -3
- package/dist/interfaces/adoption-job.d.ts +113 -0
- package/dist/node.d.ts +2 -0
- package/dist/node.js +57 -0
- package/dist/node.mjs +57 -2
- package/dist/{sleep-7WqNZVcL.mjs → sleep-CT4lN1ij.mjs} +1 -0
- package/dist/{sleep-ocMLM2o5.js → sleep-DfF6vKCf.js} +1 -0
- package/dist/utils/expiring-url-signature.d.ts +27 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_event_category = require("./event-category-BE4PDZ_3.js");
|
|
3
|
-
const require_sleep = require("./sleep-
|
|
3
|
+
const require_sleep = require("./sleep-DfF6vKCf.js");
|
|
4
4
|
const require_canonical_hash = require("./canonical-hash-DNV8S5ET.js");
|
|
5
5
|
const require_enums = require("./enums.js");
|
|
6
6
|
const require_err_msg = require("./err-msg-COpsHMw2.js");
|
|
@@ -585,6 +585,106 @@ function resolveAddonPlacement(decl) {
|
|
|
585
585
|
return resolveAddonExecution(decl).placement;
|
|
586
586
|
}
|
|
587
587
|
//#endregion
|
|
588
|
+
//#region src/interfaces/adoption-job.ts
|
|
589
|
+
/**
|
|
590
|
+
* Adoption job — the background form of `device-adoption.adopt`.
|
|
591
|
+
*
|
|
592
|
+
* ## Why this exists
|
|
593
|
+
*
|
|
594
|
+
* `adopt({childNativeIds: [...]})` materialises one CamStack device per
|
|
595
|
+
* candidate PLUS every accessory child, and the whole array shares ONE UDS
|
|
596
|
+
* request deadline (60s). Measured on the live hub against Home Assistant:
|
|
597
|
+
* each device the kernel creates costs ~450 ms — `devices.create` pre-seeds
|
|
598
|
+
* meta with up to eleven SEQUENTIAL round trips (`setName`, `setType`,
|
|
599
|
+
* `setRole`, … `persistConfig`) before the class is constructed — and an
|
|
600
|
+
* accessory child costs the same as its parent. So the real unit of work is
|
|
601
|
+
* the CHILD, not the candidate:
|
|
602
|
+
*
|
|
603
|
+
* - 25 candidates averaging 6 children → ~150 devices → **>60s, times out**
|
|
604
|
+
* - ONE candidate with 217 children → ~217 devices → **>60s, times out**
|
|
605
|
+
*
|
|
606
|
+
* That second line is why this is a job and not a smaller batch. No chunking,
|
|
607
|
+
* no bounded concurrency over candidates and no per-call tuning can fix a
|
|
608
|
+
* shape where **N=1 already exceeds the deadline** — the count that blows the
|
|
609
|
+
* budget is the source system's accessory fan-out, which the operator does not
|
|
610
|
+
* choose and cannot see. A design that only works below some N is the same bug
|
|
611
|
+
* deferred.
|
|
612
|
+
*
|
|
613
|
+
* ## What the timeout did NOT do
|
|
614
|
+
*
|
|
615
|
+
* It did not stop the work. The UDS deadline ends the CALLER's wait; the
|
|
616
|
+
* provider's loop runs to completion. Measured: a 25-candidate adopt that
|
|
617
|
+
* "failed" at 60s had adopted 17 by 87s and all 25 by ~130s. The operator saw
|
|
618
|
+
* an error and had no way to learn that. Every field below exists so that
|
|
619
|
+
* question has an answer.
|
|
620
|
+
*
|
|
621
|
+
* ## Idempotency
|
|
622
|
+
*
|
|
623
|
+
* Jobs are in-RAM; a restart forgets them. That is safe here because adoption
|
|
624
|
+
* is keyed by a stable id (`ha:<broker>:dev:<nativeId>` and equivalents), so
|
|
625
|
+
* re-running a job re-adopts nothing: an already-adopted candidate is SKIPPED
|
|
626
|
+
* by the engine before any provider call and lands in `alreadyAdopted`. It is
|
|
627
|
+
* never a duplicate device, and never an error the operator has to interpret.
|
|
628
|
+
*/
|
|
629
|
+
var AdoptionJobStateSchema = zod.z.enum([
|
|
630
|
+
"running",
|
|
631
|
+
"done",
|
|
632
|
+
"failed",
|
|
633
|
+
"cancelled"
|
|
634
|
+
]);
|
|
635
|
+
/**
|
|
636
|
+
* Per-candidate result. Every candidate the job was asked to adopt ends in
|
|
637
|
+
* exactly one of these buckets — there is no silent drop, and the operator can
|
|
638
|
+
* always answer "which of my 25 landed?".
|
|
639
|
+
*
|
|
640
|
+
* - `adopted` — created now by this job.
|
|
641
|
+
* - `already-adopted` — a device for this candidate existed before the job
|
|
642
|
+
* reached it (a re-run, or a retry after a timeout). Not an error.
|
|
643
|
+
* - `failed` — the provider threw; `error` carries the message.
|
|
644
|
+
* - `cancelled` — the operator cancelled before this candidate was reached.
|
|
645
|
+
*/
|
|
646
|
+
var AdoptionOutcomeSchema = zod.z.enum([
|
|
647
|
+
"adopted",
|
|
648
|
+
"already-adopted",
|
|
649
|
+
"failed",
|
|
650
|
+
"cancelled"
|
|
651
|
+
]);
|
|
652
|
+
var AdoptionCandidateResultSchema = zod.z.object({
|
|
653
|
+
childNativeId: zod.z.string(),
|
|
654
|
+
outcome: AdoptionOutcomeSchema,
|
|
655
|
+
/** The materialised parent device id — null for `failed` / `cancelled`. */
|
|
656
|
+
parentDeviceId: zod.z.number().int().nonnegative().nullable(),
|
|
657
|
+
/** Accessory children created for this candidate. */
|
|
658
|
+
accessoryCount: zod.z.number().int().nonnegative(),
|
|
659
|
+
/** Failure message; null unless `outcome === 'failed'`. */
|
|
660
|
+
error: zod.z.string().nullable()
|
|
661
|
+
});
|
|
662
|
+
var AdoptionJobSchema = zod.z.object({
|
|
663
|
+
jobId: zod.z.string(),
|
|
664
|
+
/** The integration provider this job adopts through (the `addonId` pin). */
|
|
665
|
+
addonId: zod.z.string(),
|
|
666
|
+
integrationId: zod.z.string(),
|
|
667
|
+
state: AdoptionJobStateSchema,
|
|
668
|
+
/** Candidates the job was asked to adopt. Known up front, so never null. */
|
|
669
|
+
total: zod.z.number().int().nonnegative(),
|
|
670
|
+
/** Candidates that have reached a terminal bucket. */
|
|
671
|
+
processed: zod.z.number().int().nonnegative(),
|
|
672
|
+
adopted: zod.z.number().int().nonnegative(),
|
|
673
|
+
alreadyAdopted: zod.z.number().int().nonnegative(),
|
|
674
|
+
failed: zod.z.number().int().nonnegative(),
|
|
675
|
+
/** Accessory child devices created across every candidate — the real unit
|
|
676
|
+
* of work, surfaced so a slow job is legible rather than mysterious. */
|
|
677
|
+
accessoriesCreated: zod.z.number().int().nonnegative(),
|
|
678
|
+
/** The candidate currently being adopted; null when idle or finished. */
|
|
679
|
+
currentChildNativeId: zod.z.string().nullable(),
|
|
680
|
+
/** One entry per candidate, in the order they were processed. */
|
|
681
|
+
results: zod.z.array(AdoptionCandidateResultSchema).readonly(),
|
|
682
|
+
startedAt: zod.z.number(),
|
|
683
|
+
finishedAt: zod.z.number().nullable(),
|
|
684
|
+
/** Set only when the job itself broke (not a per-candidate failure). */
|
|
685
|
+
error: zod.z.string().nullable()
|
|
686
|
+
});
|
|
687
|
+
//#endregion
|
|
588
688
|
//#region src/interfaces/analysis-persistence.ts
|
|
589
689
|
var DEFAULT_RETENTION = {
|
|
590
690
|
cleanupIntervalMs: 3600 * 1e3,
|
|
@@ -8706,6 +8806,31 @@ var deviceManagerCapability = {
|
|
|
8706
8806
|
auth: "admin"
|
|
8707
8807
|
}),
|
|
8708
8808
|
/**
|
|
8809
|
+
* Start a background adoption and return its `jobId` immediately. The job
|
|
8810
|
+
* adopts ONE candidate per provider call, so no single request can exceed
|
|
8811
|
+
* the transport deadline, and it skips candidates that are already adopted
|
|
8812
|
+
* — which makes re-submitting a batch after a timeout safe and silent
|
|
8813
|
+
* rather than a wall of duplicate-stableId errors.
|
|
8814
|
+
*/
|
|
8815
|
+
adoptionStartJob: require_sleep.method(AdoptInputSchema.extend({ addonId: zod.z.string() }), zod.z.object({ jobId: zod.z.string() }), {
|
|
8816
|
+
kind: "mutation",
|
|
8817
|
+
auth: "admin"
|
|
8818
|
+
}),
|
|
8819
|
+
/**
|
|
8820
|
+
* Adoption jobs for an integration, newest first. This is the answer to
|
|
8821
|
+
* "which of my 25 landed?" — `results` carries one entry per candidate,
|
|
8822
|
+
* every one of them in a named bucket.
|
|
8823
|
+
*/
|
|
8824
|
+
adoptionListJobs: require_sleep.method(zod.z.object({
|
|
8825
|
+
addonId: zod.z.string(),
|
|
8826
|
+
integrationId: zod.z.string().optional()
|
|
8827
|
+
}), zod.z.array(AdoptionJobSchema).readonly(), { auth: "admin" }),
|
|
8828
|
+
/** Cooperative cancel: the in-flight candidate finishes, the rest never start. */
|
|
8829
|
+
adoptionCancelJob: require_sleep.method(zod.z.object({ jobId: zod.z.string() }), zod.z.object({ cancelled: zod.z.boolean() }), {
|
|
8830
|
+
kind: "mutation",
|
|
8831
|
+
auth: "admin"
|
|
8832
|
+
}),
|
|
8833
|
+
/**
|
|
8709
8834
|
* Re-sync a device with its source via the device-adoption provider of the
|
|
8710
8835
|
* device's OWNING addon (resolved from `camDeviceId`). Unlike the singleton
|
|
8711
8836
|
* `device-adoption.resync`, this routes to the correct integration so a
|
|
@@ -17308,6 +17433,77 @@ var snapshotCapability = {
|
|
|
17308
17433
|
lastCapturedAt: zod.z.number().nullable(),
|
|
17309
17434
|
cacheAgeMs: zod.z.number().nullable(),
|
|
17310
17435
|
etag: zod.z.string().nullable()
|
|
17436
|
+
}))),
|
|
17437
|
+
/**
|
|
17438
|
+
* Signed, expiring links to a CLIENT-SIZED frame — and the demand signal
|
|
17439
|
+
* that makes those frames current.
|
|
17440
|
+
*
|
|
17441
|
+
* ## The problem it replaces
|
|
17442
|
+
*
|
|
17443
|
+
* `getSnapshotOverview` is cache-only by contract: it answers from whatever
|
|
17444
|
+
* the wrapper happens to hold and never captures. Under D93 the client
|
|
17445
|
+
* versions its image URL on that answer, and an image REQUEST is what enrols
|
|
17446
|
+
* a camera in the keep-warm loop. Both of those are satisfiable by the
|
|
17447
|
+
* client's own image cache — `expo-image` is URL-keyed and never revalidates
|
|
17448
|
+
* — so a URL painted in a previous session comes off disk with no network,
|
|
17449
|
+
* no enrolment, and nothing warming. Measured on the live hub: reopening
|
|
17450
|
+
* after two minutes idle painted 15 of 16 tiles at **168 s old** with zero
|
|
17451
|
+
* HTTP requests, and the fleet only recovered because a later poll happened
|
|
17452
|
+
* to observe a different identity.
|
|
17453
|
+
*
|
|
17454
|
+
* ## The two properties that fix it
|
|
17455
|
+
*
|
|
17456
|
+
* **It is an RPC, so no client cache can answer it.** The demand signal
|
|
17457
|
+
* always reaches the wrapper. This method therefore MAY create keep-warm
|
|
17458
|
+
* subscriptions, where `getSnapshotOverview` must never (D93) — the
|
|
17459
|
+
* distinction is not "one is newer" but that the overview poll is app-wide
|
|
17460
|
+
* (a creating overview would warm every camera on the install) while this is
|
|
17461
|
+
* called by a rendered surface naming the tiles it is actually painting, at
|
|
17462
|
+
* the width it is painting them.
|
|
17463
|
+
*
|
|
17464
|
+
* **It waits, briefly and boundedly, for the capture it triggered.** The
|
|
17465
|
+
* returned `capturedAt` is the frame the link will serve, not the frame the
|
|
17466
|
+
* cache held when the client asked, so a first paint is honest and current
|
|
17467
|
+
* instead of a generation behind. A device that does not settle inside the
|
|
17468
|
+
* bound still gets a link and its real (older) `capturedAt` — the next poll
|
|
17469
|
+
* carries it forward.
|
|
17470
|
+
*
|
|
17471
|
+
* `force` is never set on behalf of a client here. A sleeping battery camera
|
|
17472
|
+
* is reported with `sleeping: true` and the last frame it produced, however
|
|
17473
|
+
* old; the wrapper's existing sleep gate owns that decision and this method
|
|
17474
|
+
* adds no second one.
|
|
17475
|
+
*/
|
|
17476
|
+
getSnapshotLinks: require_sleep.systemMethod(zod.z.object({
|
|
17477
|
+
/** The tiles a surface is actually rendering. One entry per (device,
|
|
17478
|
+
* width) the caller will paint — the width is snapped to the server's
|
|
17479
|
+
* ladder and becomes part of the link's SIGNED identity. */
|
|
17480
|
+
targets: zod.z.array(zod.z.object({
|
|
17481
|
+
deviceId: zod.z.number(),
|
|
17482
|
+
/** Target width in px. Omit for the frame as captured — correct
|
|
17483
|
+
* for a full-bleed surface, wrong (and expensive) for a grid. */
|
|
17484
|
+
width: zod.z.number().int().positive().optional()
|
|
17485
|
+
})).min(1).max(200) }), zod.z.array(zod.z.object({
|
|
17486
|
+
deviceId: zod.z.number(),
|
|
17487
|
+
/** Root-relative signed path, or null when the link plane is not
|
|
17488
|
+
* served (no data-plane facility). Present even for a device that has
|
|
17489
|
+
* never captured — the request is what triggers the first one (D94). */
|
|
17490
|
+
url: zod.z.string().nullable(),
|
|
17491
|
+
/** Epoch ms of the frame this link serves. Null = never captured.
|
|
17492
|
+
* THE honest age: the tRPC path carried none before this. */
|
|
17493
|
+
capturedAt: zod.z.number().nullable(),
|
|
17494
|
+
/** Age of that frame at the moment the answer was built. */
|
|
17495
|
+
ageMs: zod.z.number().nullable(),
|
|
17496
|
+
/** Epoch ms after which `url` stops verifying. */
|
|
17497
|
+
expiresAt: zod.z.number().nullable(),
|
|
17498
|
+
/** Ladder rung the bytes are at; null = the frame as captured. */
|
|
17499
|
+
width: zod.z.number().nullable(),
|
|
17500
|
+
/** The device has never produced a frame. An empty state, not a
|
|
17501
|
+
* failure — and never a reason to withhold the link (D94). */
|
|
17502
|
+
neverCaptured: zod.z.boolean(),
|
|
17503
|
+
/** A sleeping battery camera: the frame is deliberately stale and will
|
|
17504
|
+
* NOT refresh in the background. A surface should say so rather than
|
|
17505
|
+
* present it as current. */
|
|
17506
|
+
sleeping: zod.z.boolean()
|
|
17311
17507
|
})))
|
|
17312
17508
|
},
|
|
17313
17509
|
status: {
|
|
@@ -19973,6 +20169,101 @@ onColorChanged: { data: zod.z.object({
|
|
|
19973
20169
|
runtimeState: ColorStatusSchema
|
|
19974
20170
|
};
|
|
19975
20171
|
//#endregion
|
|
20172
|
+
//#region src/capabilities/connection-test.cap.ts
|
|
20173
|
+
/**
|
|
20174
|
+
* `connection-test` — pre-creation validation of an integration's settings,
|
|
20175
|
+
* system-scoped collection (one provider per integration addon).
|
|
20176
|
+
*
|
|
20177
|
+
* ── Why this cap exists ─────────────────────────────────────────────────────
|
|
20178
|
+
*
|
|
20179
|
+
* Before it, `integrations.testConnection` had exactly two behaviours: a broker
|
|
20180
|
+
* branch (`settings.brokerId` → `broker.testConnection`) and a DEFAULT branch
|
|
20181
|
+
* that probed `settings.main_stream_url ?? settings.url` with ffprobe. Every
|
|
20182
|
+
* account-based integration — Dreo, Dreame, Tuya, Petkit, Wyze — fell into that
|
|
20183
|
+
* default and was told `{"success":false,"error":"No stream URL provided"}`.
|
|
20184
|
+
* That answer neither validated nor refused anything, so:
|
|
20185
|
+
*
|
|
20186
|
+
* - the Test button had NEVER worked for an account integration, and
|
|
20187
|
+
* - `integrations.create` had nothing to gate on, so an integration with a
|
|
20188
|
+
* wrong password was created happily and failed later, silently, at
|
|
20189
|
+
* reconcile time.
|
|
20190
|
+
*
|
|
20191
|
+
* The structural gap was that at CREATE time the integration does not exist
|
|
20192
|
+
* yet: there is no `integrationId`, no `brokerId`, no live client — and every
|
|
20193
|
+
* existing provider surface (`device-provider`, `device-adoption`) is keyed by
|
|
20194
|
+
* one of those. There was no way to ask "are these settings valid?" before the
|
|
20195
|
+
* row existed.
|
|
20196
|
+
*
|
|
20197
|
+
* ── The contract ────────────────────────────────────────────────────────────
|
|
20198
|
+
*
|
|
20199
|
+
* The provider knows how to validate its OWN settings. The framework does not
|
|
20200
|
+
* guess from the shape of the settings — a stream-URL probe is one provider's
|
|
20201
|
+
* implementation of this cap, not the universal fallback. A provider that does
|
|
20202
|
+
* not register this cap is a KNOWN "cannot validate", never a silent pass.
|
|
20203
|
+
*
|
|
20204
|
+
* `testSettings` takes the candidate settings blob exactly as the wizard's
|
|
20205
|
+
* config step collected it (the same blob that would be handed to
|
|
20206
|
+
* `integrations.create`), and MUST NOT persist anything, mint an integration,
|
|
20207
|
+
* or mutate live state. It opens a throwaway session, asks, and closes it.
|
|
20208
|
+
*
|
|
20209
|
+
* ── The three outcomes are NOT interchangeable ──────────────────────────────
|
|
20210
|
+
*
|
|
20211
|
+
* This is the whole point of the discriminated union: a `null` from a timeout
|
|
20212
|
+
* must never look like a `null` from a refusal.
|
|
20213
|
+
*
|
|
20214
|
+
* - `validated` — the remote ACCEPTED these credentials. Observed.
|
|
20215
|
+
* - `rejected` — the remote REFUSED these credentials. Observed.
|
|
20216
|
+
* This is the ONLY outcome that blocks creation.
|
|
20217
|
+
* - `inconclusive` — the check could not complete (DNS, timeout, 5xx, an
|
|
20218
|
+
* unexpected shape). NOTHING was observed about the
|
|
20219
|
+
* credentials. Never rendered, or counted, as a failure.
|
|
20220
|
+
*
|
|
20221
|
+
* A provider that cannot tell a refusal from a transport fault must return
|
|
20222
|
+
* `inconclusive`. Guessing `rejected` would block creation on a flaky network;
|
|
20223
|
+
* guessing `validated` would wave a wrong password through.
|
|
20224
|
+
*/
|
|
20225
|
+
/** Ceiling on how long a pre-creation probe may hold the wizard. */
|
|
20226
|
+
var CONNECTION_TEST_TIMEOUT_MS = 2e4;
|
|
20227
|
+
var ConnectionTestOutcomeSchema = zod.z.discriminatedUnion("outcome", [
|
|
20228
|
+
zod.z.object({
|
|
20229
|
+
outcome: zod.z.literal("validated"),
|
|
20230
|
+
/** Round-trip of the sign-in, when the provider measured it. */
|
|
20231
|
+
latencyMs: zod.z.number().nonnegative().optional(),
|
|
20232
|
+
/** Optional human detail worth showing next to the tick
|
|
20233
|
+
* ("3 devices visible on this account"). */
|
|
20234
|
+
detail: zod.z.string().optional()
|
|
20235
|
+
}).strict(),
|
|
20236
|
+
zod.z.object({
|
|
20237
|
+
outcome: zod.z.literal("rejected"),
|
|
20238
|
+
error: zod.z.string()
|
|
20239
|
+
}).strict(),
|
|
20240
|
+
zod.z.object({
|
|
20241
|
+
outcome: zod.z.literal("inconclusive"),
|
|
20242
|
+
error: zod.z.string()
|
|
20243
|
+
}).strict()
|
|
20244
|
+
]);
|
|
20245
|
+
var ConnectionTestInputSchema = zod.z.object({
|
|
20246
|
+
/** Candidate integration settings, exactly as the create form collected them. */
|
|
20247
|
+
settings: zod.z.record(zod.z.string(), zod.z.unknown()) });
|
|
20248
|
+
/**
|
|
20249
|
+
* What the provider's test actually DOES, so the UI can say it in words before
|
|
20250
|
+
* the operator presses the button ("Signs in to the Dreo cloud"). Purely
|
|
20251
|
+
* descriptive — it never changes routing.
|
|
20252
|
+
*/
|
|
20253
|
+
var ConnectionTestDescriptorSchema = zod.z.object({ label: zod.z.string() });
|
|
20254
|
+
var connectionTestCapability = {
|
|
20255
|
+
name: "connection-test",
|
|
20256
|
+
scope: "system",
|
|
20257
|
+
mode: "collection",
|
|
20258
|
+
methods: {
|
|
20259
|
+
testSettings: require_sleep.method(ConnectionTestInputSchema, ConnectionTestOutcomeSchema, {
|
|
20260
|
+
kind: "mutation",
|
|
20261
|
+
auth: "admin"
|
|
20262
|
+
}),
|
|
20263
|
+
describeTest: require_sleep.method(zod.z.void(), ConnectionTestDescriptorSchema, { auth: "admin" })
|
|
20264
|
+
}
|
|
20265
|
+
};
|
|
20266
|
+
//#endregion
|
|
19976
20267
|
//#region src/capabilities/connectivity.cap.ts
|
|
19977
20268
|
/**
|
|
19978
20269
|
* Upstream-system connectivity sensor — distinct from `device-status`,
|
|
@@ -21457,15 +21748,57 @@ var AvailableIntegrationTypeSchema = zod.z.object({
|
|
|
21457
21748
|
* flow can import (e.g. HA areas). Drives the adopt modal's "import
|
|
21458
21749
|
* locations" checkbox. Provider-declared in the addon manifest. */
|
|
21459
21750
|
supportsLocationImport: zod.z.boolean(),
|
|
21751
|
+
/**
|
|
21752
|
+
* True when this integration DECLARES a pre-creation test (the
|
|
21753
|
+
* `connection-test` cap, or a broker whose settings it stores). Drives the
|
|
21754
|
+
* Test button: an integration that cannot be tested must say so up front
|
|
21755
|
+
* rather than offering a button that always answers the same nonsense.
|
|
21756
|
+
*/
|
|
21757
|
+
canTest: zod.z.boolean(),
|
|
21460
21758
|
existingInstances: zod.z.array(zod.z.object({
|
|
21461
21759
|
id: zod.z.string(),
|
|
21462
21760
|
name: zod.z.string()
|
|
21463
21761
|
})),
|
|
21464
21762
|
canAdd: zod.z.boolean()
|
|
21465
21763
|
});
|
|
21764
|
+
/**
|
|
21765
|
+
* Why a test could not be answered as a plain boolean.
|
|
21766
|
+
*
|
|
21767
|
+
* `success` alone collapsed four different situations into one red box, and the
|
|
21768
|
+
* one that mattered most — "nobody ever asked the remote anything" — looked
|
|
21769
|
+
* exactly like "the remote said no". The status is the discriminator:
|
|
21770
|
+
*
|
|
21771
|
+
* - `validated` — a provider-declared test ran and the remote ACCEPTED.
|
|
21772
|
+
* - `rejected` — a provider-declared test ran and the remote REFUSED.
|
|
21773
|
+
* The only status that blocks `integrations.create`.
|
|
21774
|
+
* - `inconclusive` — a test IS declared but could not complete (timeout,
|
|
21775
|
+
* DNS, 5xx). Nothing was observed; not a failure.
|
|
21776
|
+
* - `unsupported` — this integration declares NO test. Nothing was
|
|
21777
|
+
* observed either; not a failure, and not a pass.
|
|
21778
|
+
*
|
|
21779
|
+
* `unsupported` and `inconclusive` both carry `success: false` so an older
|
|
21780
|
+
* client can never read them as a green tick, and both carry an `error` string
|
|
21781
|
+
* that SAYS the test did not run rather than inventing a failure.
|
|
21782
|
+
*/
|
|
21783
|
+
var TestConnectionStatusEnum = zod.z.enum([
|
|
21784
|
+
"validated",
|
|
21785
|
+
"rejected",
|
|
21786
|
+
"inconclusive",
|
|
21787
|
+
"unsupported"
|
|
21788
|
+
]);
|
|
21466
21789
|
var TestConnectionResultSchema$1 = zod.z.object({
|
|
21790
|
+
/** True ONLY for `validated`. Never true for a test that did not run. */
|
|
21467
21791
|
success: zod.z.boolean(),
|
|
21468
|
-
error: zod.z.string().optional()
|
|
21792
|
+
error: zod.z.string().optional(),
|
|
21793
|
+
/** Optional for wire back-compat with clients built before the tri-state;
|
|
21794
|
+
* the server always sets it. */
|
|
21795
|
+
status: TestConnectionStatusEnum.optional(),
|
|
21796
|
+
/** Addon id whose declared test answered — `null` when none did. Lets the UI
|
|
21797
|
+
* attribute a result instead of blaming "the integration". */
|
|
21798
|
+
testedBy: zod.z.string().nullable().optional(),
|
|
21799
|
+
latencyMs: zod.z.number().nonnegative().optional(),
|
|
21800
|
+
/** Human detail from a `validated` result ("3 devices on this account"). */
|
|
21801
|
+
detail: zod.z.string().optional()
|
|
21469
21802
|
});
|
|
21470
21803
|
var CreateIntegrationInputSchema = zod.z.object({
|
|
21471
21804
|
addonId: zod.z.string(),
|
|
@@ -29780,6 +30113,7 @@ var CAPABILITY_NAMES = {
|
|
|
29780
30113
|
carbonMonoxide: "carbon-monoxide",
|
|
29781
30114
|
climateControl: "climate-control",
|
|
29782
30115
|
color: "color",
|
|
30116
|
+
connectionTest: "connection-test",
|
|
29783
30117
|
connectivity: "connectivity",
|
|
29784
30118
|
consumables: "consumables",
|
|
29785
30119
|
contact: "contact",
|
|
@@ -30023,6 +30357,10 @@ var CAPABILITY_ROUTER_KEYS = [
|
|
|
30023
30357
|
key: "color",
|
|
30024
30358
|
name: "color"
|
|
30025
30359
|
},
|
|
30360
|
+
{
|
|
30361
|
+
key: "connectionTest",
|
|
30362
|
+
name: "connection-test"
|
|
30363
|
+
},
|
|
30026
30364
|
{
|
|
30027
30365
|
key: "connectivity",
|
|
30028
30366
|
name: "connectivity"
|
|
@@ -30529,6 +30867,7 @@ var ALL_CAPABILITY_DEFINITIONS = [
|
|
|
30529
30867
|
carbonMonoxideCapability,
|
|
30530
30868
|
climateControlCapability,
|
|
30531
30869
|
colorCapability,
|
|
30870
|
+
connectionTestCapability,
|
|
30532
30871
|
connectivityCapability,
|
|
30533
30872
|
consumablesCapability,
|
|
30534
30873
|
contactCapability,
|
|
@@ -31423,6 +31762,18 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
31423
31762
|
addonId: null,
|
|
31424
31763
|
access: "create"
|
|
31425
31764
|
},
|
|
31765
|
+
"connectionTest.describeTest": {
|
|
31766
|
+
capName: "connection-test",
|
|
31767
|
+
capScope: "system",
|
|
31768
|
+
addonId: null,
|
|
31769
|
+
access: "view"
|
|
31770
|
+
},
|
|
31771
|
+
"connectionTest.testSettings": {
|
|
31772
|
+
capName: "connection-test",
|
|
31773
|
+
capScope: "system",
|
|
31774
|
+
addonId: null,
|
|
31775
|
+
access: "create"
|
|
31776
|
+
},
|
|
31426
31777
|
"consumables.reset": {
|
|
31427
31778
|
capName: "consumables",
|
|
31428
31779
|
capScope: "device",
|
|
@@ -31813,6 +32164,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
31813
32164
|
addonId: null,
|
|
31814
32165
|
access: "create"
|
|
31815
32166
|
},
|
|
32167
|
+
"deviceManager.adoptionCancelJob": {
|
|
32168
|
+
capName: "device-manager",
|
|
32169
|
+
capScope: "system",
|
|
32170
|
+
addonId: null,
|
|
32171
|
+
access: "create"
|
|
32172
|
+
},
|
|
31816
32173
|
"deviceManager.adoptionListCandidateFilters": {
|
|
31817
32174
|
capName: "device-manager",
|
|
31818
32175
|
capScope: "system",
|
|
@@ -31825,6 +32182,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
31825
32182
|
addonId: null,
|
|
31826
32183
|
access: "view"
|
|
31827
32184
|
},
|
|
32185
|
+
"deviceManager.adoptionListJobs": {
|
|
32186
|
+
capName: "device-manager",
|
|
32187
|
+
capScope: "system",
|
|
32188
|
+
addonId: null,
|
|
32189
|
+
access: "view"
|
|
32190
|
+
},
|
|
31828
32191
|
"deviceManager.adoptionRefresh": {
|
|
31829
32192
|
capName: "device-manager",
|
|
31830
32193
|
capScope: "system",
|
|
@@ -31843,6 +32206,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
31843
32206
|
addonId: null,
|
|
31844
32207
|
access: "create"
|
|
31845
32208
|
},
|
|
32209
|
+
"deviceManager.adoptionStartJob": {
|
|
32210
|
+
capName: "device-manager",
|
|
32211
|
+
capScope: "system",
|
|
32212
|
+
addonId: null,
|
|
32213
|
+
access: "create"
|
|
32214
|
+
},
|
|
31846
32215
|
"deviceManager.allocateDeviceId": {
|
|
31847
32216
|
capName: "device-manager",
|
|
31848
32217
|
capScope: "system",
|
|
@@ -34981,6 +35350,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
34981
35350
|
addonId: null,
|
|
34982
35351
|
access: "view"
|
|
34983
35352
|
},
|
|
35353
|
+
"snapshot.getSnapshotLinks": {
|
|
35354
|
+
capName: "snapshot",
|
|
35355
|
+
capScope: "device",
|
|
35356
|
+
addonId: null,
|
|
35357
|
+
access: "view"
|
|
35358
|
+
},
|
|
34984
35359
|
"snapshot.getSnapshotOverview": {
|
|
34985
35360
|
capName: "snapshot",
|
|
34986
35361
|
capScope: "device",
|
|
@@ -36078,6 +36453,7 @@ var KNOWN_CAP_NAMES = [
|
|
|
36078
36453
|
"camera-streams",
|
|
36079
36454
|
"climate-control",
|
|
36080
36455
|
"color",
|
|
36456
|
+
"connection-test",
|
|
36081
36457
|
"consumables",
|
|
36082
36458
|
"control",
|
|
36083
36459
|
"core-blocks",
|
|
@@ -36247,6 +36623,7 @@ var SYSTEM_CAP_NAMES = [
|
|
|
36247
36623
|
"auth-provider",
|
|
36248
36624
|
"backup",
|
|
36249
36625
|
"broker",
|
|
36626
|
+
"connection-test",
|
|
36250
36627
|
"core-blocks",
|
|
36251
36628
|
"custom-model-registry",
|
|
36252
36629
|
"data-store-provider",
|
|
@@ -36518,6 +36895,10 @@ function createSystemProxy(api) {
|
|
|
36518
36895
|
getState: (input) => dispatch("broker", "getState", "query", input),
|
|
36519
36896
|
getStatus: (input) => dispatch("broker", "getStatus", "query", input)
|
|
36520
36897
|
},
|
|
36898
|
+
connectionTest: {
|
|
36899
|
+
testSettings: (input) => dispatch("connectionTest", "testSettings", "mutation", input),
|
|
36900
|
+
describeTest: (input) => dispatch("connectionTest", "describeTest", "query", input)
|
|
36901
|
+
},
|
|
36521
36902
|
coreBlocks: {
|
|
36522
36903
|
list: (input) => dispatch("coreBlocks", "list", "query", input),
|
|
36523
36904
|
get: (input) => dispatch("coreBlocks", "get", "query", input),
|
|
@@ -36587,6 +36968,9 @@ function createSystemProxy(api) {
|
|
|
36587
36968
|
adoptionRefresh: (input) => dispatch("deviceManager", "adoptionRefresh", "mutation", input),
|
|
36588
36969
|
adoptionAdopt: (input) => dispatch("deviceManager", "adoptionAdopt", "mutation", input),
|
|
36589
36970
|
adoptionRelease: (input) => dispatch("deviceManager", "adoptionRelease", "mutation", input),
|
|
36971
|
+
adoptionStartJob: (input) => dispatch("deviceManager", "adoptionStartJob", "mutation", input),
|
|
36972
|
+
adoptionListJobs: (input) => dispatch("deviceManager", "adoptionListJobs", "query", input),
|
|
36973
|
+
adoptionCancelJob: (input) => dispatch("deviceManager", "adoptionCancelJob", "mutation", input),
|
|
36590
36974
|
adoptionResync: (input) => dispatch("deviceManager", "adoptionResync", "mutation", input),
|
|
36591
36975
|
discoveryProviders: (input) => dispatch("deviceManager", "discoveryProviders", "query", input),
|
|
36592
36976
|
discoverAllProviders: (input) => dispatch("deviceManager", "discoverAllProviders", "mutation", input),
|
|
@@ -39211,10 +39595,14 @@ exports.AddonPageDeclarationSchema = AddonPageDeclarationSchema;
|
|
|
39211
39595
|
exports.AddonPageInfoSchema = AddonPageInfoSchema;
|
|
39212
39596
|
exports.AdoptionAdoptInputSchema = AdoptInputSchema;
|
|
39213
39597
|
exports.AdoptionAdoptResultSchema = AdoptResultSchema;
|
|
39598
|
+
exports.AdoptionCandidateResultSchema = AdoptionCandidateResultSchema;
|
|
39214
39599
|
exports.AdoptionFilterSchema = AdoptionFilterSchema;
|
|
39215
39600
|
exports.AdoptionGetCandidateInputSchema = GetCandidateInputSchema;
|
|
39601
|
+
exports.AdoptionJobSchema = AdoptionJobSchema;
|
|
39602
|
+
exports.AdoptionJobStateSchema = AdoptionJobStateSchema;
|
|
39216
39603
|
exports.AdoptionListCandidatesInputSchema = ListCandidatesInputSchema;
|
|
39217
39604
|
exports.AdoptionListCandidatesOutputSchema = ListCandidatesOutputSchema;
|
|
39605
|
+
exports.AdoptionOutcomeSchema = AdoptionOutcomeSchema;
|
|
39218
39606
|
exports.AdoptionReleaseInputSchema = ReleaseInputSchema;
|
|
39219
39607
|
exports.AdoptionStatusSchema = AdoptionStatusSchema;
|
|
39220
39608
|
exports.AgentLoadSummarySchema = AgentLoadSummarySchema;
|
|
@@ -39303,6 +39691,7 @@ exports.CAP_NODE_PIN_CONTEXT_KEY = require_sleep.CAP_NODE_PIN_CONTEXT_KEY;
|
|
|
39303
39691
|
exports.CAP_PROVIDER_KIND_MAP = CAP_PROVIDER_KIND_MAP;
|
|
39304
39692
|
exports.COCO_80_LABELS = COCO_80_LABELS;
|
|
39305
39693
|
exports.COCO_TO_MACRO = COCO_TO_MACRO;
|
|
39694
|
+
exports.CONNECTION_TEST_TIMEOUT_MS = CONNECTION_TEST_TIMEOUT_MS;
|
|
39306
39695
|
exports.CORE_BLOCKS_ADDON_ID = CORE_BLOCKS_ADDON_ID;
|
|
39307
39696
|
exports.CORE_BLOCK_ADDON_PREFIX = CORE_BLOCK_ADDON_PREFIX;
|
|
39308
39697
|
exports.CamProfileSchema = require_sleep.CamProfileSchema;
|
|
@@ -39355,6 +39744,9 @@ exports.ColorStatusSchema = ColorStatusSchema;
|
|
|
39355
39744
|
exports.ConfigEntrySchema = ConfigEntrySchema;
|
|
39356
39745
|
exports.ConfigSectionWithValuesSchema = ConfigSectionWithValuesSchema;
|
|
39357
39746
|
exports.ConfigTabDeclarationSchema = ConfigTabDeclarationSchema;
|
|
39747
|
+
exports.ConnectionTestDescriptorSchema = ConnectionTestDescriptorSchema;
|
|
39748
|
+
exports.ConnectionTestInputSchema = ConnectionTestInputSchema;
|
|
39749
|
+
exports.ConnectionTestOutcomeSchema = ConnectionTestOutcomeSchema;
|
|
39358
39750
|
exports.ConnectivityStatusSchema = ConnectivityStatusSchema;
|
|
39359
39751
|
exports.ConsumableItemSchema = ConsumableItemSchema;
|
|
39360
39752
|
exports.ConsumablesStatusSchema = ConsumablesStatusSchema;
|
|
@@ -39920,6 +40312,7 @@ exports.TemperatureSensorStatusSchema = TemperatureSensorStatusSchema;
|
|
|
39920
40312
|
exports.TerminalProfileInfoSchema = TerminalProfileInfoSchema;
|
|
39921
40313
|
exports.TerminalSessionInfoSchema = TerminalSessionInfoSchema;
|
|
39922
40314
|
exports.TestConnectionResultSchema = TestConnectionResultSchema$1;
|
|
40315
|
+
exports.TestConnectionStatusEnum = TestConnectionStatusEnum;
|
|
39923
40316
|
exports.TestResultSchema = TestResultSchema;
|
|
39924
40317
|
exports.TimelapseRuleInputSchema = TimelapseRuleInputSchema;
|
|
39925
40318
|
exports.TimelapseRulePatchSchema = TimelapseRulePatchSchema;
|
|
@@ -40059,6 +40452,7 @@ exports.colorForKind = colorForKind;
|
|
|
40059
40452
|
exports.compileExpression = compileExpression;
|
|
40060
40453
|
exports.compileExpressionSafe = compileExpressionSafe;
|
|
40061
40454
|
exports.conditionDepth = conditionDepth;
|
|
40455
|
+
exports.connectionTestCapability = connectionTestCapability;
|
|
40062
40456
|
exports.connectivityCapability = connectivityCapability;
|
|
40063
40457
|
exports.consumablesCapability = consumablesCapability;
|
|
40064
40458
|
exports.contactCapability = contactCapability;
|