@camstack/types 1.2.453 → 1.2.455

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.
@@ -3,7 +3,7 @@
3
3
  * the layout payload of the `remote` template kind. Pure data: no runtime, no
4
4
  * node dependency, so the admin UI imports the same schemas the server checks.
5
5
  *
6
- * A binding is the SAME shape an Action step has (`AutomationCapStepSchema`: a
6
+ * A binding is the SAME shape an Action step has (`AutomationCapStepBaseSchema`: a
7
7
  * cap method called on a device with arguments), narrowed to ONE device: an IR
8
8
  * code is `ir-transmitter.send` on the transmitter, a smart TV is a `switch` or a
9
9
  * vendor cap — the remote does not know which. How many times a command is sent
@@ -11,22 +11,22 @@
11
11
  */
12
12
  import { z } from 'zod';
13
13
  export declare const RemoteBindingActionSchema: z.ZodObject<{
14
+ deviceId: z.ZodNumber;
14
15
  kind: z.ZodLiteral<"cap">;
15
16
  cap: z.ZodString;
16
17
  method: z.ZodString;
17
18
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
18
19
  argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
19
- deviceId: z.ZodNumber;
20
20
  }, z.core.$strip>;
21
21
  export type RemoteBindingAction = z.infer<typeof RemoteBindingActionSchema>;
22
22
  export declare const RemoteBindingSchema: z.ZodObject<{
23
23
  action: z.ZodObject<{
24
+ deviceId: z.ZodNumber;
24
25
  kind: z.ZodLiteral<"cap">;
25
26
  cap: z.ZodString;
26
27
  method: z.ZodString;
27
28
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
28
29
  argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
29
- deviceId: z.ZodNumber;
30
30
  }, z.core.$strip>;
31
31
  }, z.core.$strip>;
32
32
  export type RemoteBinding = z.infer<typeof RemoteBindingSchema>;
@@ -48,12 +48,12 @@ export declare const RemoteConfigSchema: z.ZodObject<{
48
48
  defaultTransmitterId: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
49
49
  bindings: z.ZodRecord<z.ZodString, z.ZodObject<{
50
50
  action: z.ZodObject<{
51
+ deviceId: z.ZodNumber;
51
52
  kind: z.ZodLiteral<"cap">;
52
53
  cap: z.ZodString;
53
54
  method: z.ZodString;
54
55
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
55
56
  argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
56
- deviceId: z.ZodNumber;
57
57
  }, z.core.$strip>;
58
58
  }, z.core.$strip>>;
59
59
  customButtons: z.ZodArray<z.ZodObject<{
@@ -176,6 +176,11 @@ export declare const RemoteLayoutGroupSchema: z.ZodObject<{
176
176
  rowSpan: z.ZodNumber;
177
177
  colSpan: z.ZodNumber;
178
178
  title: z.ZodOptional<z.ZodString>;
179
+ size: z.ZodOptional<z.ZodEnum<{
180
+ compact: "compact";
181
+ normal: "normal";
182
+ }>>;
183
+ hideTitle: z.ZodOptional<z.ZodBoolean>;
179
184
  }, z.core.$strip>;
180
185
  export type RemoteLayoutGroup = z.infer<typeof RemoteLayoutGroupSchema>;
181
186
  export interface LayoutRect {
@@ -232,6 +237,11 @@ export declare const RemoteLayoutPayloadSchema: z.ZodObject<{
232
237
  rowSpan: z.ZodNumber;
233
238
  colSpan: z.ZodNumber;
234
239
  title: z.ZodOptional<z.ZodString>;
240
+ size: z.ZodOptional<z.ZodEnum<{
241
+ compact: "compact";
242
+ normal: "normal";
243
+ }>>;
244
+ hideTitle: z.ZodOptional<z.ZodBoolean>;
235
245
  }, z.core.$strip>>>;
236
246
  }, z.core.$strip>;
237
247
  export type RemoteLayoutPayload = z.infer<typeof RemoteLayoutPayloadSchema>;
@@ -0,0 +1,2 @@
1
+ export * from './solar.js';
2
+ export * from './time-spec.js';
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Where the sun is, from a latitude and a longitude — the one solar
3
+ * calculation in the repo. Compact NOAA sunrise equation (accurate to about a
4
+ * minute away from the poles), so no astronomy dependency is needed.
5
+ *
6
+ * Two consumers read it: the scene-condition resolver (day / night / dawn /
7
+ * dusk of a camera) and a schedule's sun time (`time-spec.ts`).
8
+ */
9
+ /** The sun's upper limb on the horizon, refraction included: sunrise and sunset. */
10
+ export declare const SUNRISE_ALTITUDE_DEG = -0.833;
11
+ /** The sun's centre 6 degrees below the horizon: civil dawn and civil dusk. */
12
+ export declare const CIVIL_TWILIGHT_ALTITUDE_DEG = -6;
13
+ /**
14
+ * The two moments, in UTC epoch ms, at which the sun crosses an altitude on one
15
+ * day: going up (`rise`) and going down (`set`).
16
+ */
17
+ export interface SunCrossings {
18
+ readonly rise: number;
19
+ readonly set: number;
20
+ }
21
+ /**
22
+ * When the sun crosses `altitudeDeg` on the day `date` falls in at this place.
23
+ * Pass an instant near local midday of the civil day you mean: the day is
24
+ * chosen from the instant, and midday is the one that never straddles two.
25
+ *
26
+ * `null` when the sun never crosses that altitude that day (polar day or polar
27
+ * night, or — for a twilight altitude — a summer night that never gets dark
28
+ * enough). The caller decides what that means; nothing here guesses.
29
+ */
30
+ export declare function sunCrossings(lat: number, lng: number, date: Date, altitudeDeg: number): SunCrossings | null;
31
+ /**
32
+ * Sunrise and sunset (UTC epoch ms) for a place and date; `null` for the polar
33
+ * cases (the sun never rises or sets that day).
34
+ */
35
+ export declare function sunTimes(lat: number, lng: number, date: Date): SunCrossings | null;
36
+ /** Civil dawn and dusk (UTC epoch ms); `null` when the sun never gets that low or that high. */
37
+ export declare function twilightTimes(lat: number, lng: number, date: Date): SunCrossings | null;
@@ -0,0 +1,117 @@
1
+ /**
2
+ * WHEN something happens, as data (D983) — the one time vocabulary of the
3
+ * scheduler and of an automation's schedule leaf. Three shapes, no cron:
4
+ *
5
+ * - `clock` — a wall-clock time every day (`07:30`), read in the site's zone;
6
+ * - `sun` — a sun event (`sunrise`, `sunset`, `dawn`, `dusk`) plus or minus
7
+ * up to twelve hours, from the site's coordinates;
8
+ * - `date` — one local date and time (`2026-12-24T18:00`), once.
9
+ *
10
+ * A site is a place and its IANA zone ({@link TimeSite}). Every function here
11
+ * is pure: the zone arithmetic uses `Intl`, no date library.
12
+ *
13
+ * Wall-clock honesty across a DST change: a local time that does not exist
14
+ * (02:30 on the spring-forward day) happens at the first minute that does
15
+ * (03:00); one that happens twice (02:30 on the fall-back day) happens at its
16
+ * FIRST occurrence.
17
+ */
18
+ import { z } from 'zod';
19
+ export declare const SunEventSchema: z.ZodEnum<{
20
+ dawn: "dawn";
21
+ dusk: "dusk";
22
+ sunrise: "sunrise";
23
+ sunset: "sunset";
24
+ }>;
25
+ export type SunEvent = z.infer<typeof SunEventSchema>;
26
+ export declare const TimeSpecSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
27
+ kind: z.ZodLiteral<"clock">;
28
+ hh: z.ZodNumber;
29
+ mm: z.ZodNumber;
30
+ }, z.core.$strip>, z.ZodObject<{
31
+ kind: z.ZodLiteral<"sun">;
32
+ event: z.ZodEnum<{
33
+ dawn: "dawn";
34
+ dusk: "dusk";
35
+ sunrise: "sunrise";
36
+ sunset: "sunset";
37
+ }>;
38
+ offsetMin: z.ZodNumber;
39
+ }, z.core.$strip>, z.ZodObject<{
40
+ kind: z.ZodLiteral<"date">;
41
+ local: z.ZodString;
42
+ }, z.core.$strip>], "kind">;
43
+ export type TimeSpec = z.infer<typeof TimeSpecSchema>;
44
+ /** A day of the week as a schedule names it. */
45
+ export declare const WeekdayKeySchema: z.ZodEnum<{
46
+ fri: "fri";
47
+ mon: "mon";
48
+ sat: "sat";
49
+ sun: "sun";
50
+ thu: "thu";
51
+ tue: "tue";
52
+ wed: "wed";
53
+ }>;
54
+ export type WeekdayKey = z.infer<typeof WeekdayKeySchema>;
55
+ /** Where a spec is read: coordinates for the sun, an IANA zone for the wall clock. */
56
+ export interface TimeSite {
57
+ readonly lat: number;
58
+ readonly lon: number;
59
+ readonly timeZone: string;
60
+ }
61
+ /**
62
+ * A moment as epoch ms, or `null` — "nothing happens". `null` means one of two
63
+ * things and only these: the sun never crosses the event's altitude that day
64
+ * (polar day or night), or a `date` spec asked about a day that is not its own.
65
+ */
66
+ export type Occurrence = number | null;
67
+ /** Is `timeZone` a zone this runtime knows? */
68
+ export declare function isKnownTimeZone(timeZone: string): boolean;
69
+ /** `YYYY-MM-DD` of an instant, read in the zone. */
70
+ export declare function localDateOf(epochMs: number, timeZone: string): string;
71
+ /** The weekday of a `YYYY-MM-DD` civil date (zone-independent). */
72
+ export declare function weekdayOfLocalDate(localDate: string): WeekdayKey;
73
+ /**
74
+ * The moment `spec` happens on the site-local date `localDate` (`YYYY-MM-DD`).
75
+ * See {@link Occurrence} for what `null` means.
76
+ */
77
+ export declare function occurrenceOn(spec: TimeSpec, localDate: string, site: TimeSite): Occurrence;
78
+ /** How far ahead {@link nextOccurrence} looks before giving up: a polar winter fits. */
79
+ export declare const NEXT_OCCURRENCE_HORIZON_DAYS = 400;
80
+ export interface NextOccurrenceOptions {
81
+ /** Only on these weekdays, judged on the site-local date the spec belongs to. */
82
+ readonly days?: readonly WeekdayKey[];
83
+ }
84
+ /**
85
+ * The first moment strictly after `afterMs` at which `spec` happens, or `null`
86
+ * when none does within {@link NEXT_OCCURRENCE_HORIZON_DAYS} (a `date` spec in
87
+ * the past, a sun event that never happens, an empty `days` list).
88
+ */
89
+ export declare function nextOccurrence(spec: TimeSpec, afterMs: number, site: TimeSite, options?: NextOccurrenceOptions): Occurrence;
90
+ /** What `system.getSiteLocation` answers, as far as a spec needs it. */
91
+ export interface SiteReading {
92
+ readonly location: {
93
+ readonly latitude: number;
94
+ readonly longitude: number;
95
+ } | null;
96
+ readonly timeZone: string;
97
+ }
98
+ export type TimeSpecRefusal = 'sun-needs-site-location' | 'unknown-time-zone';
99
+ export type TimeSpecValidation = {
100
+ readonly ok: true;
101
+ readonly site: TimeSite | null;
102
+ } | {
103
+ readonly ok: false;
104
+ readonly reason: TimeSpecRefusal;
105
+ readonly message: string;
106
+ };
107
+ /**
108
+ * Can `spec` be scheduled at this site? A sun spec without a location is
109
+ * REFUSED with its reason — never read as a guessed sunrise. A clock or date
110
+ * spec needs only a zone, and `site` is `null` in that case when there is no
111
+ * location (it is not needed to place them; use {@link siteFor} to read them).
112
+ */
113
+ export declare function validateTimeSpecForSite(spec: TimeSpec, reading: SiteReading): TimeSpecValidation;
114
+ /** The site, when it has a location; a clock spec on a site without one uses {@link zoneOnlySite}. */
115
+ export declare function siteFor(reading: SiteReading): TimeSite | null;
116
+ /** A site that can place a clock or date spec but no sun event (coordinates are unused by those). */
117
+ export declare function zoneOnlySite(timeZone: string): TimeSite;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/types",
3
- "version": "1.2.453",
3
+ "version": "1.2.455",
4
4
  "description": "Shared types, interfaces, and model catalogs for the CamStack detection ecosystem",
5
5
  "keywords": [
6
6
  "camstack",