edilkamin 1.7.3 → 1.8.0

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 (77) hide show
  1. package/.github/workflows/cli-tests.yml +6 -0
  2. package/README.md +36 -3
  3. package/dist/cjs/package.json +95 -0
  4. package/dist/cjs/src/bluetooth-utils.d.ts +13 -0
  5. package/dist/cjs/src/bluetooth-utils.js +28 -0
  6. package/dist/cjs/src/bluetooth-utils.test.js +35 -0
  7. package/dist/cjs/src/bluetooth.d.ts +40 -0
  8. package/dist/cjs/src/bluetooth.js +107 -0
  9. package/dist/cjs/src/browser-bundle.test.js +64 -0
  10. package/dist/cjs/src/buffer-utils.js +78 -0
  11. package/dist/cjs/src/buffer-utils.test.js +186 -0
  12. package/dist/cjs/src/cli.js +253 -0
  13. package/dist/cjs/src/configureAmplify.test.js +42 -0
  14. package/dist/cjs/src/constants.js +9 -0
  15. package/dist/{esm → cjs/src}/index.d.ts +2 -1
  16. package/dist/cjs/src/index.js +24 -0
  17. package/dist/cjs/src/library.js +324 -0
  18. package/dist/cjs/src/library.test.js +547 -0
  19. package/dist/cjs/src/serial-utils.js +50 -0
  20. package/dist/cjs/src/serial-utils.test.js +50 -0
  21. package/dist/cjs/src/token-storage.js +119 -0
  22. package/dist/{esm → cjs/src}/types.d.ts +14 -1
  23. package/dist/cjs/src/types.js +2 -0
  24. package/dist/esm/package.json +95 -0
  25. package/dist/esm/src/bluetooth-utils.d.ts +13 -0
  26. package/dist/esm/src/bluetooth-utils.js +25 -0
  27. package/dist/esm/src/bluetooth-utils.test.d.ts +1 -0
  28. package/dist/esm/src/bluetooth-utils.test.js +33 -0
  29. package/dist/esm/src/bluetooth.d.ts +40 -0
  30. package/dist/esm/src/bluetooth.js +100 -0
  31. package/dist/esm/src/browser-bundle.test.d.ts +1 -0
  32. package/dist/esm/{browser-bundle.test.js → src/browser-bundle.test.js} +1 -1
  33. package/dist/esm/src/buffer-utils.d.ts +25 -0
  34. package/dist/esm/src/buffer-utils.test.d.ts +1 -0
  35. package/dist/esm/src/cli.d.ts +3 -0
  36. package/dist/esm/src/configureAmplify.test.d.ts +1 -0
  37. package/dist/esm/src/constants.d.ts +4 -0
  38. package/dist/esm/src/index.d.ts +7 -0
  39. package/dist/esm/{index.js → src/index.js} +1 -0
  40. package/dist/esm/src/library.d.ts +55 -0
  41. package/dist/esm/src/library.test.d.ts +1 -0
  42. package/dist/esm/src/serial-utils.d.ts +33 -0
  43. package/dist/esm/src/serial-utils.test.d.ts +1 -0
  44. package/dist/esm/src/token-storage.d.ts +14 -0
  45. package/dist/esm/src/types.d.ts +86 -0
  46. package/dist/esm/src/types.js +1 -0
  47. package/package.json +22 -11
  48. package/src/bluetooth-utils.test.ts +46 -0
  49. package/src/bluetooth-utils.ts +29 -0
  50. package/src/bluetooth.ts +115 -0
  51. package/src/browser-bundle.test.ts +1 -1
  52. package/src/index.ts +2 -0
  53. package/src/types.ts +15 -0
  54. package/tsconfig.cjs.json +2 -2
  55. package/tsconfig.json +3 -3
  56. /package/dist/{esm/browser-bundle.test.d.ts → cjs/src/bluetooth-utils.test.d.ts} +0 -0
  57. /package/dist/{esm/buffer-utils.test.d.ts → cjs/src/browser-bundle.test.d.ts} +0 -0
  58. /package/dist/{esm → cjs/src}/buffer-utils.d.ts +0 -0
  59. /package/dist/{esm/configureAmplify.test.d.ts → cjs/src/buffer-utils.test.d.ts} +0 -0
  60. /package/dist/{esm → cjs/src}/cli.d.ts +0 -0
  61. /package/dist/{esm/library.test.d.ts → cjs/src/configureAmplify.test.d.ts} +0 -0
  62. /package/dist/{esm → cjs/src}/constants.d.ts +0 -0
  63. /package/dist/{esm → cjs/src}/library.d.ts +0 -0
  64. /package/dist/{esm/serial-utils.test.d.ts → cjs/src/library.test.d.ts} +0 -0
  65. /package/dist/{esm → cjs/src}/serial-utils.d.ts +0 -0
  66. /package/dist/{esm/types.js → cjs/src/serial-utils.test.d.ts} +0 -0
  67. /package/dist/{esm → cjs/src}/token-storage.d.ts +0 -0
  68. /package/dist/esm/{buffer-utils.js → src/buffer-utils.js} +0 -0
  69. /package/dist/esm/{buffer-utils.test.js → src/buffer-utils.test.js} +0 -0
  70. /package/dist/esm/{cli.js → src/cli.js} +0 -0
  71. /package/dist/esm/{configureAmplify.test.js → src/configureAmplify.test.js} +0 -0
  72. /package/dist/esm/{constants.js → src/constants.js} +0 -0
  73. /package/dist/esm/{library.js → src/library.js} +0 -0
  74. /package/dist/esm/{library.test.js → src/library.test.js} +0 -0
  75. /package/dist/esm/{serial-utils.js → src/serial-utils.js} +0 -0
  76. /package/dist/esm/{serial-utils.test.js → src/serial-utils.test.js} +0 -0
  77. /package/dist/esm/{token-storage.js → src/token-storage.js} +0 -0
