@camstack/types 1.2.436 → 1.2.438

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.
Files changed (38) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/addon.js +2 -2
  3. package/dist/addon.mjs +2 -2
  4. package/dist/capabilities/index.d.ts +3 -1
  5. package/dist/capabilities/ir-transmitter.cap.d.ts +84 -0
  6. package/dist/capabilities/llm.cap.d.ts +27 -0
  7. package/dist/capabilities/pet-feeder.cap.d.ts +12 -0
  8. package/dist/client.js +5 -0
  9. package/dist/client.mjs +5 -0
  10. package/dist/{composition-WNkEpwkF.js → composition-DCmtFE-X.js} +1 -1
  11. package/dist/{composition-DwA0uVW5.mjs → composition-DpFv_J6D.mjs} +1 -1
  12. package/dist/device/cap-vocabulary/entries/actuators.d.ts +1 -1
  13. package/dist/device/device-type.d.ts +4 -1
  14. package/dist/{err-msg-DIorGYeC.mjs → err-msg-BCdlR2Li.mjs} +3 -0
  15. package/dist/{err-msg-U7lLUMNz.js → err-msg-COHgq7Mb.js} +3 -0
  16. package/dist/generated/addon-api.d.ts +22 -0
  17. package/dist/generated/addon-cap-facts.d.ts +1 -1
  18. package/dist/generated/capability-router-map.d.ts +5 -2
  19. package/dist/generated/device-proxy.d.ts +2 -0
  20. package/dist/generated/device-scoped-caps.d.ts +1 -1
  21. package/dist/generated/method-access-map.d.ts +1 -1
  22. package/dist/generated/method-device-selectors.d.ts +1 -1
  23. package/dist/index.d.ts +1 -0
  24. package/dist/index.js +369 -7
  25. package/dist/index.mjs +357 -8
  26. package/dist/ir/index.d.ts +5 -0
  27. package/dist/ir/ir-error.d.ts +6 -0
  28. package/dist/ir/ir-payload.d.ts +23 -0
  29. package/dist/ir/ir-timings.d.ts +17 -0
  30. package/dist/ir/pronto.d.ts +10 -0
  31. package/dist/ir/smartir.d.ts +31 -0
  32. package/dist/node.js +2 -2
  33. package/dist/node.mjs +2 -2
  34. package/dist/{sleep-Crlmu_tO.mjs → sleep-BAvUCi_2.mjs} +13 -1
  35. package/dist/{sleep-DHitF_e4.js → sleep-g6ZjBHBL.js} +13 -1
  36. package/dist/vendor-login-proxy/index.d.ts +1 -1
  37. package/dist/vendor-login-proxy/url-rewrite.d.ts +7 -0
  38. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_sleep = require("./sleep-DHitF_e4.js");
2
+ const require_sleep = require("./sleep-g6ZjBHBL.js");
3
3
  const require_event_category = require("./event-category-E17zaHjN.js");
4
- const require_composition = require("./composition-WNkEpwkF.js");
4
+ const require_composition = require("./composition-DCmtFE-X.js");
5
5
  const require_node_color = require("./node-color.js");
6
- const require_err_msg = require("./err-msg-U7lLUMNz.js");
6
+ const require_err_msg = require("./err-msg-COHgq7Mb.js");
7
7
  const require_enums = require("./enums.js");
8
8
  let zod = require("zod");
9
9
  //#region src/media/media-owner-key.ts
