@camstack/addon-import-alexa 0.2.194 → 0.2.195
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 +7 -0
- package/dist/addon.js +128 -408
- package/dist/addon.mjs +128 -408
- package/package.json +2 -2
package/dist/addon.mjs
CHANGED
|
@@ -46,7 +46,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
46
46
|
var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
47
47
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
48
48
|
//#endregion
|
|
49
|
-
//#region ../types/dist/event-category-
|
|
49
|
+
//#region ../types/dist/event-category-78tcBemo.mjs
|
|
50
50
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
51
51
|
EventCategory["SystemBoot"] = "system.boot";
|
|
52
52
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -167,6 +167,23 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
167
167
|
*/
|
|
168
168
|
EventCategory["AddonLoadRecovered"] = "addon.load-recovered";
|
|
169
169
|
/**
|
|
170
|
+
* An addon is RUNNING although its installed package is below what the
|
|
171
|
+
* running server requires (`camstack.requires.addons` of the server, or the
|
|
172
|
+
* addon's own `requires.server`). Raised once per streak by the unsupported-
|
|
173
|
+
* addon tracker, on the hub and on agents; AlertCenter turns it into one
|
|
174
|
+
* operator alert per node and package. The addon is never held back for it.
|
|
175
|
+
*
|
|
176
|
+
* Payload: `{ packageName, addonId, nodeId, installedVersion, requiredMinimum, serverVersion, unmet }`.
|
|
177
|
+
*/
|
|
178
|
+
EventCategory["AddonUnsupportedVersion"] = "addon.unsupported-version";
|
|
179
|
+
/**
|
|
180
|
+
* The package of an {@link AddonUnsupportedVersion} alert reached a supported
|
|
181
|
+
* version, or is no longer installed on the node. AlertCenter dismisses the matching alert.
|
|
182
|
+
*
|
|
183
|
+
* Payload: `{ packageName, addonId, nodeId }`.
|
|
184
|
+
*/
|
|
185
|
+
EventCategory["AddonUnsupportedResolved"] = "addon.unsupported-resolved";
|
|
186
|
+
/**
|
|
170
187
|
* Monitor scheduled the next retry for a failed addon. Transient —
|
|
171
188
|
* surfaced to the UI for live-updating the "next retry in Ns"
|
|
172
189
|
* countdown on the Addons page row, NOT persisted as an alert.
|
|
@@ -277,7 +294,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
277
294
|
EventCategory["ProcessRestarted"] = "process.restarted";
|
|
278
295
|
/**
|
|
279
296
|
* The SET of storage locations changed — one was created, edited, enabled,
|
|
280
|
-
* disabled or deleted through
|
|
297
|
+
* disabled or deleted through the location instances or the forced-delete action.
|
|
281
298
|
*
|
|
282
299
|
* Telemetry, not a transaction (D8/D11): every consumer that re-resolves on
|
|
283
300
|
* it must also converge on its own periodic path, because a dropped event
|
|
@@ -6042,7 +6059,7 @@ function number(params) {
|
|
|
6042
6059
|
return /* @__PURE__ */ _coercedNumber(ZodNumber, params);
|
|
6043
6060
|
}
|
|
6044
6061
|
//#endregion
|
|
6045
|
-
//#region ../types/dist/sleep-
|
|
6062
|
+
//#region ../types/dist/sleep-AEnTN3b4.mjs
|
|
6046
6063
|
/**
|
|
6047
6064
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6048
6065
|
* window to float samples (D455).
|
|
@@ -7306,17 +7323,35 @@ var RecordIntegrationInstances = class {
|
|
|
7306
7323
|
...kind !== void 0 ? { kind } : {}
|
|
7307
7324
|
});
|
|
7308
7325
|
if (minted === void 0) throw new Error("createInstance needs an id: this provider does not mint one");
|
|
7326
|
+
const initial = this.hooks.initialBody(name, kind);
|
|
7327
|
+
const patch = this.patchOf(values ?? {});
|
|
7328
|
+
if (Object.keys(patch).length > 0) Object.assign(patch, await this.hooks.validateWrite?.({
|
|
7329
|
+
kind,
|
|
7330
|
+
body: {
|
|
7331
|
+
...initial,
|
|
7332
|
+
...patch
|
|
7333
|
+
}
|
|
7334
|
+
}));
|
|
7309
7335
|
await this.handle.put({
|
|
7310
7336
|
id: minted,
|
|
7311
|
-
data:
|
|
7337
|
+
data: initial
|
|
7312
7338
|
}, { ifRev: 0 });
|
|
7313
|
-
const patch = this.patchOf(values ?? {});
|
|
7314
7339
|
if (Object.keys(patch).length > 0) await this.handle.patch(minted, patch);
|
|
7315
7340
|
await this.hooks.onChanged?.(minted, "created");
|
|
7316
7341
|
return { id: minted };
|
|
7317
7342
|
};
|
|
7318
7343
|
updateInstance = async ({ id, name, values }) => {
|
|
7319
7344
|
const patch = this.patchOf(values);
|
|
7345
|
+
if (this.hooks.validateWrite !== void 0 && Object.keys(patch).length > 0) {
|
|
7346
|
+
const stored = await this.handle.get(id);
|
|
7347
|
+
if (stored !== null) Object.assign(patch, await this.hooks.validateWrite({
|
|
7348
|
+
kind: void 0,
|
|
7349
|
+
body: {
|
|
7350
|
+
...stored.data,
|
|
7351
|
+
...patch
|
|
7352
|
+
}
|
|
7353
|
+
}));
|
|
7354
|
+
}
|
|
7320
7355
|
if (name !== void 0) patch[this.nameField] = name;
|
|
7321
7356
|
await this.handle.patch(id, patch);
|
|
7322
7357
|
await this.hooks.onChanged?.(id, "updated");
|
|
@@ -10662,7 +10697,6 @@ var CAP_NAMES = Object.freeze([
|
|
|
10662
10697
|
"notifier",
|
|
10663
10698
|
"numeric-sensor",
|
|
10664
10699
|
"oauth-integration",
|
|
10665
|
-
"oidc-connections",
|
|
10666
10700
|
"osd",
|
|
10667
10701
|
"osd-manager",
|
|
10668
10702
|
"pet-feeder",
|
|
@@ -12554,8 +12588,7 @@ Object.freeze({
|
|
|
12554
12588
|
"device-provider": { "reloadDevice": 18e4 },
|
|
12555
12589
|
"llm": {
|
|
12556
12590
|
"generate": 6e5,
|
|
12557
|
-
"generateVision": 6e5
|
|
12558
|
-
"testProfile": 6e5
|
|
12591
|
+
"generateVision": 6e5
|
|
12559
12592
|
},
|
|
12560
12593
|
"llm-runtime": {
|
|
12561
12594
|
"complete": 6e5,
|
|
@@ -14166,17 +14199,18 @@ function composeInstanceKinds(parts, base) {
|
|
|
14166
14199
|
* message to what the kind supports — callers never special-case a service.
|
|
14167
14200
|
*
|
|
14168
14201
|
* DESIGN DECISIONS (locked):
|
|
14169
|
-
* -
|
|
14170
|
-
*
|
|
14171
|
-
*
|
|
14172
|
-
*
|
|
14173
|
-
*
|
|
14174
|
-
*
|
|
14175
|
-
*
|
|
14176
|
-
*
|
|
14177
|
-
*
|
|
14178
|
-
* routable. `send` / `testTarget` /
|
|
14179
|
-
* `
|
|
14202
|
+
* - A target is an INSTANCE of this function cap (epic #440, step 6): the
|
|
14203
|
+
* providers serve their targets as `integration-instances` records, one
|
|
14204
|
+
* record kind per target kind, and the admin lists, adds, edits, switches
|
|
14205
|
+
* and deletes them through that cap. This cap keeps what an instance cannot
|
|
14206
|
+
* say: the kind catalogue (`listTargetKinds`: capabilities, delivery
|
|
14207
|
+
* parameters, brand icon), dispatch (`send`, `testTarget`) and the form
|
|
14208
|
+
* helpers (`discoverTargets`, `probeTargetConfig`).
|
|
14209
|
+
* - `listTargetKinds` / `discoverTargets` return arrays → the generated
|
|
14210
|
+
* cap-mount auto-`concatCollection`-fans them across every registered
|
|
14211
|
+
* provider so one catalog is routable. `send` / `testTarget` /
|
|
14212
|
+
* `probeTargetConfig` route to ONE provider by the `addonId` the generated
|
|
14213
|
+
* collection router extracts from the call input.
|
|
14180
14214
|
* - `Attachment.bytes` is `Uint8Array`. Transport-safe: superjson (the tRPC
|
|
14181
14215
|
* transformer) + UDS MsgPack both round-trip typed arrays — already used by
|
|
14182
14216
|
* `storage` / `storage-provider` / `recording` caps over the same path. No
|
|
@@ -14421,7 +14455,7 @@ var TargetKindCapsSchema = object({
|
|
|
14421
14455
|
* the union is large and not meant for runtime validation here; the exported
|
|
14422
14456
|
* `TargetKind` type re-tightens `configSchema` to `ConfigUISchema`.
|
|
14423
14457
|
*/
|
|
14424
|
-
var ConfigSchemaPassthrough$
|
|
14458
|
+
var ConfigSchemaPassthrough$3 = unknown();
|
|
14425
14459
|
var TargetKindSchema = object({
|
|
14426
14460
|
kind: string(),
|
|
14427
14461
|
label: string(),
|
|
@@ -14458,7 +14492,7 @@ var TargetKindSchema = object({
|
|
|
14458
14492
|
* its raster path, which is the safe default for an unknown image.
|
|
14459
14493
|
*/
|
|
14460
14494
|
iconMediaType: string().optional(),
|
|
14461
|
-
configSchema: ConfigSchemaPassthrough$
|
|
14495
|
+
configSchema: ConfigSchemaPassthrough$3,
|
|
14462
14496
|
/**
|
|
14463
14497
|
* The config keys that decide WHERE this kind's secrets are sent (server,
|
|
14464
14498
|
* base URL, instance, chat, recipient). A save that changes any of them
|
|
@@ -14480,9 +14514,11 @@ var TargetKindSchema = object({
|
|
|
14480
14514
|
caps: TargetKindCapsSchema
|
|
14481
14515
|
});
|
|
14482
14516
|
/**
|
|
14483
|
-
* A
|
|
14484
|
-
*
|
|
14485
|
-
*
|
|
14517
|
+
* A target as a provider's own code sees it (the notification-center bridge, the
|
|
14518
|
+
* send path): the flat record body split into the name, the switch and the
|
|
14519
|
+
* kind's fields. `config` holds secrets; a reader that serves it to a client
|
|
14520
|
+
* REDACTS secret fields (a presence marker only) — never round-trip a stored
|
|
14521
|
+
* secret to the UI.
|
|
14486
14522
|
*/
|
|
14487
14523
|
var TargetSchema = object({
|
|
14488
14524
|
id: string(),
|
|
@@ -14531,21 +14567,13 @@ var notificationOutputCapability = {
|
|
|
14531
14567
|
mode: "collection",
|
|
14532
14568
|
methods: {
|
|
14533
14569
|
listTargetKinds: method(object({}), array(TargetKindSchema)),
|
|
14534
|
-
listTargets: method(object({}), array(TargetSchema), { auth: "admin" }),
|
|
14535
|
-
/**
|
|
14536
|
-
* One target WITH secrets — admin edit / duplicate hydration only.
|
|
14537
|
-
* `listTargets` stays redacted; the editor loads this so password fields
|
|
14538
|
-
* are filled (masked in the input) and a save can round-trip the token
|
|
14539
|
-
* when a destination changes (Duplicate with a new chatId, etc.).
|
|
14540
|
-
*/
|
|
14541
|
-
getTarget: method(object({ targetId: string() }), TargetSchema, { auth: "admin" }),
|
|
14542
14570
|
discoverTargets: method(object({
|
|
14543
14571
|
kind: string(),
|
|
14544
14572
|
config: record(string(), unknown()).optional(),
|
|
14545
14573
|
/**
|
|
14546
14574
|
* When editing / duplicating, the blank password field never round-trips
|
|
14547
14575
|
* the stored token. Pass the source target id so the provider can restore
|
|
14548
|
-
* secrets server-side before dialling
|
|
14576
|
+
* secrets server-side before dialling.
|
|
14549
14577
|
*/
|
|
14550
14578
|
targetId: string().optional()
|
|
14551
14579
|
}), array(DiscoveredTargetSchema), { auth: "admin" }),
|
|
@@ -14571,30 +14599,6 @@ var notificationOutputCapability = {
|
|
|
14571
14599
|
}), TestResultSchema, {
|
|
14572
14600
|
kind: "mutation",
|
|
14573
14601
|
auth: "admin"
|
|
14574
|
-
}),
|
|
14575
|
-
upsertTarget: method(object({
|
|
14576
|
-
target: TargetSchema,
|
|
14577
|
-
/**
|
|
14578
|
-
* Duplicate flow: create a NEW target id while copying secrets from an
|
|
14579
|
-
* existing row. The UI never holds the stored token; blank / redacted
|
|
14580
|
-
* password fields are restored from this source (D634 still applies if
|
|
14581
|
-
* destinations diverge without a re-typed secret).
|
|
14582
|
-
*/
|
|
14583
|
-
cloneSecretsFrom: string().optional()
|
|
14584
|
-
}), TargetSchema, {
|
|
14585
|
-
kind: "mutation",
|
|
14586
|
-
auth: "admin"
|
|
14587
|
-
}),
|
|
14588
|
-
deleteTarget: method(object({ targetId: string() }), _void(), {
|
|
14589
|
-
kind: "mutation",
|
|
14590
|
-
auth: "admin"
|
|
14591
|
-
}),
|
|
14592
|
-
setTargetEnabled: method(object({
|
|
14593
|
-
targetId: string(),
|
|
14594
|
-
enabled: boolean()
|
|
14595
|
-
}), _void(), {
|
|
14596
|
-
kind: "mutation",
|
|
14597
|
-
auth: "admin"
|
|
14598
14602
|
})
|
|
14599
14603
|
}
|
|
14600
14604
|
};
|
|
@@ -14610,8 +14614,9 @@ var notificationOutputCapability = {
|
|
|
14610
14614
|
*
|
|
14611
14615
|
* Three providers (notifiers, Home Assistant, Alexa) serve the same shape, so the pieces are shared:
|
|
14612
14616
|
* - {@link defineNotificationTargetKind}: the record kind of one `TargetKind` descriptor;
|
|
14613
|
-
* - {@link NotificationTargetStore}: the `Target`-shaped facade the
|
|
14614
|
-
* using, over one handle per kind
|
|
14617
|
+
* - {@link NotificationTargetStore}: the `Target`-shaped facade the provider's own code keeps
|
|
14618
|
+
* using (send, the notification-center bridge), over one handle per kind;
|
|
14619
|
+
* - {@link listNotificationTargets}: the targets as an addon on `ctx.api` reads them;
|
|
14615
14620
|
* - {@link buildNotificationTargetInstances}: the `integration-instances` provider, one kind each;
|
|
14616
14621
|
* - {@link moveTargetRows}: the D987 procedure that flattens the old `config` blobs into the bodies.
|
|
14617
14622
|
*/
|
|
@@ -14868,6 +14873,10 @@ function notificationTargetParts(records, spec) {
|
|
|
14868
14873
|
initialBody: (name) => ({ name }),
|
|
14869
14874
|
mintId: () => spec.mintId(),
|
|
14870
14875
|
configured: () => true,
|
|
14876
|
+
validateWrite: ({ body }) => spec.validate?.({
|
|
14877
|
+
kind: descriptor.kind,
|
|
14878
|
+
config: body
|
|
14879
|
+
}),
|
|
14871
14880
|
test: async ({ id, values }) => {
|
|
14872
14881
|
if (spec.probe === void 0 || !canTest) return {
|
|
14873
14882
|
success: false,
|
|
@@ -23263,7 +23272,6 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
23263
23272
|
"notification-output": system("notification delivery — reached through notifier devices and rules"),
|
|
23264
23273
|
"notification-rules": system("notification rules — authored on their own page"),
|
|
23265
23274
|
"oauth-integration": system(IDENTITY),
|
|
23266
|
-
"oidc-connections": system(IDENTITY),
|
|
23267
23275
|
"osd-manager": system(PIPELINE),
|
|
23268
23276
|
"pipeline-executor": system(PIPELINE),
|
|
23269
23277
|
"pipeline-orchestrator": system(PIPELINE),
|
|
@@ -57055,7 +57063,7 @@ method(_void(), array(IntegrationWithStateSchema)), method(object({ id: string()
|
|
|
57055
57063
|
* or the redaction token KEEPS the stored secret; `{ $secretClear: true }`
|
|
57056
57064
|
* clears it.
|
|
57057
57065
|
*/
|
|
57058
|
-
var ConfigSchemaPassthrough$
|
|
57066
|
+
var ConfigSchemaPassthrough$2 = custom();
|
|
57059
57067
|
var IntegrationInstanceIdSchema = string().min(1);
|
|
57060
57068
|
var IntegrationInstanceModeSchema = _enum(["single", "multiple"]);
|
|
57061
57069
|
/**
|
|
@@ -57101,7 +57109,16 @@ var IntegrationInstanceKindSchema = object({
|
|
|
57101
57109
|
/** Relative hub path to start an interactive account link of an instance of this kind. */
|
|
57102
57110
|
connectPath: string().min(1).optional(),
|
|
57103
57111
|
/** Relative hub path to disconnect that account. */
|
|
57104
|
-
disconnectPath: string().min(1).optional()
|
|
57112
|
+
disconnectPath: string().min(1).optional(),
|
|
57113
|
+
/**
|
|
57114
|
+
* Parts of the edit dialog the flat form cannot draw (a node picker, a model source), named by a
|
|
57115
|
+
* GENERIC widget id the client maps to a component; a client that knows none of them shows none.
|
|
57116
|
+
* `connection` widgets write connection values, `model` widgets own the model choice.
|
|
57117
|
+
*/
|
|
57118
|
+
widgets: array(object({
|
|
57119
|
+
id: string().min(1),
|
|
57120
|
+
placement: _enum(["connection", "model"])
|
|
57121
|
+
})).optional()
|
|
57105
57122
|
});
|
|
57106
57123
|
/**
|
|
57107
57124
|
* How devices of an instance are found. `none`: the operator adds them by hand; `lan`: the addon
|
|
@@ -57206,7 +57223,7 @@ var integrationInstancesCapability = {
|
|
|
57206
57223
|
id: IntegrationInstanceIdSchema.nullable(),
|
|
57207
57224
|
/** The kind of the create form (`id: null`) of a provider with several. */
|
|
57208
57225
|
kind: string().min(1).optional()
|
|
57209
|
-
}), ConfigSchemaPassthrough$
|
|
57226
|
+
}), ConfigSchemaPassthrough$2, { auth: "admin" }),
|
|
57210
57227
|
listInstances: method(_void(), array(IntegrationInstanceSchema).readonly(), { auth: "admin" }),
|
|
57211
57228
|
getInstance: method(object({ id: IntegrationInstanceIdSchema }), IntegrationInstanceSchema.nullable(), { auth: "admin" }),
|
|
57212
57229
|
/**
|
|
@@ -58308,12 +58325,12 @@ var LlmModelInfoSchema = object({
|
|
|
58308
58325
|
});
|
|
58309
58326
|
/**
|
|
58310
58327
|
* The provider-specific part of a profile, validated by the provider that owns
|
|
58311
|
-
* the kind (
|
|
58328
|
+
* the kind (saving an instance refuses what it does not accept). A field its
|
|
58312
58329
|
* `connectionSchema` declares `type: 'password'` is a secret: it is held in the
|
|
58313
58330
|
* keychain, never in the row, and reads back as the redaction marker.
|
|
58314
58331
|
*/
|
|
58315
58332
|
var LlmProviderConfigSchema = record(string(), unknown());
|
|
58316
|
-
|
|
58333
|
+
object({
|
|
58317
58334
|
id: string(),
|
|
58318
58335
|
name: string(),
|
|
58319
58336
|
/** The provider-declared kind (`LlmProfileKindDescriptor.kind`). */
|
|
@@ -58407,8 +58424,8 @@ var LlmProviderWidgetSchema = object({
|
|
|
58407
58424
|
/** ConfigUISchema tree passed through untyped on the wire (the
|
|
58408
58425
|
* notification-output `ConfigSchemaPassthrough` precedent at
|
|
58409
58426
|
* notification-output.cap.ts:151); the exported TS type re-tightens it. */
|
|
58410
|
-
var ConfigSchemaPassthrough$
|
|
58411
|
-
|
|
58427
|
+
var ConfigSchemaPassthrough$1 = unknown();
|
|
58428
|
+
object({
|
|
58412
58429
|
kind: LlmProfileKindSchema,
|
|
58413
58430
|
label: string(),
|
|
58414
58431
|
/** A generic icon name (`cloud`, `plug`, `cpu`) — never a glyph or a logo. */
|
|
@@ -58416,9 +58433,9 @@ var LlmProfileKindDescriptorSchema = object({
|
|
|
58416
58433
|
/** Stamped by each provider so the concat-fanned catalog stays routable. */
|
|
58417
58434
|
addonId: string(),
|
|
58418
58435
|
/** The provider's own fields (`providerConfig`); `password` fields are keychain-held. */
|
|
58419
|
-
connectionSchema: ConfigSchemaPassthrough$
|
|
58436
|
+
connectionSchema: ConfigSchemaPassthrough$1,
|
|
58420
58437
|
/** Provider fields that belong under "Advanced" (extra headers, runtime tuning). */
|
|
58421
|
-
advancedSchema: ConfigSchemaPassthrough$
|
|
58438
|
+
advancedSchema: ConfigSchemaPassthrough$1.optional(),
|
|
58422
58439
|
/** The kind's defaults; a model from `listModels` may override any of them. */
|
|
58423
58440
|
features: LlmModelFeaturesSchema,
|
|
58424
58441
|
/** `false` = the provider stamps `supportsVision` itself (from what a node reports). */
|
|
@@ -58547,20 +58564,7 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, {
|
|
|
58547
58564
|
}), method(object({
|
|
58548
58565
|
addonId: string().optional(),
|
|
58549
58566
|
requestId: string()
|
|
58550
|
-
}), _void(), { kind: "mutation" }), method(
|
|
58551
|
-
kind: "mutation",
|
|
58552
|
-
auth: "admin"
|
|
58553
|
-
}), method(RawSecretMigrationInputSchema, RawSecretMigrationReportSchema, {
|
|
58554
|
-
kind: "mutation",
|
|
58555
|
-
auth: "admin"
|
|
58556
|
-
}), method(ProfileRefInputSchema, _void(), {
|
|
58557
|
-
kind: "mutation",
|
|
58558
|
-
auth: "admin"
|
|
58559
|
-
}), method(ProfileRefInputSchema, LlmGenerateResultSchema, {
|
|
58560
|
-
kind: "mutation",
|
|
58561
|
-
auth: "admin",
|
|
58562
|
-
timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
|
|
58563
|
-
}), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
|
|
58567
|
+
}), _void(), { kind: "mutation" }), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
|
|
58564
58568
|
kind: "mutation",
|
|
58565
58569
|
auth: "admin"
|
|
58566
58570
|
}), method(object({}), array(LlmDefaultSchema)), method(object({
|
|
@@ -59623,20 +59627,7 @@ method(_void(), MeshStatusSchema), method(object({
|
|
|
59623
59627
|
/** Optional hostname override the host should advertise once joined. */
|
|
59624
59628
|
hostname: string().optional() }), object({
|
|
59625
59629
|
/** Authentication URL the operator should open in a browser. */
|
|
59626
|
-
loginUrl: string() }), { kind: "mutation" }), method(_void(), object({ left: literal(true) }), { kind: "mutation" }), method(_void(), object({ loggedOut: literal(true) }), { kind: "mutation" }), method(_void(), object({ peers: array(MeshPeerSchema).readonly() }))
|
|
59627
|
-
/** Optional auth key — when provided, probes the key validity
|
|
59628
|
-
* against the provider's API. Omit when already joined to
|
|
59629
|
-
* just ping the daemon. */
|
|
59630
|
-
authKey: string().optional() }), object({
|
|
59631
|
-
ok: boolean(),
|
|
59632
|
-
/** Provider-side identifier resolved by the probe (tailnet
|
|
59633
|
-
* name for Tailscale, network id for ZeroTier, etc.). */
|
|
59634
|
-
tenant: string().optional(),
|
|
59635
|
-
/** Daemon binary version, when reachable. */
|
|
59636
|
-
daemonVersion: string().optional(),
|
|
59637
|
-
/** Human-readable error when `ok: false`. */
|
|
59638
|
-
error: string().optional()
|
|
59639
|
-
}), { kind: "mutation" });
|
|
59630
|
+
loginUrl: string() }), { kind: "mutation" }), method(_void(), object({ left: literal(true) }), { kind: "mutation" }), method(_void(), object({ loggedOut: literal(true) }), { kind: "mutation" }), method(_void(), object({ peers: array(MeshPeerSchema).readonly() }));
|
|
59640
59631
|
/**
|
|
59641
59632
|
* A monotonic total between resets (D944). Energy uses `power-meter.energy`
|
|
59642
59633
|
* so dashboards keep one series; every other instantaneous reading lands here.
|
|
@@ -69843,61 +69834,6 @@ var OauthIntegrationDescriptorSchema = object({
|
|
|
69843
69834
|
});
|
|
69844
69835
|
method(_void(), OauthIntegrationDescriptorSchema, { auth: "admin" });
|
|
69845
69836
|
/**
|
|
69846
|
-
* `oidc-connections` — CRUD for IdP rows under `auth-oidc` (D828 sibling).
|
|
69847
|
-
*
|
|
69848
|
-
* One hub-only singleton (`auth-oidc`). The Settings UI is a DataTable +
|
|
69849
|
-
* ItemFormDialog; there is no `editable-array` in `globalSettingsSchema`.
|
|
69850
|
-
* Operator-chosen `id` is the URL slug (`/addon/auth-oidc/<id>/…`) and is
|
|
69851
|
-
* immutable after create.
|
|
69852
|
-
*/
|
|
69853
|
-
var ConfigSchemaPassthrough$1 = unknown();
|
|
69854
|
-
var OidcConnectionSchema = object({
|
|
69855
|
-
id: string().min(1),
|
|
69856
|
-
displayName: string(),
|
|
69857
|
-
icon: string(),
|
|
69858
|
-
issuerUrl: string(),
|
|
69859
|
-
clientId: string(),
|
|
69860
|
-
/** Client id + secret present — never the secret value. */
|
|
69861
|
-
configured: boolean(),
|
|
69862
|
-
/**
|
|
69863
|
-
* Values for the connection form schema. `clientSecret` is a keychain
|
|
69864
|
-
* {@link SecretFieldView} or `null` / `''`, never plaintext (D789).
|
|
69865
|
-
*/
|
|
69866
|
-
formValues: record(string(), unknown()).optional()
|
|
69867
|
-
});
|
|
69868
|
-
/**
|
|
69869
|
-
* Patch one connection. Omitted or empty `clientSecret` keeps the stored
|
|
69870
|
-
* secret (D787). `{ $secretClear: true }` clears it. `id` is never renamed.
|
|
69871
|
-
*/
|
|
69872
|
-
var OidcConnectionUpdateInputSchema = object({
|
|
69873
|
-
id: string().min(1),
|
|
69874
|
-
displayName: string().min(1),
|
|
69875
|
-
icon: string().optional(),
|
|
69876
|
-
issuerUrl: string().optional(),
|
|
69877
|
-
clientId: string().optional(),
|
|
69878
|
-
clientSecret: union([string(), object({ $secretClear: literal(true) })]).optional(),
|
|
69879
|
-
redirectUri: string().optional(),
|
|
69880
|
-
scopes: string().optional(),
|
|
69881
|
-
usernameClaim: _enum([
|
|
69882
|
-
"preferred_username",
|
|
69883
|
-
"email",
|
|
69884
|
-
"sub"
|
|
69885
|
-
]).optional()
|
|
69886
|
-
});
|
|
69887
|
-
method(object({}), ConfigSchemaPassthrough$1, { auth: "admin" }), method(object({}), array(OidcConnectionSchema).readonly(), { auth: "admin" }), method(object({
|
|
69888
|
-
id: string().min(1).regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "id must be a lowercase slug"),
|
|
69889
|
-
displayName: string().min(1)
|
|
69890
|
-
}), object({ id: string() }), {
|
|
69891
|
-
kind: "mutation",
|
|
69892
|
-
auth: "admin"
|
|
69893
|
-
}), method(OidcConnectionUpdateInputSchema, object({ ok: literal(true) }), {
|
|
69894
|
-
kind: "mutation",
|
|
69895
|
-
auth: "admin"
|
|
69896
|
-
}), method(object({ id: string().min(1) }), object({ ok: literal(true) }), {
|
|
69897
|
-
kind: "mutation",
|
|
69898
|
-
auth: "admin"
|
|
69899
|
-
});
|
|
69900
|
-
/**
|
|
69901
69837
|
* Generic on-screen-display (video overlay) cap. Each camera exposes
|
|
69902
69838
|
* a firmware-defined list of overlays (channel name, timestamp,
|
|
69903
69839
|
* watermark, logo, …); the cap models them as a homogeneous array of
|
|
@@ -76979,21 +76915,6 @@ method(object({
|
|
|
76979
76915
|
*/
|
|
76980
76916
|
ttlSec: union([number$1().int().positive(), literal("never")]).optional()
|
|
76981
76917
|
}), object({ token: string() }), { auth: "admin" }), method(object({ token: string() }), SsoBridgeClaimsSchema.nullable(), { auth: "admin" });
|
|
76982
|
-
var ProviderListEntrySchema = discriminatedUnion("shouldSaveDiskSpace", [object({
|
|
76983
|
-
providerId: string().min(1),
|
|
76984
|
-
displayName: string().min(1),
|
|
76985
|
-
configSchema: unknown(),
|
|
76986
|
-
nodeLocal: boolean(),
|
|
76987
|
-
shouldSaveDiskSpace: literal(true),
|
|
76988
|
-
minFreePercent: number$1().min(0).max(100)
|
|
76989
|
-
}), object({
|
|
76990
|
-
providerId: string().min(1),
|
|
76991
|
-
displayName: string().min(1),
|
|
76992
|
-
configSchema: unknown(),
|
|
76993
|
-
nodeLocal: boolean(),
|
|
76994
|
-
shouldSaveDiskSpace: literal(false),
|
|
76995
|
-
minFreePercent: literal(null)
|
|
76996
|
-
})]);
|
|
76997
76918
|
method(object({
|
|
76998
76919
|
location: StorageLocationRefSchema,
|
|
76999
76920
|
relativePath: string()
|
|
@@ -77055,42 +76976,7 @@ method(object({
|
|
|
77055
76976
|
}), _instanceof(Uint8Array), { auth: "admin" }), method(object({ downloadId: string() }), _void(), {
|
|
77056
76977
|
kind: "mutation",
|
|
77057
76978
|
auth: "admin"
|
|
77058
|
-
}), method(object({ type: StorageLocationTypeSchema.optional() }), array(StorageLocationSchema).readonly()), method(_void(), array(StorageLocationDeclarationSchema).readonly()), method(
|
|
77059
|
-
createdAt: true,
|
|
77060
|
-
updatedAt: true
|
|
77061
|
-
}), StorageLocationSchema, {
|
|
77062
|
-
kind: "mutation",
|
|
77063
|
-
auth: "admin"
|
|
77064
|
-
}), method(object({
|
|
77065
|
-
id: string(),
|
|
77066
|
-
force: boolean().optional()
|
|
77067
|
-
}), _void(), {
|
|
77068
|
-
kind: "mutation",
|
|
77069
|
-
auth: "admin"
|
|
77070
|
-
}), method(_void(), array(StorageDrainProgressSchema).readonly()), method(object({ id: string() }), object({
|
|
77071
|
-
ok: boolean(),
|
|
77072
|
-
error: string().optional()
|
|
77073
|
-
}), { auth: "admin" }), method(_void(), array(ProviderListEntrySchema).readonly()), method(object({
|
|
77074
|
-
providerId: string(),
|
|
77075
|
-
/**
|
|
77076
|
-
* The location this config is an UNSAVED edit of, when there is one.
|
|
77077
|
-
*
|
|
77078
|
-
* `listLocations` replaces every declared secret with the redaction
|
|
77079
|
-
* sentinel, so the edit modal's form state holds the sentinel for any
|
|
77080
|
-
* credential the operator did not retype — and posting that here
|
|
77081
|
-
* without a way to resolve it makes the provider try to authenticate
|
|
77082
|
-
* as `__camstack_redacted__` and report the operator's own working
|
|
77083
|
-
* password as wrong. Given this id, the orchestrator restores each
|
|
77084
|
-
* sentinel from the stored config (same rule as `upsertLocation`)
|
|
77085
|
-
* before dispatching. Omitted by the "Add location" wizard, where
|
|
77086
|
-
* every value was typed just now and nothing is stored yet.
|
|
77087
|
-
*/
|
|
77088
|
-
locationId: string().optional(),
|
|
77089
|
-
config: record(string(), unknown())
|
|
77090
|
-
}), object({
|
|
77091
|
-
ok: boolean(),
|
|
77092
|
-
error: string().optional()
|
|
77093
|
-
}), { auth: "admin" });
|
|
76979
|
+
}), method(object({ type: StorageLocationTypeSchema.optional() }), array(StorageLocationSchema).readonly()), method(_void(), array(StorageLocationDeclarationSchema).readonly()), method(_void(), array(StorageDrainProgressSchema).readonly());
|
|
77094
76980
|
/** One table of the settings database. */
|
|
77095
76981
|
var StorageTableSchema = object({
|
|
77096
76982
|
/** The table's full name, e.g. `recorder:addon-settings` or `addon-device-settings`. */
|
|
@@ -86976,13 +86862,6 @@ Object.freeze({
|
|
|
86976
86862
|
access: "delete",
|
|
86977
86863
|
role: "admin"
|
|
86978
86864
|
},
|
|
86979
|
-
"llm.deleteProfile": {
|
|
86980
|
-
capName: "llm",
|
|
86981
|
-
capScope: "system",
|
|
86982
|
-
addonId: null,
|
|
86983
|
-
access: "delete",
|
|
86984
|
-
role: "admin"
|
|
86985
|
-
},
|
|
86986
86865
|
"llm.generate": {
|
|
86987
86866
|
capName: "llm",
|
|
86988
86867
|
capScope: "system",
|
|
@@ -87046,20 +86925,6 @@ Object.freeze({
|
|
|
87046
86925
|
access: "view",
|
|
87047
86926
|
role: "admin"
|
|
87048
86927
|
},
|
|
87049
|
-
"llm.listProfileKinds": {
|
|
87050
|
-
capName: "llm",
|
|
87051
|
-
capScope: "system",
|
|
87052
|
-
addonId: null,
|
|
87053
|
-
access: "view",
|
|
87054
|
-
role: "admin"
|
|
87055
|
-
},
|
|
87056
|
-
"llm.listProfiles": {
|
|
87057
|
-
capName: "llm",
|
|
87058
|
-
capScope: "system",
|
|
87059
|
-
addonId: null,
|
|
87060
|
-
access: "view",
|
|
87061
|
-
role: "admin"
|
|
87062
|
-
},
|
|
87063
86928
|
"llm.listRuntimeNodes": {
|
|
87064
86929
|
capName: "llm",
|
|
87065
86930
|
capScope: "system",
|
|
@@ -87067,13 +86932,6 @@ Object.freeze({
|
|
|
87067
86932
|
access: "view",
|
|
87068
86933
|
role: "admin"
|
|
87069
86934
|
},
|
|
87070
|
-
"llm.migrateRawSecrets": {
|
|
87071
|
-
capName: "llm",
|
|
87072
|
-
capScope: "system",
|
|
87073
|
-
addonId: null,
|
|
87074
|
-
access: "create",
|
|
87075
|
-
role: "admin"
|
|
87076
|
-
},
|
|
87077
86935
|
"llm.resolveModelRef": {
|
|
87078
86936
|
capName: "llm",
|
|
87079
86937
|
capScope: "system",
|
|
@@ -87102,20 +86960,6 @@ Object.freeze({
|
|
|
87102
86960
|
access: "create",
|
|
87103
86961
|
role: "admin"
|
|
87104
86962
|
},
|
|
87105
|
-
"llm.testProfile": {
|
|
87106
|
-
capName: "llm",
|
|
87107
|
-
capScope: "system",
|
|
87108
|
-
addonId: null,
|
|
87109
|
-
access: "create",
|
|
87110
|
-
role: "admin"
|
|
87111
|
-
},
|
|
87112
|
-
"llm.upsertProfile": {
|
|
87113
|
-
capName: "llm",
|
|
87114
|
-
capScope: "system",
|
|
87115
|
-
addonId: null,
|
|
87116
|
-
access: "create",
|
|
87117
|
-
role: "admin"
|
|
87118
|
-
},
|
|
87119
86963
|
"llmRuntime.appleAvailability": {
|
|
87120
86964
|
capName: "llm-runtime",
|
|
87121
86965
|
capScope: "system",
|
|
@@ -87620,13 +87464,6 @@ Object.freeze({
|
|
|
87620
87464
|
access: "create",
|
|
87621
87465
|
role: "admin"
|
|
87622
87466
|
},
|
|
87623
|
-
"meshNetwork.testConnection": {
|
|
87624
|
-
capName: "mesh-network",
|
|
87625
|
-
capScope: "system",
|
|
87626
|
-
addonId: null,
|
|
87627
|
-
access: "create",
|
|
87628
|
-
role: "admin"
|
|
87629
|
-
},
|
|
87630
87467
|
"meter.getStatus": {
|
|
87631
87468
|
capName: "meter",
|
|
87632
87469
|
capScope: "device",
|
|
@@ -88285,13 +88122,6 @@ Object.freeze({
|
|
|
88285
88122
|
access: "create",
|
|
88286
88123
|
role: "admin"
|
|
88287
88124
|
},
|
|
88288
|
-
"notificationOutput.deleteTarget": {
|
|
88289
|
-
capName: "notification-output",
|
|
88290
|
-
capScope: "system",
|
|
88291
|
-
addonId: null,
|
|
88292
|
-
access: "delete",
|
|
88293
|
-
role: "admin"
|
|
88294
|
-
},
|
|
88295
88125
|
"notificationOutput.discoverTargets": {
|
|
88296
88126
|
capName: "notification-output",
|
|
88297
88127
|
capScope: "system",
|
|
@@ -88299,13 +88129,6 @@ Object.freeze({
|
|
|
88299
88129
|
access: "view",
|
|
88300
88130
|
role: "admin"
|
|
88301
88131
|
},
|
|
88302
|
-
"notificationOutput.getTarget": {
|
|
88303
|
-
capName: "notification-output",
|
|
88304
|
-
capScope: "system",
|
|
88305
|
-
addonId: null,
|
|
88306
|
-
access: "view",
|
|
88307
|
-
role: "admin"
|
|
88308
|
-
},
|
|
88309
88132
|
"notificationOutput.listTargetKinds": {
|
|
88310
88133
|
capName: "notification-output",
|
|
88311
88134
|
capScope: "system",
|
|
@@ -88313,13 +88136,6 @@ Object.freeze({
|
|
|
88313
88136
|
access: "view",
|
|
88314
88137
|
role: "admin"
|
|
88315
88138
|
},
|
|
88316
|
-
"notificationOutput.listTargets": {
|
|
88317
|
-
capName: "notification-output",
|
|
88318
|
-
capScope: "system",
|
|
88319
|
-
addonId: null,
|
|
88320
|
-
access: "view",
|
|
88321
|
-
role: "admin"
|
|
88322
|
-
},
|
|
88323
88139
|
"notificationOutput.probeTargetConfig": {
|
|
88324
88140
|
capName: "notification-output",
|
|
88325
88141
|
capScope: "system",
|
|
@@ -88334,13 +88150,6 @@ Object.freeze({
|
|
|
88334
88150
|
access: "create",
|
|
88335
88151
|
role: "admin"
|
|
88336
88152
|
},
|
|
88337
|
-
"notificationOutput.setTargetEnabled": {
|
|
88338
|
-
capName: "notification-output",
|
|
88339
|
-
capScope: "system",
|
|
88340
|
-
addonId: null,
|
|
88341
|
-
access: "create",
|
|
88342
|
-
role: "admin"
|
|
88343
|
-
},
|
|
88344
88153
|
"notificationOutput.testTarget": {
|
|
88345
88154
|
capName: "notification-output",
|
|
88346
88155
|
capScope: "system",
|
|
@@ -88348,13 +88157,6 @@ Object.freeze({
|
|
|
88348
88157
|
access: "create",
|
|
88349
88158
|
role: "admin"
|
|
88350
88159
|
},
|
|
88351
|
-
"notificationOutput.upsertTarget": {
|
|
88352
|
-
capName: "notification-output",
|
|
88353
|
-
capScope: "system",
|
|
88354
|
-
addonId: null,
|
|
88355
|
-
access: "create",
|
|
88356
|
-
role: "admin"
|
|
88357
|
-
},
|
|
88358
88160
|
"notificationRules.activateAlarmProfile": {
|
|
88359
88161
|
capName: "notification-rules",
|
|
88360
88162
|
capScope: "system",
|
|
@@ -88614,41 +88416,6 @@ Object.freeze({
|
|
|
88614
88416
|
access: "view",
|
|
88615
88417
|
role: "admin"
|
|
88616
88418
|
},
|
|
88617
|
-
"oidcConnections.connectionFormSchema": {
|
|
88618
|
-
capName: "oidc-connections",
|
|
88619
|
-
capScope: "system",
|
|
88620
|
-
addonId: null,
|
|
88621
|
-
access: "view",
|
|
88622
|
-
role: "admin"
|
|
88623
|
-
},
|
|
88624
|
-
"oidcConnections.createConnection": {
|
|
88625
|
-
capName: "oidc-connections",
|
|
88626
|
-
capScope: "system",
|
|
88627
|
-
addonId: null,
|
|
88628
|
-
access: "create",
|
|
88629
|
-
role: "admin"
|
|
88630
|
-
},
|
|
88631
|
-
"oidcConnections.deleteConnection": {
|
|
88632
|
-
capName: "oidc-connections",
|
|
88633
|
-
capScope: "system",
|
|
88634
|
-
addonId: null,
|
|
88635
|
-
access: "delete",
|
|
88636
|
-
role: "admin"
|
|
88637
|
-
},
|
|
88638
|
-
"oidcConnections.listConnections": {
|
|
88639
|
-
capName: "oidc-connections",
|
|
88640
|
-
capScope: "system",
|
|
88641
|
-
addonId: null,
|
|
88642
|
-
access: "view",
|
|
88643
|
-
role: "admin"
|
|
88644
|
-
},
|
|
88645
|
-
"oidcConnections.updateConnection": {
|
|
88646
|
-
capName: "oidc-connections",
|
|
88647
|
-
capScope: "system",
|
|
88648
|
-
addonId: null,
|
|
88649
|
-
access: "create",
|
|
88650
|
-
role: "admin"
|
|
88651
|
-
},
|
|
88652
88419
|
"osd.getStatus": {
|
|
88653
88420
|
capName: "osd",
|
|
88654
88421
|
capScope: "device",
|
|
@@ -91680,13 +91447,6 @@ Object.freeze({
|
|
|
91680
91447
|
access: "delete",
|
|
91681
91448
|
role: "admin"
|
|
91682
91449
|
},
|
|
91683
|
-
"storage.deleteLocation": {
|
|
91684
|
-
capName: "storage",
|
|
91685
|
-
capScope: "system",
|
|
91686
|
-
addonId: null,
|
|
91687
|
-
access: "delete",
|
|
91688
|
-
role: "admin"
|
|
91689
|
-
},
|
|
91690
91450
|
"storage.endDownload": {
|
|
91691
91451
|
capName: "storage",
|
|
91692
91452
|
capScope: "system",
|
|
@@ -91743,13 +91503,6 @@ Object.freeze({
|
|
|
91743
91503
|
access: "view",
|
|
91744
91504
|
role: "admin"
|
|
91745
91505
|
},
|
|
91746
|
-
"storage.listProviders": {
|
|
91747
|
-
capName: "storage",
|
|
91748
|
-
capScope: "system",
|
|
91749
|
-
addonId: null,
|
|
91750
|
-
access: "view",
|
|
91751
|
-
role: "admin"
|
|
91752
|
-
},
|
|
91753
91506
|
"storage.read": {
|
|
91754
91507
|
capName: "storage",
|
|
91755
91508
|
capScope: "system",
|
|
@@ -91771,27 +91524,6 @@ Object.freeze({
|
|
|
91771
91524
|
access: "view",
|
|
91772
91525
|
role: "admin"
|
|
91773
91526
|
},
|
|
91774
|
-
"storage.testConfig": {
|
|
91775
|
-
capName: "storage",
|
|
91776
|
-
capScope: "system",
|
|
91777
|
-
addonId: null,
|
|
91778
|
-
access: "view",
|
|
91779
|
-
role: "admin"
|
|
91780
|
-
},
|
|
91781
|
-
"storage.testLocation": {
|
|
91782
|
-
capName: "storage",
|
|
91783
|
-
capScope: "system",
|
|
91784
|
-
addonId: null,
|
|
91785
|
-
access: "view",
|
|
91786
|
-
role: "admin"
|
|
91787
|
-
},
|
|
91788
|
-
"storage.upsertLocation": {
|
|
91789
|
-
capName: "storage",
|
|
91790
|
-
capScope: "system",
|
|
91791
|
-
addonId: null,
|
|
91792
|
-
access: "create",
|
|
91793
|
-
role: "admin"
|
|
91794
|
-
},
|
|
91795
91527
|
"storage.write": {
|
|
91796
91528
|
capName: "storage",
|
|
91797
91529
|
capScope: "system",
|
|
@@ -145519,6 +145251,33 @@ function quietLogger$1() {
|
|
|
145519
145251
|
};
|
|
145520
145252
|
return logger;
|
|
145521
145253
|
}
|
|
145254
|
+
/**
|
|
145255
|
+
* The account a target speaks through: the one it names; else the only one there is; else the one
|
|
145256
|
+
* whose Echoes include the target's Echo.
|
|
145257
|
+
*/
|
|
145258
|
+
function pickBroker(brokers, config) {
|
|
145259
|
+
const named = readString(config, "brokerId");
|
|
145260
|
+
if (named.length > 0) return brokers.find((broker) => broker.id === named);
|
|
145261
|
+
if (brokers.length === 1) return brokers[0];
|
|
145262
|
+
const echoId = readString(config, "echoId");
|
|
145263
|
+
const owners = brokers.filter((broker) => broker.devices.some((device) => device.id === echoId));
|
|
145264
|
+
return owners.length === 1 ? owners[0] : void 0;
|
|
145265
|
+
}
|
|
145266
|
+
/**
|
|
145267
|
+
* The save-time rule of an Echo target: an Echo and an account must be picked, and the account is
|
|
145268
|
+
* pinned the moment it is known, so a second account added later cannot silently change where an
|
|
145269
|
+
* existing target speaks. Throws the reason; returns the keys to keep with the write.
|
|
145270
|
+
*/
|
|
145271
|
+
function validateEchoTarget(brokers, config) {
|
|
145272
|
+
if (readString(config, "echoId").length === 0) throw new Error("Pick the Echo that should speak");
|
|
145273
|
+
const owner = pickBroker(brokers, config);
|
|
145274
|
+
if (owner === void 0) {
|
|
145275
|
+
const named = readString(config, "brokerId");
|
|
145276
|
+
if (named.length > 0) throw new Error(`The Amazon account ${named} is not available`);
|
|
145277
|
+
throw new Error(brokers.length === 0 ? "Add an Amazon account first: an Echo speaks through one" : "Pick the Amazon account this Echo belongs to");
|
|
145278
|
+
}
|
|
145279
|
+
return readString(config, "brokerId").length === 0 ? { brokerId: owner.id } : {};
|
|
145280
|
+
}
|
|
145522
145281
|
function readString(config, key) {
|
|
145523
145282
|
const value = config[key];
|
|
145524
145283
|
return typeof value === "string" ? value : "";
|
|
@@ -145548,7 +145307,7 @@ function echoOptionLabel(device) {
|
|
|
145548
145307
|
/**
|
|
145549
145308
|
* The two pickers are not `required`: a required select shows its first option
|
|
145550
145309
|
* while the form still holds no value, so a save would drop the choice. Left
|
|
145551
|
-
* optional they open on "Select", and `
|
|
145310
|
+
* optional they open on "Select", and `validateEchoTarget` refuses an empty pick on save.
|
|
145552
145311
|
*
|
|
145553
145312
|
* The account is a broker pick (existing, or created in place); the Echo list
|
|
145554
145313
|
* is fetched from that account, so a new Echo shows up without a deploy.
|
|
@@ -145640,18 +145399,8 @@ function createAlexaNotificationProvider(ports) {
|
|
|
145640
145399
|
function record(row) {
|
|
145641
145400
|
deliveries = [...deliveries, row];
|
|
145642
145401
|
}
|
|
145643
|
-
/**
|
|
145644
|
-
* The account a target speaks through: the one it names; else the only one
|
|
145645
|
-
* there is; else the one whose Echoes include the target's Echo.
|
|
145646
|
-
*/
|
|
145647
145402
|
function brokerFor(config) {
|
|
145648
|
-
|
|
145649
|
-
const named = readString(config, "brokerId");
|
|
145650
|
-
if (named.length > 0) return all.find((broker) => broker.id === named);
|
|
145651
|
-
if (all.length === 1) return all[0];
|
|
145652
|
-
const echoId = readString(config, "echoId");
|
|
145653
|
-
const owners = all.filter((broker) => broker.devices.some((device) => device.id === echoId));
|
|
145654
|
-
return owners.length === 1 ? owners[0] : void 0;
|
|
145403
|
+
return pickBroker(ports.brokers(), config);
|
|
145655
145404
|
}
|
|
145656
145405
|
async function deliver(target, notification) {
|
|
145657
145406
|
const speech = speechFromNotification(notification);
|
|
@@ -145853,14 +145602,6 @@ function createAlexaNotificationProvider(ports) {
|
|
|
145853
145602
|
async listTargetKinds() {
|
|
145854
145603
|
return [alexaTargetKind()];
|
|
145855
145604
|
},
|
|
145856
|
-
async listTargets() {
|
|
145857
|
-
return [...await ports.loadTargets()];
|
|
145858
|
-
},
|
|
145859
|
-
async getTarget(input) {
|
|
145860
|
-
const found = (await ports.loadTargets()).find((target) => target.id === input.targetId);
|
|
145861
|
-
if (found === void 0) throw new Error(`target not found: ${input.targetId}`);
|
|
145862
|
-
return found;
|
|
145863
|
-
},
|
|
145864
145605
|
async discoverTargets(input) {
|
|
145865
145606
|
for (const broker of ports.brokers()) if (!broker.ready) ports.logger.warn(`alexa echo discovery: no Echo listed for '${broker.name}', the Amazon account is not signed in for this broker`, { tags: { brokerId: broker.id } });
|
|
145866
145607
|
const named = readString(input.config ?? {}, "brokerId");
|
|
@@ -145921,33 +145662,6 @@ function createAlexaNotificationProvider(ports) {
|
|
|
145921
145662
|
format: "text",
|
|
145922
145663
|
priority: 3
|
|
145923
145664
|
});
|
|
145924
|
-
},
|
|
145925
|
-
async upsertTarget(input) {
|
|
145926
|
-
const owner = brokerFor(input.target.config);
|
|
145927
|
-
if (readString(input.target.config, "echoId").length === 0) throw new Error("Pick the Echo that should speak");
|
|
145928
|
-
if (owner === void 0) throw new Error("Pick the Amazon account this Echo belongs to");
|
|
145929
|
-
const pinned = readString(input.target.config, "brokerId").length === 0 ? {
|
|
145930
|
-
...input.target.config,
|
|
145931
|
-
brokerId: owner.id
|
|
145932
|
-
} : input.target.config;
|
|
145933
|
-
const target = {
|
|
145934
|
-
...input.target,
|
|
145935
|
-
config: pinned,
|
|
145936
|
-
addonId: ALEXA_SPEAK_ADDON_ID,
|
|
145937
|
-
kind: ALEXA_SPEAK_KIND
|
|
145938
|
-
};
|
|
145939
|
-
await ports.putTarget(target);
|
|
145940
|
-
return target;
|
|
145941
|
-
},
|
|
145942
|
-
async deleteTarget(input) {
|
|
145943
|
-
await ports.removeTarget(input.targetId);
|
|
145944
|
-
},
|
|
145945
|
-
async setTargetEnabled(input) {
|
|
145946
|
-
const found = (await ports.loadTargets()).find((row) => row.id === input.targetId);
|
|
145947
|
-
if (found !== void 0) await ports.putTarget({
|
|
145948
|
-
...found,
|
|
145949
|
-
enabled: input.enabled
|
|
145950
|
-
});
|
|
145951
145665
|
}
|
|
145952
145666
|
};
|
|
145953
145667
|
}
|
|
@@ -146038,6 +145752,14 @@ function echoTargetProbe(speak) {
|
|
|
146038
145752
|
});
|
|
146039
145753
|
};
|
|
146040
145754
|
}
|
|
145755
|
+
/**
|
|
145756
|
+
* The Echo instance's save-time rule over the accounts now (D1013): the check the removed
|
|
145757
|
+
* `upsertTarget` made, on the instance door. Speech not started yet has no account to name, so the
|
|
145758
|
+
* write is refused with the reason, never accepted blind.
|
|
145759
|
+
*/
|
|
145760
|
+
function echoTargetValidator(brokers) {
|
|
145761
|
+
return ({ config }) => validateEchoTarget(brokers() ?? [], config);
|
|
145762
|
+
}
|
|
146041
145763
|
process.platform, process.env["SystemRoot"];
|
|
146042
145764
|
/**
|
|
146043
145765
|
* Files only their owner may read: the one place a secret-bearing file is
|
|
@@ -146878,8 +146600,6 @@ var AlexaSpeakController = class {
|
|
|
146878
146600
|
now: this.now,
|
|
146879
146601
|
logger: host.logger,
|
|
146880
146602
|
loadTargets: () => host.readTargets(),
|
|
146881
|
-
putTarget: (target) => host.putTarget(target),
|
|
146882
|
-
removeTarget: (targetId) => host.removeTarget(targetId),
|
|
146883
146603
|
speak: (command) => this.utter(command.brokerId, command.mode, command.targets, command.text)
|
|
146884
146604
|
});
|
|
146885
146605
|
}
|
|
@@ -146909,6 +146629,7 @@ var AlexaSpeakController = class {
|
|
|
146909
146629
|
echoFor(brokerId) {
|
|
146910
146630
|
return this.echoes.get(brokerId) ?? null;
|
|
146911
146631
|
}
|
|
146632
|
+
/** The accounts right now, as the provider and the save-time rule see them. */
|
|
146912
146633
|
brokerViews() {
|
|
146913
146634
|
return this.host.listBrokers().map((ref) => {
|
|
146914
146635
|
const echo = this.echoes.get(ref.id);
|
|
@@ -147456,8 +147177,6 @@ var AlexaImportAddon = class extends BaseDeviceProvider {
|
|
|
147456
147177
|
const speak = new AlexaSpeakController({
|
|
147457
147178
|
logger: this.ctx.logger.child("speak"),
|
|
147458
147179
|
readTargets: () => echoStore.list(),
|
|
147459
|
-
putTarget: (target) => echoStore.upsert(target),
|
|
147460
|
-
removeTarget: (targetId) => echoStore.delete(targetId),
|
|
147461
147180
|
listBrokers: () => this.activeBrokers.map((entry) => ({
|
|
147462
147181
|
id: entry.id,
|
|
147463
147182
|
name: entry.name,
|
|
@@ -147559,6 +147278,7 @@ var AlexaImportAddon = class extends BaseDeviceProvider {
|
|
|
147559
147278
|
kinds: alexaNotifyRecordKinds,
|
|
147560
147279
|
mintId: () => randomUUID(),
|
|
147561
147280
|
probe: echoTargetProbe(() => this.speak),
|
|
147281
|
+
validate: echoTargetValidator(() => this.speak?.brokerViews() ?? null),
|
|
147562
147282
|
canProbe: () => true
|
|
147563
147283
|
})
|
|
147564
147284
|
], {
|