@@ -0,0 +1,324 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
+ return new (P || (P = Promise))(function (resolve, reject) {
38
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
42
+ });
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.signIn = exports.headers = exports.getSession = exports.createAuthService = exports.configureAmplify = exports.configure = void 0;
46
+ const assert_1 = require("assert");
47
+ const aws_amplify_1 = require("aws-amplify");
48
+ const amplifyAuth = __importStar(require("aws-amplify/auth"));
49
+ const cognito_1 = require("aws-amplify/auth/cognito");
50
+ const buffer_utils_1 = require("./buffer-utils");
51
+ const constants_1 = require("./constants");
52
+ /**
53
+ * Makes a fetch request and returns parsed JSON response.
54
+ * Throws an error for non-2xx status codes.
55
+ */
56
+ const fetchJson = (baseURL_1, path_1, ...args_1) => __awaiter(void 0, [baseURL_1, path_1, ...args_1], void 0, function* (baseURL, path, options = {}) {
57
+ const response = yield fetch(`${baseURL}${path}`, options);
58
+ if (!response.ok) {
59
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
60
+ }
61
+ return response.json();
62
+ });
63
+ const amplifyconfiguration = {
64
+ aws_project_region: "eu-central-1",
65
+ aws_user_pools_id: "eu-central-1_BYmQ2VBlo",
66
+ aws_user_pools_web_client_id: "7sc1qltkqobo3ddqsk4542dg2h",
67
+ };
68
+ /**
69
+ * Generates headers with a JWT token for authenticated requests.
70
+ * @param {string} jwtToken - The JWT token for authorization.
71
+ * @returns {object} - The headers object with the Authorization field.
72
+ */
73
+ const headers = (jwtToken) => ({ Authorization: `Bearer ${jwtToken}` });
74
+ exports.headers = headers;
75
+ let amplifyConfigured = false;
76
+ /**
77
+ * Configures Amplify if not already configured.
78
+ * Uses a local flag to avoid calling getConfig() which prints a warning.
79
+ * @param {object} [storage] - Optional custom storage adapter for token persistence
80
+ */
81
+ const configureAmplify = (storage) => {
82
+ if (amplifyConfigured)
83
+ return;
84
+ aws_amplify_1.Amplify.configure(amplifyconfiguration);
85
+ if (storage) {
86
+ cognito_1.cognitoUserPoolsTokenProvider.setKeyValueStorage(storage);
87
+ }
88
+ amplifyConfigured = true;
89
+ };
90
+ exports.configureAmplify = configureAmplify;
91
+ /**
92
+ * Creates an authentication service with sign-in functionality.
93
+ * @param {typeof amplifyAuth} auth - The authentication module to use.
94
+ * @returns {object} - An object containing authentication-related methods.
95
+ */
96
+ const createAuthService = (auth) => {
97
+ /**
98
+ * Signs in a user with the provided credentials.
99
+ * @param {string} username - The username of the user.
100
+ * @param {string} password - The password of the user.
101
+ * @param {boolean} [legacy=false] - If true, returns accessToken for legacy API.
102
+ * @returns {Promise<string>} - The JWT token of the signed-in user.
103
+ * @throws {Error} - If sign-in fails or no tokens are retrieved.
104
+ */
105
+ const signIn = (username_1, password_1, ...args_1) => __awaiter(void 0, [username_1, password_1, ...args_1], void 0, function* (username, password, legacy = false) {
106
+ configureAmplify();
107
+ yield auth.signOut(); // Ensure the user is signed out first
108
+ const { isSignedIn } = yield auth.signIn({ username, password });
109
+ assert_1.strict.ok(isSignedIn, "Sign-in failed");
110
+ const { tokens } = yield auth.fetchAuthSession();
111
+ assert_1.strict.ok(tokens, "No tokens found");
112
+ if (legacy) {
113
+ assert_1.strict.ok(tokens.accessToken, "No access token found");
114
+ return tokens.accessToken.toString();
115
+ }
116
+ assert_1.strict.ok(tokens.idToken, "No ID token found");
117
+ return tokens.idToken.toString();
118
+ });
119
+ /**
120
+ * Retrieves the current session, refreshing tokens if necessary.
121
+ * Requires a prior successful signIn() call.
122
+ * @param {boolean} [forceRefresh=false] - Force token refresh even if valid
123
+ * @param {boolean} [legacy=false] - If true, returns accessToken for legacy API
124
+ * @returns {Promise<string>} - The JWT token (idToken or accessToken)
125
+ * @throws {Error} - If no session exists (user needs to sign in)
126
+ */
127
+ const getSession = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (forceRefresh = false, legacy = false) {
128
+ configureAmplify();
129
+ const { tokens } = yield auth.fetchAuthSession({ forceRefresh });
130
+ assert_1.strict.ok(tokens, "No session found - please sign in first");
131
+ if (legacy) {
132
+ assert_1.strict.ok(tokens.accessToken, "No access token found");
133
+ return tokens.accessToken.toString();
134
+ }
135
+ assert_1.strict.ok(tokens.idToken, "No ID token found");
136
+ return tokens.idToken.toString();
137
+ });
138
+ return { signIn, getSession };
139
+ };
140
+ exports.createAuthService = createAuthService;
141
+ // Create the default auth service using amplifyAuth
142
+ const { signIn, getSession } = createAuthService(amplifyAuth);
143
+ exports.signIn = signIn;
144
+ exports.getSession = getSession;
145
+ const deviceInfo = (baseURL) =>
146
+ /**
147
+ * Retrieves information about a device by its MAC address.
148
+ * Automatically decompresses any gzip-compressed Buffer fields in the response.
149
+ *
150
+ * @param {string} jwtToken - The JWT token for authentication.
151
+ * @param {string} macAddress - The MAC address of the device.
152
+ * @returns {Promise<DeviceInfoType>} - A promise that resolves to the device info.
153
+ */
154
+ (jwtToken, macAddress) => __awaiter(void 0, void 0, void 0, function* () {
155
+ const data = yield fetchJson(baseURL, `device/${macAddress}/info`, {
156
+ method: "GET",
157
+ headers: headers(jwtToken),
158
+ });
159
+ // Process response to decompress any gzipped Buffer fields
160
+ return (0, buffer_utils_1.processResponse)(data);
161
+ });
162
+ const mqttCommand = (baseURL) =>
163
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
164
+ (jwtToken, macAddress, payload) => fetchJson(baseURL, "mqtt/command", {
165
+ method: "PUT",
166
+ headers: Object.assign({ "Content-Type": "application/json" }, headers(jwtToken)),
167
+ body: JSON.stringify(Object.assign({ mac_address: macAddress }, payload)),
168
+ });
169
+ const setPower = (baseURL) =>
170
+ /**
171
+ * Sends a command to set the power state of a device.
172
+ *
173
+ * @param {string} jwtToken - The JWT token for authentication.
174
+ * @param {string} macAddress - The MAC address of the device.
175
+ * @param {number} value - The desired power state (1 for ON, 0 for OFF).
176
+ * @returns {Promise<string>} - A promise that resolves to the command response.
177
+ */
178
+ (jwtToken, macAddress, value) => mqttCommand(baseURL)(jwtToken, macAddress, { name: "power", value });
179
+ const setPowerOn = (baseURL) =>
180
+ /**
181
+ * Turns a device ON by setting its power state.
182
+ *
183
+ * @param {string} jwtToken - The JWT token for authentication.
184
+ * @param {string} macAddress - The MAC address of the device.
185
+ * @returns {Promise<string>} - A promise that resolves to the command response.
186
+ *
187
+ * @example
188
+ * const response = await api.setPowerOn(jwtToken, macAddress);
189
+ * console.log(response);
190
+ */
191
+ (jwtToken, macAddress) => setPower(baseURL)(jwtToken, macAddress, 1);
192
+ const setPowerOff = (baseURL) =>
193
+ /**
194
+ * Turns a device OFF by setting its power state.
195
+ *
196
+ * @param {string} jwtToken - The JWT token for authentication.
197
+ * @param {string} macAddress - The MAC address of the device.
198
+ * @returns {Promise<string>} - A promise that resolves to the command response.
199
+ *
200
+ * @example
201
+ * const response = await api.setPowerOff(jwtToken, macAddress);
202
+ * console.log(response);
203
+ */
204
+ (jwtToken, macAddress) => setPower(baseURL)(jwtToken, macAddress, 0);
205
+ const getPower = (baseURL) =>
206
+ /**
207
+ * Retrieves the power status of the device.
208
+ *
209
+ * @param {string} jwtToken - The JWT token for authentication.
210
+ * @param {string} macAddress - The MAC address of the device.
211
+ * @returns {Promise<boolean>} - A promise that resolves to the power status.
212
+ */
213
+ (jwtToken, macAddress) => __awaiter(void 0, void 0, void 0, function* () {
214
+ const info = yield deviceInfo(baseURL)(jwtToken, macAddress);
215
+ return info.status.commands.power;
216
+ });
217
+ const getEnvironmentTemperature = (baseURL) =>
218
+ /**
219
+ * Retrieves the environment temperature from the device's sensors.
220
+ *
221
+ * @param {string} jwtToken - The JWT token for authentication.
222
+ * @param {string} macAddress - The MAC address of the device.
223
+ * @returns {Promise<number>} - A promise that resolves to the temperature value.
224
+ */
225
+ (jwtToken, macAddress) => __awaiter(void 0, void 0, void 0, function* () {
226
+ const info = yield deviceInfo(baseURL)(jwtToken, macAddress);
227
+ return info.status.temperatures.enviroment;
228
+ });
229
+ const getTargetTemperature = (baseURL) =>
230
+ /**
231
+ * Retrieves the target temperature value set on the device.
232
+ *
233
+ * @param {string} jwtToken - The JWT token for authentication.
234
+ * @param {string} macAddress - The MAC address of the device.
235
+ * @returns {Promise<number>} - A promise that resolves to the target temperature (degree celsius).
236
+ */
237
+ (jwtToken, macAddress) => __awaiter(void 0, void 0, void 0, function* () {
238
+ const info = yield deviceInfo(baseURL)(jwtToken, macAddress);
239
+ return info.nvm.user_parameters.enviroment_1_temperature;
240
+ });
241
+ const setTargetTemperature = (baseURL) =>
242
+ /**
243
+ * Sends a command to set the target temperature (degree celsius) of a device.
244
+ *
245
+ * @param {string} jwtToken - The JWT token for authentication.
246
+ * @param {string} macAddress - The MAC address of the device.
247
+ * @param {number} temperature - The desired target temperature (degree celsius).
248
+ * @returns {Promise<string>} - A promise that resolves to the command response.
249
+ */
250
+ (jwtToken, macAddress, temperature) => mqttCommand(baseURL)(jwtToken, macAddress, {
251
+ name: "enviroment_1_temperature",
252
+ value: temperature,
253
+ });
254
+ const registerDevice = (baseURL) =>
255
+ /**
256
+ * Registers a device with the user's account.
257
+ * This must be called before other device operations will work on the new API.
258
+ *
259
+ * @param {string} jwtToken - The JWT token for authentication.
260
+ * @param {string} macAddress - The MAC address of the device (colons optional).
261
+ * @param {string} serialNumber - The device serial number.
262
+ * @param {string} deviceName - User-friendly name for the device (default: empty string).
263
+ * @param {string} deviceRoom - Room name for the device (default: empty string).
264
+ * @returns {Promise<DeviceAssociationResponse>} - A promise that resolves to the registration response.
265
+ */
266
+ (jwtToken_1, macAddress_1, serialNumber_1, ...args_1) => __awaiter(void 0, [jwtToken_1, macAddress_1, serialNumber_1, ...args_1], void 0, function* (jwtToken, macAddress, serialNumber, deviceName = "", deviceRoom = "") {
267
+ const body = {
268
+ macAddress: macAddress.replace(/:/g, ""),
269
+ deviceName,
270
+ deviceRoom,
271
+ serialNumber,
272
+ };
273
+ return fetchJson(baseURL, "device", {
274
+ method: "POST",
275
+ headers: Object.assign({ "Content-Type": "application/json" }, headers(jwtToken)),
276
+ body: JSON.stringify(body),
277
+ });
278
+ });
279
+ const editDevice = (baseURL) =>
280
+ /**
281
+ * Updates a device's name and room.
282
+ *
283
+ * @param {string} jwtToken - The JWT token for authentication.
284
+ * @param {string} macAddress - The MAC address of the device (colons optional).
285
+ * @param {string} deviceName - New name for the device (default: empty string).
286
+ * @param {string} deviceRoom - New room for the device (default: empty string).
287
+ * @returns {Promise<DeviceAssociationResponse>} - A promise that resolves to the update response.
288
+ */
289
+ (jwtToken_1, macAddress_1, ...args_1) => __awaiter(void 0, [jwtToken_1, macAddress_1, ...args_1], void 0, function* (jwtToken, macAddress, deviceName = "", deviceRoom = "") {
290
+ const normalizedMac = macAddress.replace(/:/g, "");
291
+ const body = {
292
+ deviceName,
293
+ deviceRoom,
294
+ };
295
+ return fetchJson(baseURL, `device/${normalizedMac}`, {
296
+ method: "PUT",
297
+ headers: Object.assign({ "Content-Type": "application/json" }, headers(jwtToken)),
298
+ body: JSON.stringify(body),
299
+ });
300
+ });
301
+ /**
302
+ * Configures the library for API interactions.
303
+ * Initializes API methods with a specified base URL.
304
+ *
305
+ * @param {string} [baseURL=API_URL] - The base URL for the API.
306
+ * @returns {object} - An object containing methods for interacting with the API.
307
+ *
308
+ * @example
309
+ * const api = configure();
310
+ * const power = await api.getPower(jwtToken, macAddress);
311
+ */
312
+ const configure = (baseURL = constants_1.API_URL) => ({
313
+ deviceInfo: deviceInfo(baseURL),
314
+ registerDevice: registerDevice(baseURL),
315
+ editDevice: editDevice(baseURL),
316
+ setPower: setPower(baseURL),
317
+ setPowerOff: setPowerOff(baseURL),
318
+ setPowerOn: setPowerOn(baseURL),
319
+ getPower: getPower(baseURL),
320
+ getEnvironmentTemperature: getEnvironmentTemperature(baseURL),
321
+ getTargetTemperature: getTargetTemperature(baseURL),
322
+ setTargetTemperature: setTargetTemperature(baseURL),
323
+ });
324
+ exports.configure = configure;