@camstack/addon-provider-bosch 0.1.52 → 0.1.54
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/{account-integration-offline-D5vjmfia.mjs → account-integration-offline-C9glrBvy.mjs} +1 -1
- package/dist/{account-integration-offline-BEzGeJcl.js → account-integration-offline-DK6CYsvB.js} +1 -1
- package/dist/{bosch-instances-DSE6IXdU.mjs → bosch-instances-DMzZSMxW.mjs} +476 -82
- package/dist/{bosch-instances-LWbVnsaD.js → bosch-instances-DkTzZrlR.js} +493 -81
- package/dist/home-connect/addon.js +5 -3
- package/dist/home-connect/addon.mjs +5 -3
- package/dist/homecom/addon.js +3 -3
- package/dist/homecom/addon.mjs +3 -3
- package/dist/shc/addon.js +4 -4
- package/dist/shc/addon.mjs +4 -4
- package/package.json +3 -2
|
@@ -6044,7 +6044,7 @@ var ZodIssueCode = {
|
|
|
6044
6044
|
var ZodFirstPartyTypeKind;
|
|
6045
6045
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
6046
6046
|
//#endregion
|
|
6047
|
-
//#region ../types/dist/sleep-
|
|
6047
|
+
//#region ../types/dist/sleep-D0roI_CZ.mjs
|
|
6048
6048
|
/**
|
|
6049
6049
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6050
6050
|
* window to float samples (D455).
|
|
@@ -16242,6 +16242,10 @@ Object.freeze({
|
|
|
16242
16242
|
"path": "lastEvent.eventType",
|
|
16243
16243
|
"valueType": "string"
|
|
16244
16244
|
},
|
|
16245
|
+
{
|
|
16246
|
+
"path": "lastEvent.sourceId",
|
|
16247
|
+
"valueType": "string"
|
|
16248
|
+
},
|
|
16245
16249
|
{
|
|
16246
16250
|
"path": "lastEvent.timestamp",
|
|
16247
16251
|
"valueType": "number"
|
|
@@ -44093,6 +44097,51 @@ function macroOnly(macro) {
|
|
|
44093
44097
|
};
|
|
44094
44098
|
}
|
|
44095
44099
|
}
|
|
44100
|
+
var EventVocabularyKindSchema = _enum([
|
|
44101
|
+
"press",
|
|
44102
|
+
"long-press",
|
|
44103
|
+
"long-press-start",
|
|
44104
|
+
"release",
|
|
44105
|
+
"repeat",
|
|
44106
|
+
"double-press",
|
|
44107
|
+
"other"
|
|
44108
|
+
]);
|
|
44109
|
+
/** The part of the device an event comes from: a button, a channel. */
|
|
44110
|
+
var EventVocabularySourceSchema = object({
|
|
44111
|
+
id: string().min(1),
|
|
44112
|
+
label: string().min(1)
|
|
44113
|
+
});
|
|
44114
|
+
/** One scalar field of an event's `data`, by dotted path. */
|
|
44115
|
+
var EventVocabularyFieldSchema = object({
|
|
44116
|
+
path: string().min(1),
|
|
44117
|
+
kind: _enum([
|
|
44118
|
+
"string",
|
|
44119
|
+
"number",
|
|
44120
|
+
"boolean",
|
|
44121
|
+
"enum"
|
|
44122
|
+
]),
|
|
44123
|
+
enumValues: array(string()).optional(),
|
|
44124
|
+
label: string().min(1).optional()
|
|
44125
|
+
});
|
|
44126
|
+
var EventVocabularyEntrySchema = object({
|
|
44127
|
+
/** The native token, verbatim. */
|
|
44128
|
+
id: string().min(1),
|
|
44129
|
+
source: EventVocabularySourceSchema.optional(),
|
|
44130
|
+
label: string().min(1),
|
|
44131
|
+
description: string().optional(),
|
|
44132
|
+
kind: EventVocabularyKindSchema.optional(),
|
|
44133
|
+
payload: array(EventVocabularyFieldSchema).optional()
|
|
44134
|
+
});
|
|
44135
|
+
/**
|
|
44136
|
+
* The vocabulary of a source that declares tokens and nothing else: one
|
|
44137
|
+
* entry per token, labelled with the token itself.
|
|
44138
|
+
*/
|
|
44139
|
+
function plainEventVocabulary(eventTypes) {
|
|
44140
|
+
return [...new Set(eventTypes)].filter((eventType) => eventType !== "").map((eventType) => ({
|
|
44141
|
+
id: eventType,
|
|
44142
|
+
label: eventType
|
|
44143
|
+
}));
|
|
44144
|
+
}
|
|
44096
44145
|
Math.PI / 180;
|
|
44097
44146
|
/**
|
|
44098
44147
|
* WHEN something happens, as data (D983) — the one time vocabulary of the
|
|
@@ -44300,6 +44349,33 @@ var ScheduleLeafSchema = object({
|
|
|
44300
44349
|
/** @deprecated legacy cron — new schedules use `at`. */
|
|
44301
44350
|
cron: string().min(1).max(120).optional()
|
|
44302
44351
|
}).refine((leaf) => leaf.at === void 0 !== (leaf.cron === void 0), { message: "a schedule names exactly one of `at` (a time spec) and `cron` (legacy)" }).refine((leaf) => leaf.days === void 0 || leaf.at !== void 0, { message: "`days` goes with `at`; a cron expression carries its own days" });
|
|
44352
|
+
/**
|
|
44353
|
+
* One payload predicate of a `device-fired` row: the value at `path` inside
|
|
44354
|
+
* the fire's `data` (dotted) equals `equals`. Compared strictly, no coercion.
|
|
44355
|
+
*/
|
|
44356
|
+
var DeviceFiredMatchSchema = object({
|
|
44357
|
+
path: string().min(1).max(120),
|
|
44358
|
+
equals: union([
|
|
44359
|
+
string(),
|
|
44360
|
+
number$1(),
|
|
44361
|
+
boolean()
|
|
44362
|
+
])
|
|
44363
|
+
});
|
|
44364
|
+
/**
|
|
44365
|
+
* "fires": one device of the `event-emitter` capability reported an event
|
|
44366
|
+
* (D1045). Every list is an OR, the lists together an AND; an absent list does
|
|
44367
|
+
* not narrow. `eventIds` are the device's own tokens, `sourceIds` the parts of
|
|
44368
|
+
* the device (a button), `kinds` the shared press kinds of its vocabulary.
|
|
44369
|
+
*/
|
|
44370
|
+
var DeviceFiredLeafSchema = object({
|
|
44371
|
+
kind: literal("device-fired"),
|
|
44372
|
+
...eventLeafId,
|
|
44373
|
+
deviceId: number$1().int().nonnegative(),
|
|
44374
|
+
eventIds: array(string().min(1)).min(1).max(64).optional(),
|
|
44375
|
+
sourceIds: array(string().min(1)).min(1).max(64).optional(),
|
|
44376
|
+
kinds: array(EventVocabularyKindSchema).min(1).optional(),
|
|
44377
|
+
match: array(DeviceFiredMatchSchema).min(1).max(8).optional()
|
|
44378
|
+
});
|
|
44303
44379
|
var ManualLeafSchema = object({
|
|
44304
44380
|
kind: literal("manual"),
|
|
44305
44381
|
...eventLeafId
|
|
@@ -44441,6 +44517,7 @@ var AutomationWhenSchema = lazy(() => discriminatedUnion("kind", [
|
|
|
44441
44517
|
}),
|
|
44442
44518
|
DeviceBecomesLeafSchema,
|
|
44443
44519
|
DeviceEventLeafSchema,
|
|
44520
|
+
DeviceFiredLeafSchema,
|
|
44444
44521
|
ScheduleLeafSchema,
|
|
44445
44522
|
ManualLeafSchema,
|
|
44446
44523
|
IntervalLeafSchema,
|
|
@@ -44455,6 +44532,7 @@ var AutomationWhenSchema = lazy(() => discriminatedUnion("kind", [
|
|
|
44455
44532
|
var EVENT_KINDS = new Set([
|
|
44456
44533
|
"device-becomes",
|
|
44457
44534
|
"device-event",
|
|
44535
|
+
"device-fired",
|
|
44458
44536
|
"schedule",
|
|
44459
44537
|
"manual",
|
|
44460
44538
|
"interval",
|
|
@@ -44535,6 +44613,7 @@ function hasEmptyContainer(node) {
|
|
|
44535
44613
|
var LEAF_WORDS = {
|
|
44536
44614
|
"device-becomes": "a device value that becomes",
|
|
44537
44615
|
"device-event": "a device event",
|
|
44616
|
+
"device-fired": "a device firing an event",
|
|
44538
44617
|
schedule: "a schedule",
|
|
44539
44618
|
manual: "a manual run",
|
|
44540
44619
|
interval: "an interval",
|
|
@@ -44800,9 +44879,12 @@ function convertLegacyWhen(half) {
|
|
|
44800
44879
|
* every caller — automations, Actions, and the notification centre, which runs
|
|
44801
44880
|
* only Actions (planning#473).
|
|
44802
44881
|
*/
|
|
44882
|
+
/** The longest one `wait` step lasts. It is cut by a restart of the run and does not survive a hub restart. */
|
|
44883
|
+
var WAIT_MAX_SECONDS = 3600;
|
|
44884
|
+
var WAIT_TOO_LONG = `a wait is at most one hour (${WAIT_MAX_SECONDS} s)`;
|
|
44803
44885
|
var AutomationWaitStepSchema = object({
|
|
44804
44886
|
kind: literal("wait"),
|
|
44805
|
-
seconds: number$1().min(0).max(
|
|
44887
|
+
seconds: number$1().min(0).max(WAIT_MAX_SECONDS, WAIT_TOO_LONG)
|
|
44806
44888
|
});
|
|
44807
44889
|
/** The legacy `deviceId` of a cap step: still READ, never written (D983). */
|
|
44808
44890
|
var LegacyStepDeviceSchema = union([
|
|
@@ -44872,39 +44954,227 @@ var elseNeedsIf = {
|
|
|
44872
44954
|
path: ["else"]
|
|
44873
44955
|
};
|
|
44874
44956
|
var GuardedWaitStepSchema = AutomationWaitStepSchema.extend(stepGuardShape).refine((step) => step.else === void 0 || step.if !== void 0, elseNeedsIf);
|
|
44875
|
-
var GuardedCapStepSchema = AutomationCapStepBaseSchema.extend(stepGuardShape).refine((step) => step.target !== void 0 || step.deviceId !== void 0, {
|
|
44876
|
-
message: "a cap step needs a target",
|
|
44877
|
-
path: ["target"]
|
|
44878
|
-
}).refine((step) => step.target?.kind !== "domain" || step.actionId !== void 0, {
|
|
44879
|
-
message: "a domain target needs the vocabulary action it applies to (actionId)",
|
|
44880
|
-
path: ["actionId"]
|
|
44881
|
-
}).refine((step) => step.else === void 0 || step.if !== void 0, elseNeedsIf);
|
|
44882
44957
|
/**
|
|
44883
44958
|
* A step of a STANDALONE list (an action, a scheduler point, a preset): the
|
|
44884
44959
|
* same two step kinds an automation runs, minus a guard that reads the
|
|
44885
44960
|
* automation's trigger, which such a list does not have.
|
|
44886
44961
|
*/
|
|
44887
|
-
var ActionStepSchema = discriminatedUnion("kind", [GuardedWaitStepSchema,
|
|
44962
|
+
var ActionStepSchema = discriminatedUnion("kind", [GuardedWaitStepSchema, AutomationCapStepBaseSchema.extend(stepGuardShape).refine((step) => step.target !== void 0 || step.deviceId !== void 0, {
|
|
44963
|
+
message: "a cap step needs a target",
|
|
44964
|
+
path: ["target"]
|
|
44965
|
+
}).refine((step) => step.target?.kind !== "domain" || step.actionId !== void 0, {
|
|
44966
|
+
message: "a domain target needs the vocabulary action it applies to (actionId)",
|
|
44967
|
+
path: ["actionId"]
|
|
44968
|
+
}).refine((step) => step.else === void 0 || step.if !== void 0, elseNeedsIf)]).superRefine((step, ctx) => {
|
|
44888
44969
|
if (step.if !== void 0 && hasTriggeredByLeaves(step.if)) ctx.addIssue({
|
|
44889
44970
|
code: "custom",
|
|
44890
44971
|
message: TRIGGERED_BY_NEEDS_AUTOMATION,
|
|
44891
44972
|
path: ["if"]
|
|
44892
44973
|
});
|
|
44893
44974
|
});
|
|
44975
|
+
/**
|
|
44976
|
+
* Flow control of an AUTOMATION's list (#500). A standalone list (an action, a
|
|
44977
|
+
* scheduler point, a preset) stays `wait` and `cap`: it has no run of its own
|
|
44978
|
+
* to end and no variable bag to write.
|
|
44979
|
+
*/
|
|
44980
|
+
var continueOnErrorShape = {
|
|
44981
|
+
/** A failure of this step is traced `failed-continued` and the next step runs. */
|
|
44982
|
+
continueOnError: literal(true).optional() };
|
|
44983
|
+
/** An automation's cap step: the shared guarded cap step, plus `continueOnError`. */
|
|
44984
|
+
var AutomationGuardedCapStepSchema = AutomationCapStepBaseSchema.extend({
|
|
44985
|
+
...stepGuardShape,
|
|
44986
|
+
...continueOnErrorShape
|
|
44987
|
+
}).refine((step) => step.target !== void 0 || step.deviceId !== void 0, {
|
|
44988
|
+
message: "a cap step needs a target",
|
|
44989
|
+
path: ["target"]
|
|
44990
|
+
}).refine((step) => step.target?.kind !== "domain" || step.actionId !== void 0, {
|
|
44991
|
+
message: "a domain target needs the vocabulary action it applies to (actionId)",
|
|
44992
|
+
path: ["actionId"]
|
|
44993
|
+
}).refine((step) => step.else === void 0 || step.if !== void 0, elseNeedsIf);
|
|
44994
|
+
/** End the run here, on purpose. `reason` may carry `{{vars.x}}` slots. */
|
|
44995
|
+
var AutomationStopStepSchema = object({
|
|
44996
|
+
kind: literal("stop"),
|
|
44997
|
+
reason: string().min(1, "a stop needs a reason: it is what the run trace shows").max(200),
|
|
44998
|
+
/** `ok`: the run ends as a success. `failed`: it ends as a failure, with the reason. */
|
|
44999
|
+
outcome: _enum(["ok", "failed"]),
|
|
45000
|
+
/** Stop only when this reads true; false or unknown does not stop. */
|
|
45001
|
+
if: AutomationWhenSchema.optional()
|
|
45002
|
+
});
|
|
45003
|
+
var SET_VAR_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]{0,39}$/;
|
|
45004
|
+
/** Names the run itself writes and reads (`leaf` is what `triggered-by` judges): a step may not overwrite them. */
|
|
45005
|
+
var RESERVED_RUN_VARS = [
|
|
45006
|
+
"kind",
|
|
45007
|
+
"leaf",
|
|
45008
|
+
"at"
|
|
45009
|
+
];
|
|
45010
|
+
/**
|
|
45011
|
+
* Write variables into the run's bag, for the steps after it. SUBSTITUTION
|
|
45012
|
+
* only, never evaluation: a text value may carry `{{vars.x}}` slots.
|
|
45013
|
+
*/
|
|
45014
|
+
var AutomationSetStepSchema = object({
|
|
45015
|
+
kind: literal("set"),
|
|
45016
|
+
vars: record(string(), union([
|
|
45017
|
+
string().max(500),
|
|
45018
|
+
number$1(),
|
|
45019
|
+
boolean()
|
|
45020
|
+
])).refine((vars) => Object.keys(vars).every((name) => SET_VAR_NAME_RE.test(name)), { message: "a variable name is letters, digits and _, not starting with a digit (max 40)" }).refine((vars) => Object.keys(vars).length >= 1, { message: "set needs at least one variable" }).refine((vars) => Object.keys(vars).length <= 20, { message: `set holds at most 20 variables` }).refine((vars) => Object.keys(vars).every((name) => !RESERVED_RUN_VARS.includes(name)), { message: `the names ${RESERVED_RUN_VARS.join(", ")} belong to the run and cannot be set` }),
|
|
45021
|
+
/** Set only when this reads true; false or unknown leaves the bag as it is. */
|
|
45022
|
+
if: AutomationWhenSchema.optional()
|
|
45023
|
+
});
|
|
45024
|
+
var AutomationRunActionStepSchema = object({
|
|
45025
|
+
kind: literal("action"),
|
|
45026
|
+
/** An entry of the `actions` surface (`internal:<uuid>` or `<addonId>:<localId>`). */
|
|
45027
|
+
actionId: string().min(1),
|
|
45028
|
+
/** Values for the action's declared variables; the others take their default. */
|
|
45029
|
+
variables: record(string(), union([
|
|
45030
|
+
string(),
|
|
45031
|
+
number$1(),
|
|
45032
|
+
boolean()
|
|
45033
|
+
])).optional(),
|
|
45034
|
+
...continueOnErrorShape
|
|
45035
|
+
});
|
|
45036
|
+
/**
|
|
45037
|
+
* A step INSIDE a branch of a `choose`: a flow step with no condition of its
|
|
45038
|
+
* own (the branch is the condition) and no block inside it. Strict, so an `if`
|
|
45039
|
+
* written on such a step is refused rather than dropped.
|
|
45040
|
+
*/
|
|
45041
|
+
/** The longest a `wait-until` may wait: six hours. */
|
|
45042
|
+
var WAIT_UNTIL_TIMEOUT_MAX_S = 21600;
|
|
45043
|
+
/**
|
|
45044
|
+
* Pause the run until a condition is true (#500). The timeout is mandatory: a
|
|
45045
|
+
* run never waits without an end. `onTimeout` says what a wait that ran out
|
|
45046
|
+
* does: `continue` goes on to the next step, `stop` ends the run as a failure.
|
|
45047
|
+
* A condition that cannot be read is not "true": the wait goes on (D49).
|
|
45048
|
+
*/
|
|
45049
|
+
var AutomationWaitUntilStepSchema = object({
|
|
45050
|
+
kind: literal("wait-until"),
|
|
45051
|
+
when: AutomationWhenSchema,
|
|
45052
|
+
timeoutS: number$1().int().min(1, "a wait needs a timeout of at least one second").max(WAIT_UNTIL_TIMEOUT_MAX_S, `a wait for a condition is at most six hours (${WAIT_UNTIL_TIMEOUT_MAX_S} s)`),
|
|
45053
|
+
onTimeout: _enum(["continue", "stop"])
|
|
45054
|
+
}).strict();
|
|
45055
|
+
/** The step kinds that hold steps of their own, or pause on a condition: they nest two levels at most. */
|
|
45056
|
+
var BLOCK_STEP_KINDS = [
|
|
45057
|
+
"choose",
|
|
45058
|
+
"repeat",
|
|
45059
|
+
"parallel",
|
|
45060
|
+
"wait-until"
|
|
45061
|
+
];
|
|
45062
|
+
var NEST_TOO_DEEP = `steps nest two levels at most: a step inside a nested choose or repeat can be a plain step only`;
|
|
45063
|
+
function kindOf(input) {
|
|
45064
|
+
return typeof input === "object" && input !== null ? Reflect.get(input, "kind") : void 0;
|
|
45065
|
+
}
|
|
45066
|
+
/** Where the nesting ends, a block step is refused in words rather than as an unknown kind. */
|
|
45067
|
+
function nestTooDeep(issue) {
|
|
45068
|
+
const kind = kindOf(issue.input);
|
|
45069
|
+
return typeof kind === "string" && BLOCK_STEP_KINDS.includes(kind) ? NEST_TOO_DEEP : void 0;
|
|
45070
|
+
}
|
|
45071
|
+
var plainStepSchemas = [
|
|
45072
|
+
AutomationWaitStepSchema.strict(),
|
|
45073
|
+
AutomationCapStepBaseSchema.extend(continueOnErrorShape).strict().refine((step) => step.target !== void 0 || step.deviceId !== void 0, {
|
|
45074
|
+
message: "a cap step needs a target",
|
|
45075
|
+
path: ["target"]
|
|
45076
|
+
}).refine((step) => step.target?.kind !== "domain" || step.actionId !== void 0, {
|
|
45077
|
+
message: "a domain target needs the vocabulary action it applies to (actionId)",
|
|
45078
|
+
path: ["actionId"]
|
|
45079
|
+
}),
|
|
45080
|
+
AutomationStopStepSchema.omit({ if: true }).strict(),
|
|
45081
|
+
AutomationSetStepSchema.omit({ if: true }).strict(),
|
|
45082
|
+
AutomationRunActionStepSchema.strict()
|
|
45083
|
+
];
|
|
45084
|
+
/**
|
|
45085
|
+
* A plain step: a flow step with no condition of its own and no step inside
|
|
45086
|
+
* it. The second (last) level of nesting holds these only.
|
|
45087
|
+
*/
|
|
45088
|
+
var AutomationBranchStepSchema = discriminatedUnion("kind", plainStepSchemas, { error: nestTooDeep });
|
|
45089
|
+
/** A step that can run beside others: it writes no variable and does not end the run. */
|
|
45090
|
+
var AutomationParallelMemberSchema = AutomationBranchStepSchema.refine((step) => step.kind === "cap" || step.kind === "action" || step.kind === "wait", "a parallel holds device commands, actions and waits only: a set or a stop beside other steps has no order");
|
|
45091
|
+
/**
|
|
45092
|
+
* Several steps at once (#500): all are started together and all are awaited.
|
|
45093
|
+
* A failure fails the run once the others finished, as in a sequence; a member
|
|
45094
|
+
* marked "continue if this fails" does not.
|
|
45095
|
+
*/
|
|
45096
|
+
var AutomationParallelStepSchema = object({
|
|
45097
|
+
kind: literal("parallel"),
|
|
45098
|
+
steps: array(AutomationParallelMemberSchema).min(2, "a parallel needs at least two steps").max(5, `a parallel takes at most 5 steps`)
|
|
45099
|
+
}).strict();
|
|
45100
|
+
var REPEAT_NEEDS_MAX = "a repeat on a condition needs a maximum number of iterations";
|
|
45101
|
+
/** A loop on a condition: the bound is mandatory, so a run never loops without an end. */
|
|
45102
|
+
var repeatConditionShape = {
|
|
45103
|
+
when: AutomationWhenSchema,
|
|
45104
|
+
maxIterations: number$1({ error: REPEAT_NEEDS_MAX }).int().min(1, REPEAT_NEEDS_MAX).max(50, `a repeat on a condition runs at most 50 times`),
|
|
45105
|
+
/** A pause between two iterations, never after the last. */
|
|
45106
|
+
waitS: number$1().int().min(1).max(WAIT_MAX_SECONDS, WAIT_TOO_LONG).optional()
|
|
45107
|
+
};
|
|
45108
|
+
/** What decides how many times a `repeat` runs. */
|
|
45109
|
+
var AutomationRepeatLoopSchema = discriminatedUnion("by", [
|
|
45110
|
+
object({
|
|
45111
|
+
by: literal("count"),
|
|
45112
|
+
count: number$1().int().min(1).max(20, `a repeat runs at most 20 times`)
|
|
45113
|
+
}).strict(),
|
|
45114
|
+
object({
|
|
45115
|
+
by: literal("while"),
|
|
45116
|
+
...repeatConditionShape
|
|
45117
|
+
}).strict(),
|
|
45118
|
+
object({
|
|
45119
|
+
by: literal("until"),
|
|
45120
|
+
...repeatConditionShape
|
|
45121
|
+
}).strict(),
|
|
45122
|
+
object({
|
|
45123
|
+
by: literal("forEach"),
|
|
45124
|
+
target: object({
|
|
45125
|
+
kind: literal("devices"),
|
|
45126
|
+
ids: array(number$1().int()).min(1, "a repeat over devices needs at least one device").max(50, `a repeat over devices takes at most 50 devices`)
|
|
45127
|
+
}).strict()
|
|
45128
|
+
}).strict()
|
|
45129
|
+
]);
|
|
45130
|
+
/**
|
|
45131
|
+
* The same steps several times (#500). Every form is bounded at save, so a
|
|
45132
|
+
* run cannot loop without an end. A failure or a `stop` in the steps ends the
|
|
45133
|
+
* loop and the run, as in a sequence.
|
|
45134
|
+
*/
|
|
45135
|
+
function repeatSchemaOf(step) {
|
|
45136
|
+
return object({
|
|
45137
|
+
kind: literal("repeat"),
|
|
45138
|
+
loop: AutomationRepeatLoopSchema,
|
|
45139
|
+
steps: array(step).min(1, "a repeat needs at least one step").max(10, `a repeat takes at most 10 steps`)
|
|
45140
|
+
}).strict();
|
|
45141
|
+
}
|
|
45142
|
+
/**
|
|
45143
|
+
* One step, several ways (#500): the branches are read in order and the FIRST
|
|
45144
|
+
* whose condition is true runs; `else` runs when every branch is false. A
|
|
45145
|
+
* branch that cannot be read ends the choice: nothing runs, not the branches
|
|
45146
|
+
* after it and not the else (D49). The #472 `if` / `else` of a wait or cap
|
|
45147
|
+
* step is the one-branch case and stays as it is stored.
|
|
45148
|
+
*/
|
|
45149
|
+
function chooseSchemaOf(step) {
|
|
45150
|
+
const steps = array(step).max(10);
|
|
45151
|
+
return object({
|
|
45152
|
+
kind: literal("choose"),
|
|
45153
|
+
branches: array(object({
|
|
45154
|
+
if: AutomationWhenSchema,
|
|
45155
|
+
steps: steps.min(1, "a branch needs at least one step")
|
|
45156
|
+
})).min(1, "a choose needs at least one branch").max(6, `a choose takes at most 6 branches`),
|
|
45157
|
+
else: steps.optional()
|
|
45158
|
+
});
|
|
45159
|
+
}
|
|
45160
|
+
var AutomationBodyStepSchema = discriminatedUnion("kind", [
|
|
45161
|
+
...plainStepSchemas,
|
|
45162
|
+
AutomationWaitUntilStepSchema,
|
|
45163
|
+
AutomationParallelStepSchema,
|
|
45164
|
+
chooseSchemaOf(AutomationBranchStepSchema),
|
|
45165
|
+
repeatSchemaOf(AutomationBranchStepSchema)
|
|
45166
|
+
]);
|
|
45167
|
+
var AutomationRepeatStepSchema = repeatSchemaOf(AutomationBodyStepSchema);
|
|
44894
45168
|
var AutomationActionSchema = discriminatedUnion("kind", [
|
|
44895
45169
|
GuardedWaitStepSchema,
|
|
44896
|
-
|
|
44897
|
-
|
|
44898
|
-
|
|
44899
|
-
|
|
44900
|
-
|
|
44901
|
-
|
|
44902
|
-
|
|
44903
|
-
|
|
44904
|
-
number$1(),
|
|
44905
|
-
boolean()
|
|
44906
|
-
])).optional()
|
|
44907
|
-
}),
|
|
45170
|
+
AutomationGuardedCapStepSchema,
|
|
45171
|
+
AutomationStopStepSchema,
|
|
45172
|
+
AutomationSetStepSchema,
|
|
45173
|
+
chooseSchemaOf(AutomationBodyStepSchema),
|
|
45174
|
+
AutomationWaitUntilStepSchema,
|
|
45175
|
+
AutomationParallelStepSchema,
|
|
45176
|
+
AutomationRepeatStepSchema,
|
|
45177
|
+
AutomationRunActionStepSchema,
|
|
44908
45178
|
object({
|
|
44909
45179
|
kind: literal("code"),
|
|
44910
45180
|
/** Compiled into the automation's OWN block by esbuild — not a third
|
|
@@ -44967,11 +45237,6 @@ function convertLegacyRecipe(legacy) {
|
|
|
44967
45237
|
...rest
|
|
44968
45238
|
};
|
|
44969
45239
|
}
|
|
44970
|
-
/**
|
|
44971
|
-
* Where recipes are PARSED (the core-blocks cap, the MCP tool, the literal a
|
|
44972
|
-
* saved block carries): the new shape as it is, or the old shape converted to
|
|
44973
|
-
* it. The output type is always the new one.
|
|
44974
|
-
*/
|
|
44975
45240
|
var AutomationRecipeSchema = union([CurrentAutomationRecipeSchema, LegacyAutomationRecipeSchema.transform(convertLegacyRecipe)]);
|
|
44976
45241
|
var DETECTION_DESCRIPTIONS = {
|
|
44977
45242
|
deviceId: "the camera that saw it",
|
|
@@ -44992,6 +45257,16 @@ var BECOMES_DESCRIPTIONS = {
|
|
|
44992
45257
|
from: "the value before the change, empty when it is not known",
|
|
44993
45258
|
to: "the value it changed to"
|
|
44994
45259
|
};
|
|
45260
|
+
/**
|
|
45261
|
+
* A fire's payload is offered too, as `data.<path>` (`{{vars.data.channel}}`):
|
|
45262
|
+
* those names depend on the device, so they are not in this list.
|
|
45263
|
+
*/
|
|
45264
|
+
var FIRED_DESCRIPTIONS = {
|
|
45265
|
+
deviceId: "the device that fired",
|
|
45266
|
+
eventType: "the event, as the device names it",
|
|
45267
|
+
sourceId: "the part of the device that fired (a button), empty when it names none",
|
|
45268
|
+
eventKind: "the kind of press (press, long-press …), empty when the device declares none"
|
|
45269
|
+
};
|
|
44995
45270
|
function describe$1(descriptions) {
|
|
44996
45271
|
return Object.entries(descriptions).map(([name, description]) => ({
|
|
44997
45272
|
name,
|
|
@@ -45000,12 +45275,74 @@ function describe$1(descriptions) {
|
|
|
45000
45275
|
}
|
|
45001
45276
|
describe$1(DETECTION_DESCRIPTIONS);
|
|
45002
45277
|
describe$1(STATIONARY_DESCRIPTIONS);
|
|
45278
|
+
describe$1(FIRED_DESCRIPTIONS).map((v) => v.name === "deviceId" ? {
|
|
45279
|
+
...v,
|
|
45280
|
+
hintKey: "firedDeviceId"
|
|
45281
|
+
} : v);
|
|
45003
45282
|
describe$1(BECOMES_DESCRIPTIONS).map((v) => v.name === "deviceId" ? {
|
|
45004
45283
|
...v,
|
|
45005
45284
|
hintKey: "becomesDeviceId"
|
|
45006
45285
|
} : v);
|
|
45007
45286
|
new Set(Object.values(COCO_TO_MACRO.mapping));
|
|
45008
45287
|
/**
|
|
45288
|
+
* Generic stateless event emitter. Installed on a `DeviceType.EventEmitter`
|
|
45289
|
+
* device. Carries the device's EXACT declared event vocabulary verbatim
|
|
45290
|
+
* (NO normalization). Two shapes:
|
|
45291
|
+
* - structured source (HA `event.*` entity) → `vocabulary` is the fixed
|
|
45292
|
+
* declared set (e.g. press_short, press_long, …).
|
|
45293
|
+
* - generic/legacy source (HA bus events, e.g. zha_event) → `vocabulary`
|
|
45294
|
+
* is [] (open) and `lastEvent.data` carries the complex payload.
|
|
45295
|
+
* `vocabulary` (D1044) names each event for a person and types it for a
|
|
45296
|
+
* rule; `eventTypes` is its list of native tokens, kept for older readers.
|
|
45297
|
+
* A fire names the part of the device it came from in `sourceId` when the
|
|
45298
|
+
* vocabulary declares sources (a remote's buttons).
|
|
45299
|
+
* `seq` is monotonic so two identical events still produce distinct slice writes.
|
|
45300
|
+
*/
|
|
45301
|
+
var EventFireSchema = object({
|
|
45302
|
+
deviceId: number$1(),
|
|
45303
|
+
eventType: string(),
|
|
45304
|
+
sourceId: string().optional(),
|
|
45305
|
+
data: record(string(), unknown()).nullable(),
|
|
45306
|
+
timestamp: number$1().meta(readingMeta("none")),
|
|
45307
|
+
seq: number$1().meta(readingMeta("count"))
|
|
45308
|
+
});
|
|
45309
|
+
var EventEmitterStatusSchema = object({
|
|
45310
|
+
eventTypes: array(string()),
|
|
45311
|
+
/**
|
|
45312
|
+
* Required of a provider by the type. A status written before the field
|
|
45313
|
+
* existed still parses, as an empty vocabulary: read it through
|
|
45314
|
+
* `readEventVocabulary`, which then answers with the plain tokens.
|
|
45315
|
+
*/
|
|
45316
|
+
vocabulary: array(EventVocabularyEntrySchema).default([]),
|
|
45317
|
+
lastEvent: EventFireSchema.nullable(),
|
|
45318
|
+
eventCountSinceStart: number$1().meta(readingMeta("count"))
|
|
45319
|
+
});
|
|
45320
|
+
var eventEmitterCapability = {
|
|
45321
|
+
name: "event-emitter",
|
|
45322
|
+
scope: "device",
|
|
45323
|
+
deviceNative: true,
|
|
45324
|
+
mode: "singleton",
|
|
45325
|
+
deviceTypes: [DeviceType.EventEmitter],
|
|
45326
|
+
methods: {},
|
|
45327
|
+
events: { onEvent: { data: EventFireSchema } },
|
|
45328
|
+
status: {
|
|
45329
|
+
schema: EventEmitterStatusSchema,
|
|
45330
|
+
kind: "push"
|
|
45331
|
+
},
|
|
45332
|
+
runtimeState: EventEmitterStatusSchema,
|
|
45333
|
+
/**
|
|
45334
|
+
* Runtime-state durability: **session** — `eventCountSinceStart` names its own scope.
|
|
45335
|
+
*
|
|
45336
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
45337
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
45338
|
+
*/
|
|
45339
|
+
durability: "session",
|
|
45340
|
+
/**
|
|
45341
|
+
* History (D850): none — `eventCountSinceStart` resets with the addon; events live in ledgers.
|
|
45342
|
+
*/
|
|
45343
|
+
history: "none"
|
|
45344
|
+
};
|
|
45345
|
+
/**
|
|
45009
45346
|
* Schedulers (D983) — an entity that performs actions over the day.
|
|
45010
45347
|
*
|
|
45011
45348
|
* A scheduler has profiles; a profile has weekdays and a timeline of POINTS.
|
|
@@ -45056,12 +45393,16 @@ var HoldOverrideSchema = discriminatedUnion("mode", [object({ mode: literal("res
|
|
|
45056
45393
|
})]);
|
|
45057
45394
|
/** A missed edge up to this late still runs. */
|
|
45058
45395
|
var DEFAULT_MAX_LATE_MS = 10 * 6e4;
|
|
45396
|
+
var SchedulerStepSchema = ActionStepSchema.refine((step) => step.kind !== "wait" || step.seconds <= 300, {
|
|
45397
|
+
message: `a scheduler point waits at most five minutes (300 s); put a longer wait in an action`,
|
|
45398
|
+
path: ["seconds"]
|
|
45399
|
+
});
|
|
45059
45400
|
var SchedulerPointSchema = object({
|
|
45060
45401
|
id: string().min(1).max(64),
|
|
45061
45402
|
at: SchedulerTimeSpecSchema,
|
|
45062
45403
|
mode: SchedulerPointModeSchema,
|
|
45063
45404
|
/** The actions of an `edge` or `hold`; a `release` has none. */
|
|
45064
|
-
steps: array(
|
|
45405
|
+
steps: array(SchedulerStepSchema).max(20).default([]),
|
|
45065
45406
|
/** Checked when the point runs (an edge) or is applied (a hold). */
|
|
45066
45407
|
conditions: SchedulerStateTreeSchema.optional(),
|
|
45067
45408
|
/** Hold only; absent means `respect`. */
|
|
@@ -45259,6 +45600,7 @@ var AutomationConditionTraceNodeSchema = object({
|
|
|
45259
45600
|
"triggered-by",
|
|
45260
45601
|
"device-becomes",
|
|
45261
45602
|
"device-event",
|
|
45603
|
+
"device-fired",
|
|
45262
45604
|
"schedule",
|
|
45263
45605
|
"interval",
|
|
45264
45606
|
"manual",
|
|
@@ -45329,18 +45671,46 @@ var StepTraceBaseSchema = object({
|
|
|
45329
45671
|
]).optional(),
|
|
45330
45672
|
/** Why the condition read what it read, in the evaluator's own words. */
|
|
45331
45673
|
conditionReason: string().optional(),
|
|
45332
|
-
/** `empty`: the target resolved to no device, so nothing was done — never silently `ok`. `skipped`: its `if` was false (or unknown) and nothing ran in its place. */
|
|
45674
|
+
/** `empty`: the target resolved to no device, so nothing was done — never silently `ok`. `skipped`: its `if` was false (or unknown) and nothing ran in its place. `failed-continued`: it failed and was marked to be passed over (#500). */
|
|
45333
45675
|
outcome: _enum([
|
|
45334
45676
|
"ok",
|
|
45335
45677
|
"error",
|
|
45336
45678
|
"not-run",
|
|
45337
45679
|
"empty",
|
|
45338
|
-
"skipped"
|
|
45680
|
+
"skipped",
|
|
45681
|
+
"failed-continued",
|
|
45682
|
+
"timed-out"
|
|
45339
45683
|
]),
|
|
45340
45684
|
message: string().optional()
|
|
45341
45685
|
});
|
|
45686
|
+
/** What a block step adds to its row: which list ran, what each branch read, how many rounds. */
|
|
45687
|
+
var blockTraceShape = {
|
|
45688
|
+
/** A `choose` step (#500): the list that ran, `branches.<n>` or `else`. Absent when none did. */
|
|
45689
|
+
branch: string().optional(),
|
|
45690
|
+
/** A `choose` step: what each branch read, in order, up to the one that decided. */
|
|
45691
|
+
branchChecks: array(object({
|
|
45692
|
+
condition: _enum([
|
|
45693
|
+
"true",
|
|
45694
|
+
"false",
|
|
45695
|
+
"unknown"
|
|
45696
|
+
]),
|
|
45697
|
+
conditionReason: string().optional()
|
|
45698
|
+
})).optional(),
|
|
45699
|
+
/** A `repeat` step (#500): how many times its steps ran. */
|
|
45700
|
+
iterations: number$1().int().optional()
|
|
45701
|
+
};
|
|
45702
|
+
/** A step one level down: it may be a block step itself, whose own steps are plain rows (the nesting ends there). */
|
|
45703
|
+
var NestedStepTraceSchema = StepTraceBaseSchema.extend({
|
|
45704
|
+
...blockTraceShape,
|
|
45705
|
+
steps: array(StepTraceBaseSchema).optional()
|
|
45706
|
+
});
|
|
45342
45707
|
/** A step trace; the `else` steps that ran are one level of the same shape (the nesting is bounded at one). */
|
|
45343
|
-
var AutomationStepTraceSchema = StepTraceBaseSchema.extend({
|
|
45708
|
+
var AutomationStepTraceSchema = StepTraceBaseSchema.extend({
|
|
45709
|
+
else: array(StepTraceBaseSchema).optional(),
|
|
45710
|
+
...blockTraceShape,
|
|
45711
|
+
/** A `choose` step: the steps of the list that ran. A `parallel`: its members. A `repeat`: the LAST iteration. */
|
|
45712
|
+
steps: array(NestedStepTraceSchema).optional()
|
|
45713
|
+
});
|
|
45344
45714
|
var AutomationRunTraceSchema = object({
|
|
45345
45715
|
runId: string().min(1),
|
|
45346
45716
|
startedAt: number$1(),
|
|
@@ -45747,7 +46117,9 @@ var AddonHttpRouteSchema = object({
|
|
|
45747
46117
|
]).optional(),
|
|
45748
46118
|
description: string().optional(),
|
|
45749
46119
|
/** The hub limits this route per client address before the handler runs. */
|
|
45750
|
-
rateLimit: _enum(["auth"]).optional()
|
|
46120
|
+
rateLimit: _enum(["auth"]).optional(),
|
|
46121
|
+
/** Served once per integration instance; the handler reads `instanceId`. */
|
|
46122
|
+
perInstance: boolean().optional()
|
|
45751
46123
|
});
|
|
45752
46124
|
/**
|
|
45753
46125
|
* Cross-process route invocation envelope. The hub captures the
|
|
@@ -45764,6 +46136,8 @@ var InvokeRequestSchema = object({
|
|
|
45764
46136
|
query: record(string(), string()),
|
|
45765
46137
|
body: unknown(),
|
|
45766
46138
|
headers: record(string(), string()),
|
|
46139
|
+
/** The instance the hub resolved for a `perInstance` route. */
|
|
46140
|
+
instanceId: string().optional(),
|
|
45767
46141
|
user: object({
|
|
45768
46142
|
id: string(),
|
|
45769
46143
|
username: string(),
|
|
@@ -56435,53 +56809,6 @@ var enumSensorCapability = {
|
|
|
56435
56809
|
* whether persisting is worth a SQLite commit. */
|
|
56436
56810
|
volatileStateFields: ["lastFetchedAt", "timestamp"]
|
|
56437
56811
|
};
|
|
56438
|
-
/**
|
|
56439
|
-
* Generic stateless event emitter. Installed on a `DeviceType.EventEmitter`
|
|
56440
|
-
* device. Carries the device's EXACT declared event vocabulary verbatim
|
|
56441
|
-
* (NO normalization). Two shapes:
|
|
56442
|
-
* - structured source (HA `event.*` entity) → `eventTypes` is the fixed
|
|
56443
|
-
* declared vocabulary (e.g. ['press_short','press_long',...]).
|
|
56444
|
-
* - generic/legacy source (HA bus events, e.g. zha_event) → `eventTypes`
|
|
56445
|
-
* is [] (open) and `lastEvent.data` carries the complex payload.
|
|
56446
|
-
* `seq` is monotonic so two identical events still produce distinct slice writes.
|
|
56447
|
-
*/
|
|
56448
|
-
var EventFireSchema = object({
|
|
56449
|
-
deviceId: number$1(),
|
|
56450
|
-
eventType: string(),
|
|
56451
|
-
data: record(string(), unknown()).nullable(),
|
|
56452
|
-
timestamp: number$1().meta(readingMeta("none")),
|
|
56453
|
-
seq: number$1().meta(readingMeta("count"))
|
|
56454
|
-
});
|
|
56455
|
-
var EventEmitterStatusSchema = object({
|
|
56456
|
-
eventTypes: array(string()),
|
|
56457
|
-
lastEvent: EventFireSchema.nullable(),
|
|
56458
|
-
eventCountSinceStart: number$1().meta(readingMeta("count"))
|
|
56459
|
-
});
|
|
56460
|
-
var eventEmitterCapability = {
|
|
56461
|
-
name: "event-emitter",
|
|
56462
|
-
scope: "device",
|
|
56463
|
-
deviceNative: true,
|
|
56464
|
-
mode: "singleton",
|
|
56465
|
-
deviceTypes: [DeviceType.EventEmitter],
|
|
56466
|
-
methods: {},
|
|
56467
|
-
events: { onEvent: { data: EventFireSchema } },
|
|
56468
|
-
status: {
|
|
56469
|
-
schema: EventEmitterStatusSchema,
|
|
56470
|
-
kind: "push"
|
|
56471
|
-
},
|
|
56472
|
-
runtimeState: EventEmitterStatusSchema,
|
|
56473
|
-
/**
|
|
56474
|
-
* Runtime-state durability: **session** — `eventCountSinceStart` names its own scope.
|
|
56475
|
-
*
|
|
56476
|
-
* See `RuntimeStateDurability`. Enforced by
|
|
56477
|
-
* `scripts/check-runtime-state-durability.ts`.
|
|
56478
|
-
*/
|
|
56479
|
-
durability: "session",
|
|
56480
|
-
/**
|
|
56481
|
-
* History (D850): none — `eventCountSinceStart` resets with the addon; events live in ledgers.
|
|
56482
|
-
*/
|
|
56483
|
-
history: "none"
|
|
56484
|
-
};
|
|
56485
56812
|
var IdentitySchema = object({
|
|
56486
56813
|
id: string(),
|
|
56487
56814
|
name: string(),
|
|
@@ -59084,6 +59411,12 @@ var IntegrationLiteSchema = object({
|
|
|
59084
59411
|
var AvailableIntegrationTypeSchema = object({
|
|
59085
59412
|
addonId: string(),
|
|
59086
59413
|
name: string(),
|
|
59414
|
+
/**
|
|
59415
|
+
* Product name a new integration is prefilled from (`<label> - Home`).
|
|
59416
|
+
* Absent: the client uses `name`. Set when the catalog title is not the
|
|
59417
|
+
* product (Bosch SHC, MQTT).
|
|
59418
|
+
*/
|
|
59419
|
+
providerLabel: string().optional(),
|
|
59087
59420
|
description: string(),
|
|
59088
59421
|
iconUrl: string().nullable(),
|
|
59089
59422
|
color: string(),
|
|
@@ -71972,7 +72305,18 @@ var OauthIntegrationDescriptorSchema = object({
|
|
|
71972
72305
|
* The value is baked into the authorization code at `/authorize` and travels
|
|
71973
72306
|
* on the tokens, so editing this field changes FUTURE links only.
|
|
71974
72307
|
*/
|
|
71975
|
-
refreshTokenTtlSec: union([number$1().int().positive(), literal("never")]).optional()
|
|
72308
|
+
refreshTokenTtlSec: union([number$1().int().positive(), literal("never")]).optional(),
|
|
72309
|
+
/**
|
|
72310
|
+
* The integration instances an account can be linked to (planning#415),
|
|
72311
|
+
* beside the default one. `/api/oauth2/authorize?instance=<id>` is accepted
|
|
72312
|
+
* only for an id listed here; with no `instance=` the link is made to the
|
|
72313
|
+
* default instance, which is never listed and always accepted — it is the
|
|
72314
|
+
* address third parties already hold. Omit for a single-instance integration.
|
|
72315
|
+
*/
|
|
72316
|
+
instances: array(object({
|
|
72317
|
+
id: string(),
|
|
72318
|
+
displayName: string()
|
|
72319
|
+
})).optional()
|
|
71976
72320
|
});
|
|
71977
72321
|
method(_void(), OauthIntegrationDescriptorSchema, { auth: "admin" });
|
|
71978
72322
|
/**
|
|
@@ -78909,6 +79253,13 @@ var SsoBridgeClaimsSchema = object({
|
|
|
78909
79253
|
/** OAuth authorization-code binding — set only on `oauth-code` tokens. */
|
|
78910
79254
|
redirectUri: string().optional(),
|
|
78911
79255
|
integrationId: string().optional(),
|
|
79256
|
+
/**
|
|
79257
|
+
* The integration INSTANCE an OAuth link was made for (planning#415). Set on
|
|
79258
|
+
* `oauth-code`, `oauth-access` and `oauth-refresh` tokens of a link made
|
|
79259
|
+
* with `instance=`; absent on a link to the default instance. A cloud relay
|
|
79260
|
+
* reads it off the access token to route; the hub answers from the session.
|
|
79261
|
+
*/
|
|
79262
|
+
instanceId: string().optional(),
|
|
78912
79263
|
/** JWT ID — unique per issued code; consumed-set enforces single-use. */
|
|
78913
79264
|
jti: string().optional(),
|
|
78914
79265
|
/** PKCE S256 challenge — set only on `oauth-code` tokens issued to a public
|
|
@@ -81287,6 +81638,8 @@ var OauthSessionSummarySchema = object({
|
|
|
81287
81638
|
userId: string(),
|
|
81288
81639
|
username: string(),
|
|
81289
81640
|
integrationId: string(),
|
|
81641
|
+
/** The instance the link was made for; `null` = the default instance. */
|
|
81642
|
+
instanceId: string().nullable().optional(),
|
|
81290
81643
|
scopes: array(TokenScopeSchema),
|
|
81291
81644
|
createdAt: number$1(),
|
|
81292
81645
|
lastUsedAt: number$1(),
|
|
@@ -81386,6 +81739,9 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(_void(), ob
|
|
|
81386
81739
|
access: "view"
|
|
81387
81740
|
}), method(object({
|
|
81388
81741
|
integrationId: string(),
|
|
81742
|
+
/** The integration instance the link is for. Omit for the default
|
|
81743
|
+
* instance — never pass the addon id to mean it. */
|
|
81744
|
+
instanceId: string().optional(),
|
|
81389
81745
|
userId: string(),
|
|
81390
81746
|
username: string(),
|
|
81391
81747
|
scopes: array(TokenScopeSchema),
|
|
@@ -81424,7 +81780,13 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(_void(), ob
|
|
|
81424
81780
|
}), method(object({ token: string() }), object({
|
|
81425
81781
|
userId: string(),
|
|
81426
81782
|
username: string(),
|
|
81427
|
-
scopes: array(TokenScopeSchema)
|
|
81783
|
+
scopes: array(TokenScopeSchema),
|
|
81784
|
+
/** The instance the link was made for, read from the SESSION.
|
|
81785
|
+
* Absent = the default instance. `oauthLinkServesInstance` is the
|
|
81786
|
+
* helper a per-instance route calls to compare it with the instance
|
|
81787
|
+
* of its path; no route declares `perInstance` yet (the Alexa
|
|
81788
|
+
* per-instance route, T3, is the first consumer). */
|
|
81789
|
+
instanceId: string().optional()
|
|
81428
81790
|
}).nullable(), { access: "view" }), method(object({ userId: string() }), array(ExternalIdentitySchema), { auth: "admin" }), method(ExternalIdentityKeySchema, object({
|
|
81429
81791
|
userId: string(),
|
|
81430
81792
|
issuer: string()
|
|
@@ -102780,6 +103142,38 @@ function ingestReading(input) {
|
|
|
102780
103142
|
value: converted
|
|
102781
103143
|
};
|
|
102782
103144
|
}
|
|
103145
|
+
/**
|
|
103146
|
+
* Names chosen when an integration or a Gateway device is created.
|
|
103147
|
+
* A stored name is never rewritten from these helpers.
|
|
103148
|
+
*/
|
|
103149
|
+
var HOME_SUFFIX = "Home";
|
|
103150
|
+
function collapse(value) {
|
|
103151
|
+
return value.trim().replace(/\s+/g, " ");
|
|
103152
|
+
}
|
|
103153
|
+
/** "KLF-200" → "KLF200". A hyphen between words ("Home Hub") stays. */
|
|
103154
|
+
function compactModelToken(value) {
|
|
103155
|
+
return value.replace(/([A-Za-z])-(\d)/g, "$1$2");
|
|
103156
|
+
}
|
|
103157
|
+
/** Prefill for a new integration: "<provider> - Home". The operator can edit it. */
|
|
103158
|
+
function defaultIntegrationName(providerLabel) {
|
|
103159
|
+
const label = collapse(providerLabel);
|
|
103160
|
+
if (label.length === 0) return HOME_SUFFIX;
|
|
103161
|
+
return `${label} - ${HOME_SUFFIX}`;
|
|
103162
|
+
}
|
|
103163
|
+
/**
|
|
103164
|
+
* A Gateway device: "<Brand> <Model>". An unknown model is the brand alone
|
|
103165
|
+
* (the caller passes the brand-level fallback it already has, e.g. "Velux KLF-200").
|
|
103166
|
+
*/
|
|
103167
|
+
function gatewayDeviceName(brand, model) {
|
|
103168
|
+
const brandPart = compactModelToken(collapse(brand));
|
|
103169
|
+
const raw = collapse(model ?? "");
|
|
103170
|
+
if (raw.length === 0) return brandPart;
|
|
103171
|
+
const modelPart = compactModelToken(raw);
|
|
103172
|
+
const prefix = `${brandPart.toLowerCase()} `;
|
|
103173
|
+
if (modelPart.toLowerCase() === brandPart.toLowerCase()) return brandPart;
|
|
103174
|
+
if (modelPart.toLowerCase().startsWith(prefix)) return modelPart;
|
|
103175
|
+
return `${brandPart} ${modelPart}`;
|
|
103176
|
+
}
|
|
102783
103177
|
String.raw`(?<=^|["'(\s>,\[{])`;
|
|
102784
103178
|
var MB = 1024 * 1024;
|
|
102785
103179
|
1024 * MB, 3072 * MB;
|
|
@@ -103008,6 +103402,12 @@ Object.defineProperty(exports, "customAction", {
|
|
|
103008
103402
|
return customAction;
|
|
103009
103403
|
}
|
|
103010
103404
|
});
|
|
103405
|
+
Object.defineProperty(exports, "defaultIntegrationName", {
|
|
103406
|
+
enumerable: true,
|
|
103407
|
+
get: function() {
|
|
103408
|
+
return defaultIntegrationName;
|
|
103409
|
+
}
|
|
103410
|
+
});
|
|
103011
103411
|
Object.defineProperty(exports, "defineCustomActions", {
|
|
103012
103412
|
enumerable: true,
|
|
103013
103413
|
get: function() {
|
|
@@ -103056,6 +103456,12 @@ Object.defineProperty(exports, "eventEmitterCapability", {
|
|
|
103056
103456
|
return eventEmitterCapability;
|
|
103057
103457
|
}
|
|
103058
103458
|
});
|
|
103459
|
+
Object.defineProperty(exports, "gatewayDeviceName", {
|
|
103460
|
+
enumerable: true,
|
|
103461
|
+
get: function() {
|
|
103462
|
+
return gatewayDeviceName;
|
|
103463
|
+
}
|
|
103464
|
+
});
|
|
103059
103465
|
Object.defineProperty(exports, "heatPumpControlCapability", {
|
|
103060
103466
|
enumerable: true,
|
|
103061
103467
|
get: function() {
|
|
@@ -103128,6 +103534,12 @@ Object.defineProperty(exports, "object", {
|
|
|
103128
103534
|
return object;
|
|
103129
103535
|
}
|
|
103130
103536
|
});
|
|
103537
|
+
Object.defineProperty(exports, "plainEventVocabulary", {
|
|
103538
|
+
enumerable: true,
|
|
103539
|
+
get: function() {
|
|
103540
|
+
return plainEventVocabulary;
|
|
103541
|
+
}
|
|
103542
|
+
});
|
|
103131
103543
|
Object.defineProperty(exports, "powerMeterCapability", {
|
|
103132
103544
|
enumerable: true,
|
|
103133
103545
|
get: function() {
|