@@ -44650,6 +44650,17 @@ var LlmProfileSchema = zod.z.object({
44650
44650
  * field in its editor only when its descriptor lists it in `profileFields`. */
44651
44651
  topK: zod.z.number().int().positive().optional(),
44652
44652
  maxTokens: zod.z.number().int().positive().optional(),
44653
+ /** How hard the model "thinks" before it answers. Omitted = the model's own
44654
+ * default. `off` matters for structured output: a thinking model can spend
44655
+ * the whole completion on reasoning and return an empty `content`. Carried
44656
+ * only by the wires that have it — a kind offers the field in its editor
44657
+ * only when its descriptor lists it in `profileFields`. */
44658
+ reasoningEffort: zod.z.enum([
44659
+ "off",
44660
+ "low",
44661
+ "medium",
44662
+ "high"
44663
+ ]).optional(),
44653
44664
  /** Prompt context window. Advisory for cloud kinds (they enforce their own). */
44654
44665
  contextLength: zod.z.number().int().positive().optional(),
44655
44666
  /** Default system prompt. A caller's `system` REPLACES it (never appends —
@@ -44688,6 +44699,7 @@ var LlmProfileFieldSchema = zod.z.enum([
44688
44699
  "topP",
44689
44700
  "topK",
44690
44701
  "maxTokens",
44702
+ "reasoningEffort",
44691
44703
  "contextLength",
44692
44704
  "systemPrompt",
44693
44705
  "timeoutMs",
@@ -65196,6 +65208,83 @@ var buttonCapability = {
65196
65208
  }) }
65197
65209
  };
65198
65210
  //#endregion
65211
+ //#region src/ir/ir-timings.ts
65212
+ /** Maximum number of mark/space entries one pulse train may carry. */
65213
+ var IR_TIMINGS_MAX = 1024;
65214
+ /**
65215
+ * A pulse train in signed microseconds: mark (+) first, then space (-), strictly
65216
+ * alternating, no zeros, 2..1024 entries.
65217
+ */
65218
+ var IrTimingsSchema = zod.z.array(zod.z.number().int()).min(2).max(IR_TIMINGS_MAX).superRefine((timings, ctx) => {
65219
+ timings.forEach((value, index) => {
65220
+ const expectMark = index % 2 === 0;
65221
+ if (value === 0 || value > 0 !== expectMark) ctx.addIssue({
65222
+ code: "custom",
65223
+ message: `timing ${index} must be a non-zero ${expectMark ? "mark (positive)" : "space (negative)"}`,
65224
+ path: [index]
65225
+ });
65226
+ });
65227
+ });
65228
+ /** Per-command transmit options. Every key is optional; a transmitter applies what it can. */
65229
+ var TransmitSettingsSchema = zod.z.object({
65230
+ carrierHz: zod.z.number().int().positive().optional(),
65231
+ dutyCyclePercent: zod.z.number().int().min(1).max(100).optional(),
65232
+ repeat: zod.z.number().int().min(0).max(20).optional(),
65233
+ repeatDelayMs: zod.z.number().int().min(0).optional()
65234
+ });
65235
+ //#endregion
65236
+ //#region src/capabilities/ir-transmitter.cap.ts
65237
+ /** The setting keys a transmitter may declare as settable (`getInfo.settable`). */
65238
+ var TransmitSettingKeySchema = zod.z.enum([
65239
+ "carrierHz",
65240
+ "dutyCyclePercent",
65241
+ "repeat",
65242
+ "repeatDelayMs"
65243
+ ]);
65244
+ var IrMediumSchema = zod.z.enum(["ir", "rf"]);
65245
+ var IrSendResultSchema = zod.z.object({
65246
+ ok: zod.z.literal(true),
65247
+ /** Settings the transmitter could not apply; the train was still sent. */
65248
+ ignoredSettings: zod.z.array(zod.z.string())
65249
+ });
65250
+ var IrTransmitterInfoSchema = zod.z.object({
65251
+ media: zod.z.array(IrMediumSchema),
65252
+ settable: zod.z.array(TransmitSettingKeySchema),
65253
+ maxTimings: zod.z.number().int().positive()
65254
+ });
65255
+ /**
65256
+ * ir-transmitter — emit a pulse train (infrared or RF) with settings. One cap
65257
+ * for both media: everything medium-specific is a per-call setting, validated
65258
+ * against what the transmitter declares in `getInfo`.
65259
+ *
65260
+ * `send` refuses with a typed user error: `ir-transmitter.offline` (the
65261
+ * transmitter cannot be reached) and `ir-transmitter.too-long` (more pulses
65262
+ * than the transmitter's `maxTimings`). A setting the transmitter cannot apply
65263
+ * is NOT a refusal: the train is sent and the key comes back in
65264
+ * `ignoredSettings`.
65265
+ */
65266
+ var irTransmitterCapability = {
65267
+ name: "ir-transmitter",
65268
+ scope: "device",
65269
+ deviceNative: true,
65270
+ mode: "singleton",
65271
+ deviceTypes: [require_err_msg.DeviceType.Generic],
65272
+ methods: {
65273
+ send: require_sleep.method(zod.z.object({
65274
+ deviceId: zod.z.number().int().nonnegative(),
65275
+ timings: IrTimingsSchema,
65276
+ settings: TransmitSettingsSchema.optional()
65277
+ }), IrSendResultSchema, {
65278
+ kind: "mutation",
65279
+ auth: "protected"
65280
+ }),
65281
+ getInfo: require_sleep.method(zod.z.object({ deviceId: zod.z.number().int().nonnegative() }), IrTransmitterInfoSchema, {
65282
+ kind: "query",
65283
+ auth: "protected"
65284
+ })
65285
+ }
65286
+ };
65287
+ //#endregion
65199
65288
  //#region src/capabilities/calendar-source.cap.ts
65200
65289
  /**
65201
65290
  * `calendar-source` — collection cap exposing per-provider calendars and
@@ -72345,9 +72434,14 @@ var PetFeederStatusSchema = zod.z.object({
72345
72434
  * (`device_class: problem`, on = low). True when the tank reports empty,
72346
72435
  * or, on a dual-hopper model, when EITHER hopper is empty. */
72347
72436
  lowFood: zod.z.boolean(),
72348
- /** Battery charge 0..100 (%). Null on mains-powered models or when the
72349
- * device has no battery reading. */
72437
+ /** Battery charge 0..100 (%). On a feeder running on `mains` this is the
72438
+ * BACKUP battery's charge, not the power source. Null when the device has
72439
+ * no battery reading. */
72350
72440
  batteryPower: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
72441
+ /** What the feeder is powered from right now: `mains` (plugged in, the
72442
+ * battery is only a backup) or `battery`. Null when the device does not
72443
+ * report it. */
72444
+ powerSource: zod.z.enum(["mains", "battery"]).nullable(),
72351
72445
  /**
72352
72446
  * Desiccant life remaining, stored in seconds (duration base, D944).
72353
72447
  * Providers convert from the days the feeder reports. Null when the
@@ -90847,6 +90941,20 @@ var METHOD_ACCESS_MAP = Object.freeze({
90847
90941
  access: "create",
90848
90942
  role: "viewer"
90849
90943
  },
90944
+ "irTransmitter.getInfo": {
90945
+ capName: "ir-transmitter",
90946
+ capScope: "device",
90947
+ addonId: null,
90948
+ access: "view",
90949
+ role: "viewer"
90950
+ },
90951
+ "irTransmitter.send": {
90952
+ capName: "ir-transmitter",
90953
+ capScope: "device",
90954
+ addonId: null,
90955
+ access: "create",
90956
+ role: "viewer"
90957
+ },
90850
90958
  "keychain.delete": {
90851
90959
  capName: "keychain",
90852
90960
  capScope: "system",
@@ -97215,6 +97323,7 @@ var KNOWN_CAP_NAMES = [
97215
97323
  "image-settings",
97216
97324
  "integrations",
97217
97325
  "intercom",
97326
+ "ir-transmitter",
97218
97327
  "keychain",
97219
97328
  "keychain-admin",
97220
97329
  "lawn-mower-control",
@@ -97366,6 +97475,7 @@ var DEVICE_CAP_NAMES = [
97366
97475
  "image",
97367
97476
  "image-settings",
97368
97477
  "intercom",
97478
+ "ir-transmitter",
97369
97479
  "lawn-mower-control",
97370
97480
  "lock-control",
97371
97481
  "media-player",
@@ -98857,6 +98967,11 @@ var ACTUATOR_CAP_VOCABULARY = {
98857
98967
  icon: "circle-dot"
98858
98968
  }]
98859
98969
  },
98970
+ "ir-transmitter": {
98971
+ scope: "device",
98972
+ noun: t("IR / RF transmitter", "Trasmettitore IR / RF"),
98973
+ notOperatorFacing: { send: "a raw pulse train is not something an operator composes in an automation; the remote that owns the command table sends it" }
98974
+ },
98860
98975
  control: {
98861
98976
  scope: "device",
98862
98977
  noun: t("Control", "Controllo"),
@@ -103303,6 +103418,7 @@ var CAPABILITY_NAMES = {
103303
103418
  imageSettings: "image-settings",
103304
103419
  integrations: "integrations",
103305
103420
  intercom: "intercom",
103421
+ irTransmitter: "ir-transmitter",
103306
103422
  keychain: "keychain",
103307
103423
  keychainAdmin: "keychain-admin",
103308
103424
  lawnMowerControl: "lawn-mower-control",
@@ -103751,6 +103867,10 @@ var CAPABILITY_ROUTER_KEYS = [
103751
103867
  key: "intercom",
103752
103868
  name: "intercom"
103753
103869
  },
103870
+ {
103871
+ key: "irTransmitter",
103872
+ name: "ir-transmitter"
103873
+ },
103754
103874
  {
103755
103875
  key: "keychain",
103756
103876
  name: "keychain"
@@ -104252,6 +104372,7 @@ var ALL_CAPABILITY_DEFINITIONS = [
104252
104372
  imageSettingsCapability,
104253
104373
  integrationsCapability,
104254
104374
  intercomCapability,
104375
+ irTransmitterCapability,
104255
104376
  keychainCapability,
104256
104377
  keychainAdminCapability,
104257
104378
  lawnMowerControlCapability,
@@ -105447,6 +105568,16 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
105447
105568
  form: "single",
105448
105569
  optional: false
105449
105570
  }],
105571
+ "irTransmitter.getInfo": [{
105572
+ name: "deviceId",
105573
+ form: "single",
105574
+ optional: false
105575
+ }],
105576
+ "irTransmitter.send": [{
105577
+ name: "deviceId",
105578
+ form: "single",
105579
+ optional: false
105580
+ }],
105450
105581
  "keychain.deleteDeviceScope": [{
105451
105582
  name: "deviceId",
105452
105583
  form: "single",
@@ -118280,6 +118411,29 @@ function rewriteSetCookie(cookie, route) {
118280
118411
  return kept.join("; ");
118281
118412
  }
118282
118413
  /**
118414
+ * Every Set-Cookie of one vendor response, rewritten. Dropping `Domain` folds cookies
118415
+ * the vendor keeps apart (`session-id` on `.amazon.it` and on `.www.amazon.it`) into
118416
+ * one, so a past-dated set that only deleted the other domain's copy would delete the
118417
+ * live one the same response just set: that deletion is dropped.
118418
+ */
118419
+ function rewriteSetCookies(cookies, route) {
118420
+ const now = Date.now();
118421
+ const liveNames = new Set(cookies.filter((c) => !isExpiredCookie(c, now)).map(cookieName));
118422
+ return cookies.filter((c) => !(isExpiredCookie(c, now) && liveNames.has(cookieName(c)))).map((c) => rewriteSetCookie(c, route));
118423
+ }
118424
+ function cookieName(cookie) {
118425
+ return cookie.split(";")[0]?.split("=")[0]?.trim() ?? "";
118426
+ }
118427
+ function isExpiredCookie(cookie, now) {
118428
+ const attrs = cookie.split(";").slice(1).map((part) => part.trim());
118429
+ const maxAge = attrs.find((a) => /^max-age=/i.test(a));
118430
+ if (maxAge !== void 0) return Number(maxAge.slice(8)) <= 0;
118431
+ const expires = attrs.find((a) => /^expires=/i.test(a));
118432
+ if (expires === void 0) return false;
118433
+ const at = Date.parse(expires.slice(8));
118434
+ return Number.isFinite(at) && at <= now;
118435
+ }
118436
+ /**
118283
118437
  * A browser `Referer` that points into this proxy, turned back into the vendor URL it
118284
118438
  * stands for. A Referer that is not ours is dropped (null): it names the hub.
118285
118439
  */
@@ -118398,6 +118552,26 @@ async function readRequestBody(req) {
118398
118552
  }
118399
118553
  return Buffer.concat(chunks);
118400
118554
  }
118555
+ /** The path of the Referer sent upstream, or why none was sent — the query is never logged. */
118556
+ function forwardedRefererPath(forwarded, received) {
118557
+ if (forwarded !== void 0) return URL.canParse(forwarded) ? new URL(forwarded).pathname : "unparsable";
118558
+ return received === void 0 ? "absent" : "unmapped";
118559
+ }
118560
+ /** The form targets a vendor page posts to, path only (no query), so a lost path prefix is visible. */
118561
+ function formActionPaths(html) {
118562
+ const actions = [...html.matchAll(/<form\b[^>]*\baction\s*=\s*["']([^"']*)["']/gi)].map((m) => (m[1] ?? "").split("?")[0] ?? "").slice(0, 5);
118563
+ return actions.length === 0 ? "none" : actions.join(" | ");
118564
+ }
118565
+ /** Cookie NAMES only — values are session secrets and are never logged. */
118566
+ function cookieNames(header) {
118567
+ if (header === void 0 || header.length === 0) return "none";
118568
+ return header.split(";").map((part) => part.split("=")[0]?.trim() ?? "").join(",");
118569
+ }
118570
+ /** A Set-Cookie's name and attributes without its value, so a cookie the browser refuses is visible. */
118571
+ function setCookieShape(cookie) {
118572
+ const [first, ...attrs] = cookie.split(";").map((part) => part.trim());
118573
+ return [first?.split("=")[0] ?? "", ...attrs.filter((a) => !/^expires=/i.test(a))].join(";");
118574
+ }
118401
118575
  function sendPlain(res, status, text) {
118402
118576
  res.writeHead(status, {
118403
118577
  "content-type": "text/plain; charset=utf-8",
@@ -118533,7 +118707,11 @@ var VendorLoginProxy = class {
118533
118707
  host: upstream.host,
118534
118708
  path: target.pathname,
118535
118709
  status: upstreamRes.status,
118536
- method
118710
+ method,
118711
+ refererPath: forwardedRefererPath(headers["referer"], req.headers["referer"]),
118712
+ formActions: kind === "html" && text !== null ? formActionPaths(text) : void 0,
118713
+ sentNames: cookieNames(headers["cookie"]),
118714
+ vendorSets: setCookies.map(setCookieShape).join(" | ")
118537
118715
  } });
118538
118716
  const settled = await attempt.evaluate({
118539
118717
  status: upstreamRes.status,
@@ -118555,7 +118733,7 @@ var VendorLoginProxy = class {
118555
118733
  upstreamRes.headers.forEach((value, name) => {
118556
118734
  if (!DROP_RESPONSE_HEADERS.has(name.toLowerCase())) out[name] = value;
118557
118735
  });
118558
- if (setCookies.length > 0) out["set-cookie"] = setCookies.map((c) => rewriteSetCookie(c, route));
118736
+ if (setCookies.length > 0) out["set-cookie"] = rewriteSetCookies(setCookies, route);
118559
118737
  if (location !== null) out["location"] = rewriteLocation(location, upstream, route);
118560
118738
  out["cache-control"] = "no-store";
118561
118739
  if (text !== null && kind !== null) {
@@ -119660,6 +119838,177 @@ function armRemovalReconcile(opts) {
119660
119838
  return () => clearInterval(timer);
119661
119839
  }
119662
119840
  //#endregion
119841
+ //#region src/ir/ir-error.ts
119842
+ var IrCodecError = class extends Error {
119843
+ code;
119844
+ constructor(code, message) {
119845
+ super(message);
119846
+ this.name = "IrCodecError";
119847
+ this.code = code;
119848
+ }
119849
+ };
119850
+ //#endregion
119851
+ //#region src/ir/pronto.ts
119852
+ /** One Pronto frequency-word unit, in microseconds, per unit of the word. */
119853
+ var PRONTO_CLOCK_US = .241246;
119854
+ var LEARNED_FORM = 0;
119855
+ /**
119856
+ * Decode a learned (0000 form) Pronto hex string. The intro burst is followed by
119857
+ * the repeat burst once; a different form is refused with `pronto-unsupported-form`.
119858
+ */
119859
+ function decodePronto(code) {
119860
+ const words = code.trim().split(/\s+/).filter((w) => w.length > 0);
119861
+ if (words.length < 4) throw new IrCodecError("pronto-malformed", `Pronto code needs at least 4 words, got ${words.length}`);
119862
+ const values = words.map((w) => /^[0-9a-fA-F]{1,4}$/.test(w) ? parseInt(w, 16) : NaN);
119863
+ if (values.some((v) => Number.isNaN(v))) throw new IrCodecError("pronto-malformed", "Pronto code must be 4-digit hexadecimal words");
119864
+ const [form, freqWord, introCount, repeatCount] = values;
119865
+ if (form === void 0 || freqWord === void 0 || introCount === void 0 || repeatCount === void 0) throw new IrCodecError("pronto-malformed", "Pronto header incomplete");
119866
+ if (form !== LEARNED_FORM) throw new IrCodecError("pronto-unsupported-form", `Pronto form ${words[0] ?? ""} is not supported, only the learned 0000 form`);
119867
+ if (freqWord === 0) throw new IrCodecError("pronto-malformed", "Pronto frequency word is zero");
119868
+ const pairs = introCount + repeatCount;
119869
+ if (pairs === 0 || values.length !== 4 + pairs * 2) throw new IrCodecError("pronto-malformed", `Pronto declares ${pairs} burst pairs but carries ${(values.length - 4) / 2} word pairs`);
119870
+ const unitUs = freqWord * PRONTO_CLOCK_US;
119871
+ const timings = values.slice(4).map((count, index) => {
119872
+ const us = Math.max(1, Math.round(count * unitUs));
119873
+ return index % 2 === 0 ? us : -us;
119874
+ });
119875
+ const checked = IrTimingsSchema.safeParse(timings);
119876
+ if (!checked.success) throw new IrCodecError("invalid-timings", `Pronto decoded to invalid timings: ${checked.error.message}`);
119877
+ return {
119878
+ timings: checked.data,
119879
+ carrierHz: Math.round(1e6 / unitUs)
119880
+ };
119881
+ }
119882
+ //#endregion
119883
+ //#region src/ir/ir-payload.ts
119884
+ /** What a remote command stores: a raw pulse train, or a learned Pronto code. */
119885
+ var IrPayloadSchema = zod.z.discriminatedUnion("kind", [zod.z.object({
119886
+ kind: zod.z.literal("raw"),
119887
+ timings: zod.z.array(zod.z.number().int()),
119888
+ settings: TransmitSettingsSchema.optional()
119889
+ }), zod.z.object({
119890
+ kind: zod.z.literal("pronto"),
119891
+ code: zod.z.string()
119892
+ })]);
119893
+ /** Resolve a payload to what `ir-transmitter.send` takes. Throws `IrCodecError`. */
119894
+ function toTimings(payload) {
119895
+ if (payload.kind === "pronto") {
119896
+ const decoded = decodePronto(payload.code);
119897
+ return {
119898
+ timings: decoded.timings,
119899
+ settings: { carrierHz: decoded.carrierHz }
119900
+ };
119901
+ }
119902
+ const checked = IrTimingsSchema.safeParse(payload.timings);
119903
+ if (!checked.success) throw new IrCodecError("invalid-timings", checked.error.message);
119904
+ return {
119905
+ timings: checked.data,
119906
+ settings: payload.settings ?? {}
119907
+ };
119908
+ }
119909
+ //#endregion
119910
+ //#region src/ir/smartir.ts
119911
+ /** SmartIR's own default pause between two commands, in seconds. */
119912
+ var DEFAULT_DELAY_S = .5;
119913
+ var SOURCES_KEY = "sources";
119914
+ var SmartIrDocumentSchema = zod.z.object({
119915
+ manufacturer: zod.z.string().optional(),
119916
+ supportedModels: zod.z.array(zod.z.string()).optional(),
119917
+ supportedController: zod.z.string().optional(),
119918
+ commandsEncoding: zod.z.string(),
119919
+ delay: zod.z.number().nonnegative().optional(),
119920
+ commands: zod.z.record(zod.z.string(), zod.z.unknown())
119921
+ });
119922
+ function describe(error) {
119923
+ return error instanceof Error ? error.message : "unknown error";
119924
+ }
119925
+ function rawPayload(value) {
119926
+ let parsed;
119927
+ try {
119928
+ parsed = JSON.parse(value);
119929
+ } catch (error) {
119930
+ throw new IrCodecError("invalid-raw", `Raw command is not a JSON array: ${describe(error)}`);
119931
+ }
119932
+ const checked = IrTimingsSchema.safeParse(parsed);
119933
+ if (!checked.success) throw new IrCodecError("invalid-timings", checked.error.message);
119934
+ return {
119935
+ kind: "raw",
119936
+ timings: checked.data
119937
+ };
119938
+ }
119939
+ function prontoPayload(value) {
119940
+ decodePronto(value);
119941
+ return {
119942
+ kind: "pronto",
119943
+ code: value
119944
+ };
119945
+ }
119946
+ /** Parse a SmartIR media_player JSON. Raw and Pronto are imported; other encodings are reported in `skipped`. */
119947
+ function parseSmartIr(document) {
119948
+ const parsed = SmartIrDocumentSchema.safeParse(document);
119949
+ if (!parsed.success) throw new IrCodecError("smartir-malformed", `Not a SmartIR document: ${parsed.error.message}`);
119950
+ const doc = parsed.data;
119951
+ const encoding = doc.commandsEncoding;
119952
+ const entries = [];
119953
+ for (const [name, value] of Object.entries(doc.commands)) if (name === SOURCES_KEY && typeof value === "object" && value !== null && !Array.isArray(value)) for (const [sourceName, sourceValue] of Object.entries(value)) entries.push({
119954
+ name: sourceName,
119955
+ group: "source",
119956
+ value: sourceValue
119957
+ });
119958
+ else entries.push({
119959
+ name,
119960
+ group: "command",
119961
+ value
119962
+ });
119963
+ const commands = [];
119964
+ const skipped = [];
119965
+ const supported = encoding === "Raw" || encoding === "Pronto";
119966
+ for (const { name, group, value } of entries) {
119967
+ if (!supported) {
119968
+ skipped.push({
119969
+ name,
119970
+ group,
119971
+ reason: `${encoding} encoding is not supported`
119972
+ });
119973
+ continue;
119974
+ }
119975
+ if (typeof value !== "string") {
119976
+ skipped.push({
119977
+ name,
119978
+ group,
119979
+ reason: "command is not a string"
119980
+ });
119981
+ continue;
119982
+ }
119983
+ try {
119984
+ commands.push({
119985
+ name,
119986
+ group,
119987
+ payload: encoding === "Raw" ? rawPayload(value) : prontoPayload(value)
119988
+ });
119989
+ } catch (error) {
119990
+ skipped.push({
119991
+ name,
119992
+ group,
119993
+ reason: describe(error)
119994
+ });
119995
+ }
119996
+ }
119997
+ return {
119998
+ table: {
119999
+ commands,
120000
+ interCommandDelayMs: Math.round((doc.delay ?? DEFAULT_DELAY_S) * 1e3),
120001
+ origin: {
120002
+ format: "smartir",
120003
+ manufacturer: doc.manufacturer,
120004
+ models: doc.supportedModels,
120005
+ controller: doc.supportedController
120006
+ }
120007
+ },
120008
+ skipped
120009
+ };
120010
+ }
120011
+ //#endregion
119663
120012
  exports.ACCESSORY_LABEL = ACCESSORY_LABEL;
119664
120013
  exports.ACCESS_ROLES = ACCESS_ROLES;
119665
120014
  exports.ACTIVE_CRITERIA = require_composition.ACTIVE_CRITERIA;
@@ -120492,6 +120841,7 @@ exports.INITIAL_SPAN = INITIAL_SPAN;
120492
120841
  exports.INTEGRAL_OUTPUTS = require_composition.INTEGRAL_OUTPUTS;
120493
120842
  exports.INTERNAL_ACTION_PREFIX = INTERNAL_ACTION_PREFIX;
120494
120843
  exports.INVERTIBLE_CAPS = INVERTIBLE_CAPS;
120844
+ exports.IR_TIMINGS_MAX = IR_TIMINGS_MAX;
120495
120845
  exports.IconKeySchema = IconKeySchema;
120496
120846
  exports.ImageContractSchema = ImageContractSchema;
120497
120847
  exports.ImageContractStateSchema = ImageContractStateSchema;
@@ -120512,6 +120862,12 @@ exports.IntegrationWithStateSchema = IntegrationWithStateSchema;
120512
120862
  exports.IntercomAbilitySchema = IntercomAbilitySchema;
120513
120863
  exports.IntercomStatusSchema = IntercomStatusSchema;
120514
120864
  exports.InvalidRecordError = require_sleep.InvalidRecordError;
120865
+ exports.IrCodecError = IrCodecError;
120866
+ exports.IrMediumSchema = IrMediumSchema;
120867
+ exports.IrPayloadSchema = IrPayloadSchema;
120868
+ exports.IrSendResultSchema = IrSendResultSchema;
120869
+ exports.IrTimingsSchema = IrTimingsSchema;
120870
+ exports.IrTransmitterInfoSchema = IrTransmitterInfoSchema;
120515
120871
  exports.KEYCHAIN_MAX_REFS_PER_CALL = KEYCHAIN_MAX_REFS_PER_CALL;
120516
120872
  exports.KEYCHAIN_RESET_CONFIRMATION = KEYCHAIN_RESET_CONFIRMATION;
120517
120873
  exports.KEYCHAIN_RESET_TRIGGER_ACTOR = KEYCHAIN_RESET_TRIGGER_ACTOR;
@@ -121663,6 +122019,8 @@ exports.TrainingResultSchema = TrainingResultSchema;
121663
122019
  exports.TrainingSplitPlanSchema = TrainingSplitPlanSchema;
121664
122020
  exports.TrainingStageSchema = TrainingStageSchema;
121665
122021
  exports.TransactRefusedError = require_sleep.TransactRefusedError;
122022
+ exports.TransmitSettingKeySchema = TransmitSettingKeySchema;
122023
+ exports.TransmitSettingsSchema = TransmitSettingsSchema;
121666
122024
  exports.TransportPlaneCountsSchema = TransportPlaneCountsSchema;
121667
122025
  exports.TransportPlaneSchema = TransportPlaneSchema;
121668
122026
  exports.TurnServerSchema = TurnServerSchema;
@@ -122008,6 +122366,7 @@ exports.declareLogChannel = declareLogChannel;
122008
122366
  exports.declaredSeriesKind = declaredSeriesKind;
122009
122367
  exports.decodeCompositionToCards = decodeCompositionToCards;
122010
122368
  exports.decodeKeyedArrayOverride = decodeKeyedArrayOverride;
122369
+ exports.decodePronto = decodePronto;
122011
122370
  exports.decodePulseOverride = decodePulseOverride;
122012
122371
  exports.decodeScalarOverride = decodeScalarOverride;
122013
122372
  exports.decodeVectorBase64 = decodeVectorBase64;
@@ -122223,6 +122582,7 @@ exports.interpretStoredClusterModel = interpretStoredClusterModel;
122223
122582
  exports.invalidClusterStepModelEntries = invalidClusterStepModelEntries;
122224
122583
  exports.invertPresetFeature = invertPresetFeature;
122225
122584
  exports.invocationFromEncodeProfile = require_composition.invocationFromEncodeProfile;
122585
+ exports.irTransmitterCapability = irTransmitterCapability;
122226
122586
  exports.isAgentOnlyPlacement = isAgentOnlyPlacement;
122227
122587
  exports.isAlarmControllableCap = isAlarmControllableCap;
122228
122588
  exports.isAlertEpisodeOpen = isAlertEpisodeOpen;
@@ -122461,6 +122821,7 @@ exports.parseSecretRef = require_sleep.parseSecretRef;
122461
122821
  exports.parseSecretStatePath = require_sleep.parseSecretStatePath;
122462
122822
  exports.parseSessionPlacementPolicy = parseSessionPlacementPolicy;
122463
122823
  exports.parseShareSource = parseShareSource;
122824
+ exports.parseSmartIr = parseSmartIr;
122464
122825
  exports.parseStreamParamsFormPatch = parseStreamParamsFormPatch;
122465
122826
  exports.parseTrainingEventLine = parseTrainingEventLine;
122466
122827
  exports.patchAudio = patchAudio;
@@ -122797,6 +123158,7 @@ exports.toNodeId = require_sleep.toNodeId;
122797
123158
  exports.toPercentShares = toPercentShares;
122798
123159
  exports.toSecretFieldView = require_sleep.toSecretFieldView;
122799
123160
  exports.toStreamSourceEntry = toStreamSourceEntry;
123161
+ exports.toTimings = toTimings;
122800
123162
  exports.toastCapability = toastCapability;
122801
123163
  exports.toggleAudioLabel = toggleAudioLabel;
122802
123164
  exports.tokenize = require_composition.tokenize;