@bmhall2/skylight-mcp 1.1.7

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 (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +265 -0
  3. package/dist/api/auth.d.ts +38 -0
  4. package/dist/api/auth.d.ts.map +1 -0
  5. package/dist/api/auth.js +62 -0
  6. package/dist/api/auth.js.map +1 -0
  7. package/dist/api/client.d.ts +84 -0
  8. package/dist/api/client.d.ts.map +1 -0
  9. package/dist/api/client.js +228 -0
  10. package/dist/api/client.js.map +1 -0
  11. package/dist/api/endpoints/calendar.d.ts +33 -0
  12. package/dist/api/endpoints/calendar.d.ts.map +1 -0
  13. package/dist/api/endpoints/calendar.js +60 -0
  14. package/dist/api/endpoints/calendar.js.map +1 -0
  15. package/dist/api/endpoints/categories.d.ts +23 -0
  16. package/dist/api/endpoints/categories.d.ts.map +1 -0
  17. package/dist/api/endpoints/categories.js +48 -0
  18. package/dist/api/endpoints/categories.js.map +1 -0
  19. package/dist/api/endpoints/chores.d.ts +50 -0
  20. package/dist/api/endpoints/chores.d.ts.map +1 -0
  21. package/dist/api/endpoints/chores.js +106 -0
  22. package/dist/api/endpoints/chores.js.map +1 -0
  23. package/dist/api/endpoints/devices.d.ts +6 -0
  24. package/dist/api/endpoints/devices.d.ts.map +1 -0
  25. package/dist/api/endpoints/devices.js +10 -0
  26. package/dist/api/endpoints/devices.js.map +1 -0
  27. package/dist/api/endpoints/frames.d.ts +6 -0
  28. package/dist/api/endpoints/frames.d.ts.map +1 -0
  29. package/dist/api/endpoints/frames.js +10 -0
  30. package/dist/api/endpoints/frames.js.map +1 -0
  31. package/dist/api/endpoints/lists.d.ts +55 -0
  32. package/dist/api/endpoints/lists.d.ts.map +1 -0
  33. package/dist/api/endpoints/lists.js +125 -0
  34. package/dist/api/endpoints/lists.js.map +1 -0
  35. package/dist/api/endpoints/meals.d.ts +102 -0
  36. package/dist/api/endpoints/meals.d.ts.map +1 -0
  37. package/dist/api/endpoints/meals.js +100 -0
  38. package/dist/api/endpoints/meals.js.map +1 -0
  39. package/dist/api/endpoints/misc.d.ts +27 -0
  40. package/dist/api/endpoints/misc.d.ts.map +1 -0
  41. package/dist/api/endpoints/misc.js +18 -0
  42. package/dist/api/endpoints/misc.js.map +1 -0
  43. package/dist/api/endpoints/photos.d.ts +13 -0
  44. package/dist/api/endpoints/photos.d.ts.map +1 -0
  45. package/dist/api/endpoints/photos.js +10 -0
  46. package/dist/api/endpoints/photos.js.map +1 -0
  47. package/dist/api/endpoints/rewards.d.ts +49 -0
  48. package/dist/api/endpoints/rewards.d.ts.map +1 -0
  49. package/dist/api/endpoints/rewards.js +105 -0
  50. package/dist/api/endpoints/rewards.js.map +1 -0
  51. package/dist/api/endpoints/taskbox.d.ts +13 -0
  52. package/dist/api/endpoints/taskbox.d.ts.map +1 -0
  53. package/dist/api/endpoints/taskbox.js +22 -0
  54. package/dist/api/endpoints/taskbox.js.map +1 -0
  55. package/dist/api/generated-types.d.ts +18967 -0
  56. package/dist/api/generated-types.d.ts.map +1 -0
  57. package/dist/api/generated-types.js +6 -0
  58. package/dist/api/generated-types.js.map +1 -0
  59. package/dist/api/types.d.ts +283 -0
  60. package/dist/api/types.d.ts.map +1 -0
  61. package/dist/api/types.js +5 -0
  62. package/dist/api/types.js.map +1 -0
  63. package/dist/config.d.ts +52 -0
  64. package/dist/config.d.ts.map +1 -0
  65. package/dist/config.js +80 -0
  66. package/dist/config.js.map +1 -0
  67. package/dist/index.d.ts +3 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +11 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/server.d.ts +7 -0
  72. package/dist/server.d.ts.map +1 -0
  73. package/dist/server.js +48 -0
  74. package/dist/server.js.map +1 -0
  75. package/dist/tools/calendar.d.ts +3 -0
  76. package/dist/tools/calendar.d.ts.map +1 -0
  77. package/dist/tools/calendar.js +297 -0
  78. package/dist/tools/calendar.js.map +1 -0
  79. package/dist/tools/chores.d.ts +3 -0
  80. package/dist/tools/chores.d.ts.map +1 -0
  81. package/dist/tools/chores.js +349 -0
  82. package/dist/tools/chores.js.map +1 -0
  83. package/dist/tools/family.d.ts +3 -0
  84. package/dist/tools/family.d.ts.map +1 -0
  85. package/dist/tools/family.js +182 -0
  86. package/dist/tools/family.js.map +1 -0
  87. package/dist/tools/lists.d.ts +3 -0
  88. package/dist/tools/lists.d.ts.map +1 -0
  89. package/dist/tools/lists.js +481 -0
  90. package/dist/tools/lists.js.map +1 -0
  91. package/dist/tools/meals.d.ts +3 -0
  92. package/dist/tools/meals.d.ts.map +1 -0
  93. package/dist/tools/meals.js +319 -0
  94. package/dist/tools/meals.js.map +1 -0
  95. package/dist/tools/misc.d.ts +3 -0
  96. package/dist/tools/misc.d.ts.map +1 -0
  97. package/dist/tools/misc.js +101 -0
  98. package/dist/tools/misc.js.map +1 -0
  99. package/dist/tools/photos.d.ts +3 -0
  100. package/dist/tools/photos.d.ts.map +1 -0
  101. package/dist/tools/photos.js +42 -0
  102. package/dist/tools/photos.js.map +1 -0
  103. package/dist/tools/rewards.d.ts +3 -0
  104. package/dist/tools/rewards.d.ts.map +1 -0
  105. package/dist/tools/rewards.js +338 -0
  106. package/dist/tools/rewards.js.map +1 -0
  107. package/dist/tools/tasks.d.ts +3 -0
  108. package/dist/tools/tasks.d.ts.map +1 -0
  109. package/dist/tools/tasks.js +68 -0
  110. package/dist/tools/tasks.js.map +1 -0
  111. package/dist/utils/dates.d.ts +26 -0
  112. package/dist/utils/dates.d.ts.map +1 -0
  113. package/dist/utils/dates.js +109 -0
  114. package/dist/utils/dates.js.map +1 -0
  115. package/dist/utils/errors.d.ts +45 -0
  116. package/dist/utils/errors.d.ts.map +1 -0
  117. package/dist/utils/errors.js +102 -0
  118. package/dist/utils/errors.js.map +1 -0
  119. package/package.json +59 -0
@@ -0,0 +1,228 @@
1
+ import { getConfig, usesEmailAuth } from "../config.js";
2
+ import { login } from "./auth.js";
3
+ import { AuthenticationError, NotFoundError, RateLimitError, SkylightError, } from "../utils/errors.js";
4
+ const BASE_URL = "https://app.ourskylight.com";
5
+ /**
6
+ * Skylight API Client
7
+ * Handles authentication and HTTP requests to the Skylight API
8
+ */
9
+ export class SkylightClient {
10
+ config;
11
+ resolvedToken = null;
12
+ resolvedUserId = null;
13
+ loginPromise = null;
14
+ subscriptionStatus = null;
15
+ constructor(config) {
16
+ this.config = config ?? getConfig();
17
+ }
18
+ /**
19
+ * Get the authentication credentials
20
+ * If using email/password auth, will login first
21
+ */
22
+ async getCredentials() {
23
+ // If we already have a resolved token, use it
24
+ if (this.resolvedToken) {
25
+ return { token: this.resolvedToken, userId: this.resolvedUserId };
26
+ }
27
+ // If using token-based auth, use the configured token
28
+ if (!usesEmailAuth(this.config)) {
29
+ return { token: this.config.token, userId: null };
30
+ }
31
+ // If already logging in, wait for that to complete
32
+ if (this.loginPromise) {
33
+ const result = await this.loginPromise;
34
+ return { token: result.token, userId: result.userId };
35
+ }
36
+ // Login with email/password
37
+ this.loginPromise = this.performLogin();
38
+ try {
39
+ const result = await this.loginPromise;
40
+ this.resolvedToken = result.token;
41
+ this.resolvedUserId = result.userId;
42
+ return result;
43
+ }
44
+ finally {
45
+ this.loginPromise = null;
46
+ }
47
+ }
48
+ /**
49
+ * Perform login and return token and userId
50
+ */
51
+ async performLogin() {
52
+ const { email, password } = this.config;
53
+ if (!email || !password) {
54
+ throw new AuthenticationError("Email and password are required for login");
55
+ }
56
+ console.error("Logging in to Skylight...");
57
+ const result = await login(email, password);
58
+ this.subscriptionStatus = result.subscriptionStatus;
59
+ console.error(`Logged in as ${result.email} (${result.subscriptionStatus})`);
60
+ return { token: result.token, userId: result.userId };
61
+ }
62
+ /**
63
+ * Build the Authorization header
64
+ * For email/password auth: Basic base64(userId:token)
65
+ * For manual token auth: Bearer or Basic based on config
66
+ */
67
+ async getAuthHeader() {
68
+ const { token, userId } = await this.getCredentials();
69
+ // If using email/password auth, use Basic auth with userId:token
70
+ if (usesEmailAuth(this.config) && userId) {
71
+ const credentials = Buffer.from(`${userId}:${token}`).toString("base64");
72
+ return `Basic ${credentials}`;
73
+ }
74
+ // For manual token config, respect the authType setting
75
+ if (this.config.authType === "basic") {
76
+ return `Basic ${token}`;
77
+ }
78
+ return `Bearer ${token}`;
79
+ }
80
+ /**
81
+ * Build URL with query parameters
82
+ */
83
+ buildUrl(endpoint, params) {
84
+ const url = new URL(endpoint, BASE_URL);
85
+ if (params) {
86
+ for (const [key, value] of Object.entries(params)) {
87
+ if (value !== undefined) {
88
+ url.searchParams.set(key, String(value));
89
+ }
90
+ }
91
+ }
92
+ return url.toString();
93
+ }
94
+ /**
95
+ * Handle API response errors
96
+ */
97
+ async handleResponseError(response, url) {
98
+ const status = response.status;
99
+ if (status === 401) {
100
+ // Clear cached credentials on auth failure
101
+ this.resolvedToken = null;
102
+ this.resolvedUserId = null;
103
+ console.error(`[client] 401 Unauthorized for ${url}`);
104
+ if (usesEmailAuth(this.config)) {
105
+ throw new AuthenticationError("API request returned 401. This may indicate your frame ID is incorrect or doesn't belong to this account. " +
106
+ "Please verify your SKYLIGHT_FRAME_ID environment variable.");
107
+ }
108
+ throw new AuthenticationError();
109
+ }
110
+ if (status === 404) {
111
+ throw new NotFoundError("Resource");
112
+ }
113
+ if (status === 429) {
114
+ const retryAfter = response.headers.get("Retry-After");
115
+ throw new RateLimitError(retryAfter ? parseInt(retryAfter, 10) : undefined);
116
+ }
117
+ // Try to get error details from response
118
+ let errorMessage = `HTTP ${status}`;
119
+ try {
120
+ const errorBody = await response.text();
121
+ if (errorBody) {
122
+ errorMessage += `: ${errorBody.slice(0, 200)}`;
123
+ }
124
+ }
125
+ catch {
126
+ // Ignore parse errors
127
+ }
128
+ throw new SkylightError(errorMessage, "HTTP_ERROR", status, status >= 500);
129
+ }
130
+ /**
131
+ * Make an authenticated request to the Skylight API
132
+ */
133
+ async request(endpoint, options = {}, isRetry = false) {
134
+ const { method = "GET", params, body } = options;
135
+ // Replace {frameId} placeholder with actual frame ID
136
+ const resolvedEndpoint = endpoint.replace("{frameId}", this.config.frameId);
137
+ const url = this.buildUrl(resolvedEndpoint, params);
138
+ console.error(`[client] ${method} ${url}`);
139
+ const headers = {
140
+ Authorization: await this.getAuthHeader(),
141
+ Accept: "application/json",
142
+ };
143
+ if (body) {
144
+ headers["Content-Type"] = "application/json";
145
+ }
146
+ const response = await fetch(url, {
147
+ method,
148
+ headers,
149
+ body: body ? JSON.stringify(body) : undefined,
150
+ });
151
+ console.error(`[client] Response: ${response.status}`);
152
+ if (!response.ok) {
153
+ // For email/password auth, try re-login once on 401
154
+ if (response.status === 401 && usesEmailAuth(this.config) && !isRetry) {
155
+ console.error("[client] Got 401, attempting re-login...");
156
+ this.resolvedToken = null;
157
+ this.resolvedUserId = null;
158
+ return this.request(endpoint, options, true);
159
+ }
160
+ await this.handleResponseError(response, url);
161
+ }
162
+ // Handle 304 Not Modified
163
+ if (response.status === 304) {
164
+ return {};
165
+ }
166
+ return response.json();
167
+ }
168
+ /**
169
+ * GET request helper
170
+ */
171
+ async get(endpoint, params) {
172
+ return this.request(endpoint, { method: "GET", params });
173
+ }
174
+ /**
175
+ * POST request helper
176
+ */
177
+ async post(endpoint, body) {
178
+ return this.request(endpoint, { method: "POST", body });
179
+ }
180
+ /**
181
+ * Get the frame ID from config
182
+ */
183
+ get frameId() {
184
+ return this.config.frameId;
185
+ }
186
+ /**
187
+ * Get the timezone from config
188
+ */
189
+ get timezone() {
190
+ return this.config.timezone;
191
+ }
192
+ /**
193
+ * Check if user has Plus subscription
194
+ */
195
+ hasPlus() {
196
+ return this.subscriptionStatus === "plus";
197
+ }
198
+ /**
199
+ * Get the subscription status
200
+ */
201
+ getSubscriptionStatus() {
202
+ return this.subscriptionStatus;
203
+ }
204
+ /**
205
+ * Initialize the client (triggers login if using email/password auth)
206
+ */
207
+ async initialize() {
208
+ await this.getCredentials();
209
+ }
210
+ }
211
+ // Singleton instance
212
+ let clientInstance = null;
213
+ export function getClient() {
214
+ if (!clientInstance) {
215
+ clientInstance = new SkylightClient();
216
+ }
217
+ return clientInstance;
218
+ }
219
+ /**
220
+ * Initialize the client singleton and return it
221
+ * This triggers login if using email/password auth
222
+ */
223
+ export async function initializeClient() {
224
+ const client = getClient();
225
+ await client.initialize();
226
+ return client;
227
+ }
228
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type { CalendarEventResource, SourceCalendarResource, CategoryResource, CreateCalendarEventRequest, UpdateCalendarEventRequest } from "../types.js";
2
+ export interface GetCalendarEventsOptions {
3
+ dateMin: string;
4
+ dateMax: string;
5
+ timezone?: string;
6
+ include?: string;
7
+ }
8
+ export interface CalendarEventsResult {
9
+ events: CalendarEventResource[];
10
+ categories: CategoryResource[];
11
+ }
12
+ /**
13
+ * Get calendar events for a date range
14
+ * Note: The API treats date_max as exclusive, so we add 1 day to include events on the end date
15
+ */
16
+ export declare function getCalendarEvents(options: GetCalendarEventsOptions): Promise<CalendarEventsResult>;
17
+ /**
18
+ * Get source calendars (connected calendar accounts)
19
+ */
20
+ export declare function getSourceCalendars(): Promise<SourceCalendarResource[]>;
21
+ /**
22
+ * Create a calendar event
23
+ */
24
+ export declare function createCalendarEvent(data: CreateCalendarEventRequest): Promise<CalendarEventResource>;
25
+ /**
26
+ * Update a calendar event
27
+ */
28
+ export declare function updateCalendarEvent(eventId: string, data: UpdateCalendarEventRequest): Promise<CalendarEventResource>;
29
+ /**
30
+ * Delete a calendar event
31
+ */
32
+ export declare function deleteCalendarEvent(eventId: string): Promise<void>;
33
+ //# sourceMappingURL=calendar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../../../src/api/endpoints/calendar.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,qBAAqB,EAGrB,sBAAsB,EACtB,gBAAgB,EAChB,0BAA0B,EAC1B,0BAA0B,EAC3B,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,qBAAqB,EAAE,CAAC;IAChC,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAWD;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,oBAAoB,CAAC,CAqB/B;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAM5E;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,0BAA0B,GAC/B,OAAO,CAAC,qBAAqB,CAAC,CAOhC;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,0BAA0B,GAC/B,OAAO,CAAC,qBAAqB,CAAC,CAOhC;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKxE"}
@@ -0,0 +1,60 @@
1
+ import { getClient } from "../client.js";
2
+ /**
3
+ * Add days to a date string in YYYY-MM-DD format
4
+ */
5
+ function addDays(dateStr, days) {
6
+ const date = new Date(dateStr + "T00:00:00");
7
+ date.setDate(date.getDate() + days);
8
+ return date.toISOString().split("T")[0];
9
+ }
10
+ /**
11
+ * Get calendar events for a date range
12
+ * Note: The API treats date_max as exclusive, so we add 1 day to include events on the end date
13
+ */
14
+ export async function getCalendarEvents(options) {
15
+ const client = getClient();
16
+ // API treats date_max as exclusive, so add 1 day to include events on the end date
17
+ const adjustedDateMax = addDays(options.dateMax, 1);
18
+ const response = await client.get("/api/frames/{frameId}/calendar_events", {
19
+ date_min: options.dateMin,
20
+ date_max: adjustedDateMax,
21
+ timezone: options.timezone ?? client.timezone,
22
+ include: options.include,
23
+ });
24
+ const categories = (response.included ?? []).filter((item) => item.type === "category");
25
+ return { events: response.data, categories };
26
+ }
27
+ /**
28
+ * Get source calendars (connected calendar accounts)
29
+ */
30
+ export async function getSourceCalendars() {
31
+ const client = getClient();
32
+ const response = await client.get("/api/frames/{frameId}/source_calendars");
33
+ return response.data;
34
+ }
35
+ /**
36
+ * Create a calendar event
37
+ */
38
+ export async function createCalendarEvent(data) {
39
+ const client = getClient();
40
+ const response = await client.post("/api/frames/{frameId}/calendar_events", data);
41
+ return response.data;
42
+ }
43
+ /**
44
+ * Update a calendar event
45
+ */
46
+ export async function updateCalendarEvent(eventId, data) {
47
+ const client = getClient();
48
+ const response = await client.request(`/api/frames/{frameId}/calendar_events/${eventId}`, { method: "PUT", body: data });
49
+ return response.data;
50
+ }
51
+ /**
52
+ * Delete a calendar event
53
+ */
54
+ export async function deleteCalendarEvent(eventId) {
55
+ const client = getClient();
56
+ await client.request(`/api/frames/{frameId}/calendar_events/${eventId}`, {
57
+ method: "DELETE",
58
+ });
59
+ }
60
+ //# sourceMappingURL=calendar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar.js","sourceRoot":"","sources":["../../../src/api/endpoints/calendar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAwBzC;;GAEG;AACH,SAAS,OAAO,CAAC,OAAe,EAAE,IAAY;IAC5C,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC,CAAC;IAC7C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACpC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAiC;IAEjC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAE3B,mFAAmF;IACnF,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAEpD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAC/B,uCAAuC,EACvC;QACE,QAAQ,EAAE,OAAO,CAAC,OAAO;QACzB,QAAQ,EAAE,eAAe;QACzB,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ;QAC7C,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CACF,CAAC;IAEF,MAAM,UAAU,GAAG,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,MAAM,CACjD,CAAC,IAAI,EAA4B,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,UAAU,CAC7D,CAAC;IAEF,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAC/B,wCAAwC,CACzC,CAAC;IACF,OAAO,QAAQ,CAAC,IAAI,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAAgC;IAEhC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAChC,uCAAuC,EACvC,IAAI,CACL,CAAC;IACF,OAAO,QAAQ,CAAC,IAAI,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAAe,EACf,IAAgC;IAEhC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CACnC,yCAAyC,OAAO,EAAE,EAClD,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAC9B,CAAC;IACF,OAAO,QAAQ,CAAC,IAAI,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAe;IACvD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,MAAM,CAAC,OAAO,CAAC,yCAAyC,OAAO,EAAE,EAAE;QACvE,MAAM,EAAE,QAAQ;KACjB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { CategoryResource } from "../types.js";
2
+ /**
3
+ * Get all categories (family members/profiles)
4
+ */
5
+ export declare function getCategories(useCache?: boolean): Promise<CategoryResource[]>;
6
+ /**
7
+ * Clear the categories cache
8
+ */
9
+ export declare function clearCategoriesCache(): void;
10
+ /**
11
+ * Find a category by name (case-insensitive partial match)
12
+ * Categories represent family members like "Dad", "Mom", "Kids", etc.
13
+ */
14
+ export declare function findCategoryByName(name: string): Promise<CategoryResource | undefined>;
15
+ /**
16
+ * Get categories that are linked to profiles (actual family members)
17
+ */
18
+ export declare function getFamilyMembers(): Promise<CategoryResource[]>;
19
+ /**
20
+ * Get categories selected for the chore chart
21
+ */
22
+ export declare function getChoreChartCategories(): Promise<CategoryResource[]>;
23
+ //# sourceMappingURL=categories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"categories.d.ts","sourceRoot":"","sources":["../../../src/api/endpoints/categories.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAKxE;;GAEG;AACH,wBAAsB,aAAa,CAAC,QAAQ,UAAO,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAShF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAQ5F;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAGpE;AAED;;GAEG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAG3E"}
@@ -0,0 +1,48 @@
1
+ import { getClient } from "../client.js";
2
+ // Cache for categories (family members)
3
+ let categoriesCache = null;
4
+ /**
5
+ * Get all categories (family members/profiles)
6
+ */
7
+ export async function getCategories(useCache = true) {
8
+ if (useCache && categoriesCache) {
9
+ return categoriesCache;
10
+ }
11
+ const client = getClient();
12
+ const response = await client.get("/api/frames/{frameId}/categories");
13
+ categoriesCache = response.data;
14
+ return response.data;
15
+ }
16
+ /**
17
+ * Clear the categories cache
18
+ */
19
+ export function clearCategoriesCache() {
20
+ categoriesCache = null;
21
+ }
22
+ /**
23
+ * Find a category by name (case-insensitive partial match)
24
+ * Categories represent family members like "Dad", "Mom", "Kids", etc.
25
+ */
26
+ export async function findCategoryByName(name) {
27
+ const categories = await getCategories();
28
+ const lowerName = name.toLowerCase();
29
+ return categories.find((cat) => {
30
+ const label = cat.attributes.label?.toLowerCase();
31
+ return label && (label === lowerName || label.includes(lowerName));
32
+ });
33
+ }
34
+ /**
35
+ * Get categories that are linked to profiles (actual family members)
36
+ */
37
+ export async function getFamilyMembers() {
38
+ const categories = await getCategories();
39
+ return categories.filter((cat) => cat.attributes.linked_to_profile);
40
+ }
41
+ /**
42
+ * Get categories selected for the chore chart
43
+ */
44
+ export async function getChoreChartCategories() {
45
+ const categories = await getCategories();
46
+ return categories.filter((cat) => cat.attributes.selected_for_chore_chart);
47
+ }
48
+ //# sourceMappingURL=categories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"categories.js","sourceRoot":"","sources":["../../../src/api/endpoints/categories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,wCAAwC;AACxC,IAAI,eAAe,GAA8B,IAAI,CAAC;AAEtD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAQ,GAAG,IAAI;IACjD,IAAI,QAAQ,IAAI,eAAe,EAAE,CAAC;QAChC,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAAqB,kCAAkC,CAAC,CAAC;IAC1F,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC;IAChC,OAAO,QAAQ,CAAC,IAAI,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,eAAe,GAAG,IAAI,CAAC;AACzB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAY;IACnD,MAAM,UAAU,GAAG,MAAM,aAAa,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAErC,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC;QAClD,OAAO,KAAK,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,UAAU,GAAG,MAAM,aAAa,EAAE,CAAC;IACzC,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;AACtE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC3C,MAAM,UAAU,GAAG,MAAM,aAAa,EAAE,CAAC;IACzC,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,50 @@
1
+ import type { ChoreResource, CategoryResource } from "../types.js";
2
+ export interface GetChoresOptions {
3
+ after?: string;
4
+ before?: string;
5
+ includeLate?: boolean;
6
+ filterLinkedToProfile?: boolean;
7
+ }
8
+ export interface GetChoresResult {
9
+ chores: ChoreResource[];
10
+ categories: CategoryResource[];
11
+ }
12
+ /**
13
+ * Get chores for a date range
14
+ */
15
+ export declare function getChores(options?: GetChoresOptions): Promise<GetChoresResult>;
16
+ export interface CreateChoreOptions {
17
+ summary: string;
18
+ start: string;
19
+ startTime?: string;
20
+ status?: string;
21
+ recurring?: boolean;
22
+ recurrenceSet?: string;
23
+ categoryId?: string;
24
+ rewardPoints?: number;
25
+ emojiIcon?: string;
26
+ }
27
+ /**
28
+ * Create a new chore
29
+ */
30
+ export declare function createChore(options: CreateChoreOptions): Promise<ChoreResource>;
31
+ export interface UpdateChoreOptions {
32
+ summary?: string;
33
+ start?: string;
34
+ startTime?: string | null;
35
+ status?: string;
36
+ recurring?: boolean;
37
+ recurrenceSet?: string | null;
38
+ categoryId?: string | null;
39
+ rewardPoints?: number | null;
40
+ emojiIcon?: string | null;
41
+ }
42
+ /**
43
+ * Update an existing chore
44
+ */
45
+ export declare function updateChore(choreId: string, options: UpdateChoreOptions): Promise<ChoreResource>;
46
+ /**
47
+ * Delete a chore
48
+ */
49
+ export declare function deleteChore(choreId: string): Promise<void>;
50
+ //# sourceMappingURL=chores.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chores.d.ts","sourceRoot":"","sources":["../../../src/api/endpoints/chores.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,aAAa,EACb,gBAAgB,EAGjB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CAqBxF;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAqCrF;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,aAAa,CAAC,CAqCxB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKhE"}
@@ -0,0 +1,106 @@
1
+ import { getClient } from "../client.js";
2
+ /**
3
+ * Get chores for a date range
4
+ */
5
+ export async function getChores(options = {}) {
6
+ const client = getClient();
7
+ const params = {
8
+ after: options.after,
9
+ before: options.before,
10
+ include_late: options.includeLate,
11
+ };
12
+ if (options.filterLinkedToProfile) {
13
+ params.filter = "linked_to_profile";
14
+ }
15
+ const response = await client.get("/api/frames/{frameId}/chores", params);
16
+ return {
17
+ chores: response.data,
18
+ categories: response.included ?? [],
19
+ };
20
+ }
21
+ /**
22
+ * Create a new chore
23
+ */
24
+ export async function createChore(options) {
25
+ const client = getClient();
26
+ const request = {
27
+ data: {
28
+ type: "chore",
29
+ attributes: {
30
+ summary: options.summary,
31
+ start: options.start,
32
+ start_time: options.startTime ?? null,
33
+ status: options.status ?? "pending",
34
+ recurring: options.recurring ?? false,
35
+ recurrence_set: options.recurrenceSet ?? null,
36
+ reward_points: options.rewardPoints ?? null,
37
+ emoji_icon: options.emojiIcon ?? null,
38
+ },
39
+ },
40
+ };
41
+ // Add category relationship if provided
42
+ if (options.categoryId) {
43
+ request.data.relationships = {
44
+ category: {
45
+ data: {
46
+ type: "category",
47
+ id: options.categoryId,
48
+ },
49
+ },
50
+ };
51
+ }
52
+ const response = await client.post("/api/frames/{frameId}/chores", request);
53
+ return response.data;
54
+ }
55
+ /**
56
+ * Update an existing chore
57
+ */
58
+ export async function updateChore(choreId, options) {
59
+ const client = getClient();
60
+ const request = {
61
+ data: {
62
+ type: "chore",
63
+ attributes: {},
64
+ },
65
+ };
66
+ // Map options to attributes
67
+ if (options.summary !== undefined)
68
+ request.data.attributes.summary = options.summary;
69
+ if (options.start !== undefined)
70
+ request.data.attributes.start = options.start;
71
+ if (options.startTime !== undefined)
72
+ request.data.attributes.start_time = options.startTime;
73
+ if (options.status !== undefined)
74
+ request.data.attributes.status = options.status;
75
+ if (options.recurring !== undefined)
76
+ request.data.attributes.recurring = options.recurring;
77
+ if (options.recurrenceSet !== undefined)
78
+ request.data.attributes.recurrence_set = options.recurrenceSet;
79
+ if (options.rewardPoints !== undefined)
80
+ request.data.attributes.reward_points = options.rewardPoints;
81
+ if (options.emojiIcon !== undefined)
82
+ request.data.attributes.emoji_icon = options.emojiIcon;
83
+ // Handle category relationship
84
+ if (options.categoryId !== undefined) {
85
+ if (options.categoryId === null) {
86
+ request.data.relationships = { category: { data: null } };
87
+ }
88
+ else {
89
+ request.data.relationships = {
90
+ category: { data: { type: "category", id: options.categoryId } },
91
+ };
92
+ }
93
+ }
94
+ const response = await client.request(`/api/frames/{frameId}/chores/${choreId}`, { method: "PUT", body: request });
95
+ return response.data;
96
+ }
97
+ /**
98
+ * Delete a chore
99
+ */
100
+ export async function deleteChore(choreId) {
101
+ const client = getClient();
102
+ await client.request(`/api/frames/{frameId}/chores/${choreId}`, {
103
+ method: "DELETE",
104
+ });
105
+ }
106
+ //# sourceMappingURL=chores.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chores.js","sourceRoot":"","sources":["../../../src/api/endpoints/chores.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { DeviceResource } from "../types.js";
2
+ /**
3
+ * Get all Skylight devices in the household
4
+ */
5
+ export declare function getDevices(): Promise<DeviceResource[]>;
6
+ //# sourceMappingURL=devices.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devices.d.ts","sourceRoot":"","sources":["../../../src/api/endpoints/devices.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,cAAc,EAAE,MAAM,aAAa,CAAC;AAEnE;;GAEG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAI5D"}
@@ -0,0 +1,10 @@
1
+ import { getClient } from "../client.js";
2
+ /**
3
+ * Get all Skylight devices in the household
4
+ */
5
+ export async function getDevices() {
6
+ const client = getClient();
7
+ const response = await client.get("/api/frames/{frameId}/devices");
8
+ return response.data;
9
+ }
10
+ //# sourceMappingURL=devices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devices.js","sourceRoot":"","sources":["../../../src/api/endpoints/devices.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAAkB,+BAA+B,CAAC,CAAC;IACpF,OAAO,QAAQ,CAAC,IAAI,CAAC;AACvB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { FrameResource } from "../types.js";
2
+ /**
3
+ * Get frame (household) information
4
+ */
5
+ export declare function getFrame(): Promise<FrameResource>;
6
+ //# sourceMappingURL=frames.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frames.d.ts","sourceRoot":"","sources":["../../../src/api/endpoints/frames.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,aAAa,EAAE,MAAM,aAAa,CAAC;AAEhE;;GAEG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,aAAa,CAAC,CAIvD"}
@@ -0,0 +1,10 @@
1
+ import { getClient } from "../client.js";
2
+ /**
3
+ * Get frame (household) information
4
+ */
5
+ export async function getFrame() {
6
+ const client = getClient();
7
+ const response = await client.get("/api/frames/{frameId}");
8
+ return response.data;
9
+ }
10
+ //# sourceMappingURL=frames.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frames.js","sourceRoot":"","sources":["../../../src/api/endpoints/frames.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAAgB,uBAAuB,CAAC,CAAC;IAC1E,OAAO,QAAQ,CAAC,IAAI,CAAC;AACvB,CAAC"}