edilkamin 1.4.0 → 1.5.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.
@@ -2,8 +2,7 @@ name: Publish
2
2
 
3
3
  on:
4
4
  push:
5
- tags:
6
- - "*"
5
+ pull_request:
7
6
 
8
7
  jobs:
9
8
  build:
@@ -17,6 +16,8 @@ jobs:
17
16
  registry-url: "https://registry.npmjs.org"
18
17
  - run: yarn install
19
18
  - run: yarn build
19
+ - run: npm publish --dry-run
20
20
  - run: npm publish
21
+ if: startsWith(github.ref, 'refs/tags/')
21
22
  env:
22
23
  NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
@@ -19,4 +19,11 @@ jobs:
19
19
  - run: yarn install
20
20
  - run: yarn lint
21
21
  - run: yarn build
22
- - run: npm publish --dry-run
22
+ - run: yarn test
23
+ - uses: codecov/codecov-action@v5
24
+ with:
25
+ files: ./coverage/lcov.info
26
+ token: ${{ secrets.CODECOV_TOKEN }}
27
+ fail_ci_if_error: true
28
+ env:
29
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
package/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![Tests](https://github.com/AndreMiras/edilkamin.js/workflows/Tests/badge.svg)](https://github.com/AndreMiras/edilkamin.js/actions/workflows/tests.yml)
4
4
  [![CLI Tests](https://github.com/AndreMiras/edilkamin.js/actions/workflows/cli-tests.yml/badge.svg)](https://github.com/AndreMiras/edilkamin.js/actions/workflows/cli-tests.yml)
5
+ [![codecov](https://codecov.io/gh/AndreMiras/edilkamin.js/graph/badge.svg?token=YG3LKXNZWU)](https://app.codecov.io/gh/AndreMiras/edilkamin.js/tree/main)
5
6
  [![Documentation](https://github.com/AndreMiras/edilkamin.js/workflows/Documentation/badge.svg)](https://github.com/AndreMiras/edilkamin.js/actions/workflows/documentation.yml)
6
7
  [![npm version](https://badge.fury.io/js/edilkamin.svg)](https://badge.fury.io/js/edilkamin)
7
8
 
package/dist/esm/cli.js CHANGED
@@ -8,10 +8,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- import { signIn, configure } from "./library";
12
11
  import { Command } from "commander";
13
12
  import readline from "readline";
14
13
  import { version } from "../package.json";
14
+ import { configure, signIn } from "./library";
15
15
  const promptPassword = () => {
16
16
  const rl = readline.createInterface({
17
17
  input: process.stdin,
@@ -39,9 +39,48 @@ const promptPassword = () => {
39
39
  * @param command The command to which options should be added.
40
40
  * @returns The command with options added.
41
41
  */
42
- const addCommonOptions = (command) => command
42
+ const addAuthOptions = (command) => command
43
43
  .requiredOption("-u, --username <username>", "Username")
44
44
  .option("-p, --password <password>", "Password");
45
+ /**
46
+ * Adds MAC address option to a command.
47
+ * @param command The command to which the MAC address option should be added.
48
+ * @returns The command with the MAC address option added.
49
+ */
50
+ const addMacOption = (command) => command.requiredOption("-m, --mac <macAddress>", "MAC address of the device");
51
+ /**
52
+ * Handles common authentication and API initialization logic.
53
+ * @param options The options passed from the CLI command.
54
+ * @returns An object containing the normalized MAC, JWT token, and configured API instance.
55
+ */
56
+ const initializeCommand = (options) => __awaiter(void 0, void 0, void 0, function* () {
57
+ const { username, password, mac } = options;
58
+ const normalizedMac = mac.replace(/:/g, "");
59
+ const pwd = password || (yield promptPassword());
60
+ const jwtToken = yield signIn(username, pwd);
61
+ const api = configure();
62
+ return { normalizedMac, jwtToken, api };
63
+ });
64
+ /**
65
+ * Executes a getter command by handling common steps (authentication, API initialization).
66
+ * @param options The options passed from the CLI command.
67
+ * @param getter A function to call on the configured API object.
68
+ */
69
+ const executeGetter = (options, getter) => __awaiter(void 0, void 0, void 0, function* () {
70
+ const { normalizedMac, jwtToken, api } = yield initializeCommand(options);
71
+ const result = yield getter(api, jwtToken, normalizedMac);
72
+ console.log(result);
73
+ });
74
+ /**
75
+ * Executes a setter command by handling common steps (authentication, API initialization).
76
+ * @param options The options passed from the CLI command.
77
+ * @param setter A function to call on the configured API object.
78
+ */
79
+ const executeSetter = (options, setter) => __awaiter(void 0, void 0, void 0, function* () {
80
+ const { normalizedMac, jwtToken, api } = yield initializeCommand(options);
81
+ const result = yield setter(api, jwtToken, normalizedMac, options.value);
82
+ console.log(result);
83
+ });
45
84
  const createProgram = () => {
46
85
  const program = new Command();
47
86
  program
@@ -49,24 +88,52 @@ const createProgram = () => {
49
88
  .description("CLI tool for interacting with the Edilkamin API")
50
89
  .version(version);
51
90
  // Command: signIn
52
- addCommonOptions(program.command("signIn").description("Sign in and retrieve a JWT token")).action((options) => __awaiter(void 0, void 0, void 0, function* () {
91
+ addAuthOptions(program.command("signIn").description("Sign in and retrieve a JWT token")).action((options) => __awaiter(void 0, void 0, void 0, function* () {
53
92
  const { username, password } = options;
54
93
  const pwd = password || (yield promptPassword());
55
94
  const jwtToken = yield signIn(username, pwd);
56
95
  console.log("JWT Token:", jwtToken);
57
96
  }));
58
- // Command: deviceInfo
59
- addCommonOptions(program
60
- .command("deviceInfo")
61
- .description("Retrieve device info for a specific MAC address")
62
- .requiredOption("-m, --mac <macAddress>", "MAC address of the device")).action((options) => __awaiter(void 0, void 0, void 0, function* () {
63
- const { username, password, mac } = options;
64
- const pwd = password || (yield promptPassword());
65
- const jwtToken = yield signIn(username, pwd);
66
- const api = configure(); // Use the default API configuration
67
- const deviceInfo = yield api.deviceInfo(jwtToken, mac);
68
- console.log("Device Info:", deviceInfo.data);
69
- }));
97
+ // Generic getter commands
98
+ [
99
+ {
100
+ commandName: "deviceInfo",
101
+ description: "Retrieve device info for a specific MAC address",
102
+ getter: (api, jwtToken, mac) => api.deviceInfo(jwtToken, mac),
103
+ },
104
+ {
105
+ commandName: "getPower",
106
+ description: "Retrieve device power status",
107
+ getter: (api, jwtToken, mac) => api.getPower(jwtToken, mac),
108
+ },
109
+ {
110
+ commandName: "getEnvironmentTemperature",
111
+ description: "Retrieve environment temperature",
112
+ getter: (api, jwtToken, mac) => api.getEnvironmentTemperature(jwtToken, mac),
113
+ },
114
+ {
115
+ commandName: "getTargetTemperature",
116
+ description: "Retrieve target temperature",
117
+ getter: (api, jwtToken, mac) => api.getTargetTemperature(jwtToken, mac),
118
+ },
119
+ ].forEach(({ commandName, description, getter }) => {
120
+ addMacOption(addAuthOptions(program.command(commandName).description(description))).action((options) => executeGetter(options, getter));
121
+ });
122
+ // Generic setter commands
123
+ [
124
+ {
125
+ commandName: "setPower",
126
+ description: "Set the power state of the device (1 for ON, 0 for OFF)",
127
+ setter: (api, jwtToken, mac, value) => api.setPower(jwtToken, mac, value),
128
+ },
129
+ {
130
+ commandName: "setTargetTemperature",
131
+ description: "Set the target temperature (degree celsius) for a device",
132
+ setter: (api, jwtToken, mac, value) => api.setTargetTemperature(jwtToken, mac, value),
133
+ },
134
+ ].forEach(({ commandName, description, setter }) => {
135
+ addMacOption(addAuthOptions(program.command(commandName).description(description)).requiredOption("-v, --value <number>", "Value to set", parseFloat)).action((options) => executeSetter(options, setter));
136
+ });
70
137
  return program;
71
138
  };
72
139
  const main = () => {
@@ -1,4 +1,4 @@
1
1
  export { API_URL } from "./constants";
2
+ export { configure, signIn } from "./library";
2
3
  export { CommandsType, DeviceInfoType, StatusType, TemperaturesType, UserParametersType, } from "./types";
3
- export { signIn, configure } from "./library";
4
- export declare const deviceInfo: (jwtToken: string, macAddress: string) => Promise<import("axios").AxiosResponse<import("./types").DeviceInfoType, any>>, setPower: (jwtToken: string, macAddress: string, value: number) => Promise<import("axios").AxiosResponse<any, any>>, setPowerOff: (jwtToken: string, macAddress: string) => Promise<import("axios").AxiosResponse<any, any>>, setPowerOn: (jwtToken: string, macAddress: string) => Promise<import("axios").AxiosResponse<any, any>>;
4
+ export declare const deviceInfo: (jwtToken: string, macAddress: string) => Promise<import("./types").DeviceInfoType>, setPower: (jwtToken: string, macAddress: string, value: number) => Promise<import("axios").AxiosResponse<any, any>>, setPowerOff: (jwtToken: string, macAddress: string) => Promise<import("axios").AxiosResponse<any, any>>, setPowerOn: (jwtToken: string, macAddress: string) => Promise<import("axios").AxiosResponse<any, any>>, getPower: (jwtToken: string, macAddress: string) => Promise<boolean>, getEnvironmentTemperature: (jwtToken: string, macAddress: string) => Promise<number>, getTargetTemperature: (jwtToken: string, macAddress: string) => Promise<number>, setTargetTemperature: (jwtToken: string, macAddress: string, temperature: number) => Promise<import("axios").AxiosResponse<any, any>>;
package/dist/esm/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  import { configure } from "./library";
2
2
  export { API_URL } from "./constants";
3
- export { signIn, configure } from "./library";
4
- export const { deviceInfo, setPower, setPowerOff, setPowerOn } = configure();
3
+ export { configure, signIn } from "./library";
4
+ export const { deviceInfo, setPower, setPowerOff, setPowerOn, getPower, getEnvironmentTemperature, getTargetTemperature, setTargetTemperature, } = configure();
@@ -1,12 +1,41 @@
1
+ import * as amplifyAuth from "aws-amplify/auth";
1
2
  import { DeviceInfoType } from "./types";
2
3
  /**
3
- * Sign in to return the JWT token.
4
+ * Generates headers with a JWT token for authenticated requests.
5
+ * @param {string} jwtToken - The JWT token for authorization.
6
+ * @returns {object} - The headers object with the Authorization field.
4
7
  */
8
+ declare const headers: (jwtToken: string) => {
9
+ Authorization: string;
10
+ };
11
+ /**
12
+ * Creates an authentication service with sign-in functionality.
13
+ * @param {typeof amplifyAuth} auth - The authentication module to use.
14
+ * @returns {object} - An object containing authentication-related methods.
15
+ */
16
+ declare const createAuthService: (auth: typeof amplifyAuth) => {
17
+ signIn: (username: string, password: string) => Promise<string>;
18
+ };
5
19
  declare const signIn: (username: string, password: string) => Promise<string>;
20
+ /**
21
+ * Configures the library for API interactions.
22
+ * Initializes API methods with a specified base URL.
23
+ *
24
+ * @param {string} [baseURL=API_URL] - The base URL for the API.
25
+ * @returns {object} - An object containing methods for interacting with the API.
26
+ *
27
+ * @example
28
+ * const api = configure();
29
+ * const power = await api.getPower(jwtToken, macAddress);
30
+ */
6
31
  declare const configure: (baseURL?: string) => {
7
- deviceInfo: (jwtToken: string, macAddress: string) => Promise<import("axios").AxiosResponse<DeviceInfoType, any>>;
32
+ deviceInfo: (jwtToken: string, macAddress: string) => Promise<DeviceInfoType>;
8
33
  setPower: (jwtToken: string, macAddress: string, value: number) => Promise<import("axios").AxiosResponse<any, any>>;
9
34
  setPowerOff: (jwtToken: string, macAddress: string) => Promise<import("axios").AxiosResponse<any, any>>;
10
35
  setPowerOn: (jwtToken: string, macAddress: string) => Promise<import("axios").AxiosResponse<any, any>>;
36
+ getPower: (jwtToken: string, macAddress: string) => Promise<boolean>;
37
+ getEnvironmentTemperature: (jwtToken: string, macAddress: string) => Promise<number>;
38
+ getTargetTemperature: (jwtToken: string, macAddress: string) => Promise<number>;
39
+ setTargetTemperature: (jwtToken: string, macAddress: string, temperature: number) => Promise<import("axios").AxiosResponse<any, any>>;
11
40
  };
12
- export { signIn, configure };
41
+ export { configure, createAuthService, headers, signIn };
@@ -17,42 +17,180 @@ const amplifyconfiguration = {
17
17
  aws_user_pools_id: "eu-central-1_BYmQ2VBlo",
18
18
  aws_user_pools_web_client_id: "7sc1qltkqobo3ddqsk4542dg2h",
19
19
  };
20
- Amplify.configure(amplifyconfiguration);
20
+ /**
21
+ * Generates headers with a JWT token for authenticated requests.
22
+ * @param {string} jwtToken - The JWT token for authorization.
23
+ * @returns {object} - The headers object with the Authorization field.
24
+ */
21
25
  const headers = (jwtToken) => ({ Authorization: `Bearer ${jwtToken}` });
22
26
  /**
23
- * Sign in to return the JWT token.
27
+ * Configures Amplify if not already configured.
28
+ * Ensures the configuration is only applied once.
29
+ */
30
+ const configureAmplify = () => {
31
+ const currentConfig = Amplify.getConfig();
32
+ if (Object.keys(currentConfig).length !== 0)
33
+ return;
34
+ Amplify.configure(amplifyconfiguration);
35
+ };
36
+ /**
37
+ * Creates an authentication service with sign-in functionality.
38
+ * @param {typeof amplifyAuth} auth - The authentication module to use.
39
+ * @returns {object} - An object containing authentication-related methods.
40
+ */
41
+ const createAuthService = (auth) => {
42
+ /**
43
+ * Signs in a user with the provided credentials.
44
+ * @param {string} username - The username of the user.
45
+ * @param {string} password - The password of the user.
46
+ * @returns {Promise<string>} - The JWT token of the signed-in user.
47
+ * @throws {Error} - If sign-in fails or no tokens are retrieved.
48
+ */
49
+ const signIn = (username, password) => __awaiter(void 0, void 0, void 0, function* () {
50
+ configureAmplify();
51
+ yield auth.signOut(); // Ensure the user is signed out first
52
+ const { isSignedIn } = yield auth.signIn({ username, password });
53
+ assert.ok(isSignedIn, "Sign-in failed");
54
+ const { tokens } = yield auth.fetchAuthSession();
55
+ assert.ok(tokens, "No tokens found");
56
+ return tokens.accessToken.toString();
57
+ });
58
+ return { signIn };
59
+ };
60
+ // Create the default auth service using amplifyAuth
61
+ const { signIn } = createAuthService(amplifyAuth);
62
+ const deviceInfo = (axiosInstance) =>
63
+ /**
64
+ * Retrieves information about a device by its MAC address.
65
+ *
66
+ * @param {string} jwtToken - The JWT token for authentication.
67
+ * @param {string} macAddress - The MAC address of the device.
68
+ * @returns {Promise<DeviceInfoType>} - A promise that resolves to the device info.
24
69
  */
25
- const signIn = (username, password) => __awaiter(void 0, void 0, void 0, function* () {
26
- // in case the user is already signed in, refs:
27
- // https://github.com/aws-amplify/amplify-js/issues/13813
28
- yield amplifyAuth.signOut();
29
- const { isSignedIn } = yield amplifyAuth.signIn({
30
- username,
31
- password,
70
+ (jwtToken, macAddress) => __awaiter(void 0, void 0, void 0, function* () {
71
+ const response = yield axiosInstance.get(`device/${macAddress}/info`, {
72
+ headers: headers(jwtToken),
32
73
  });
33
- assert.ok(isSignedIn);
34
- const { tokens } = yield amplifyAuth.fetchAuthSession();
35
- assert.ok(tokens);
36
- return tokens.accessToken.toString();
74
+ return response.data;
75
+ });
76
+ const mqttCommand = (axiosInstance) =>
77
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
78
+ (jwtToken, macAddress, payload) => axiosInstance.put("mqtt/command", Object.assign({ mac_address: macAddress }, payload), { headers: headers(jwtToken) });
79
+ const setPower = (axiosInstance) =>
80
+ /**
81
+ * Sends a command to set the power state of a device.
82
+ *
83
+ * @param {string} jwtToken - The JWT token for authentication.
84
+ * @param {string} macAddress - The MAC address of the device.
85
+ * @param {number} value - The desired power state (1 for ON, 0 for OFF).
86
+ * @returns {Promise<string>} - A promise that resolves to the command response.
87
+ */
88
+ (jwtToken, macAddress, value) => mqttCommand(axiosInstance)(jwtToken, macAddress, { name: "power", value });
89
+ const setPowerOn = (axiosInstance) =>
90
+ /**
91
+ * Turns a device ON by setting its power state.
92
+ *
93
+ * @param {string} jwtToken - The JWT token for authentication.
94
+ * @param {string} macAddress - The MAC address of the device.
95
+ * @returns {Promise<string>} - A promise that resolves to the command response.
96
+ *
97
+ * @example
98
+ * const response = await api.setPowerOn(jwtToken, macAddress);
99
+ * console.log(response);
100
+ */
101
+ (jwtToken, macAddress) => setPower(axiosInstance)(jwtToken, macAddress, 1);
102
+ const setPowerOff = (axiosInstance) =>
103
+ /**
104
+ * Turns a device OFF by setting its power state.
105
+ *
106
+ * @param {string} jwtToken - The JWT token for authentication.
107
+ * @param {string} macAddress - The MAC address of the device.
108
+ * @returns {Promise<string>} - A promise that resolves to the command response.
109
+ *
110
+ * @example
111
+ * const response = await api.setPowerOff(jwtToken, macAddress);
112
+ * console.log(response);
113
+ */
114
+ (jwtToken, macAddress) => setPower(axiosInstance)(jwtToken, macAddress, 0);
115
+ const getPower = (axiosInstance) =>
116
+ /**
117
+ * Retrieves the power status of the device.
118
+ *
119
+ * @param {string} jwtToken - The JWT token for authentication.
120
+ * @param {string} macAddress - The MAC address of the device.
121
+ * @returns {Promise<boolean>} - A promise that resolves to the power status.
122
+ */
123
+ (jwtToken, macAddress) => __awaiter(void 0, void 0, void 0, function* () {
124
+ const info = yield deviceInfo(axiosInstance)(jwtToken, macAddress);
125
+ return info.status.commands.power;
126
+ });
127
+ const getEnvironmentTemperature = (axiosInstance) =>
128
+ /**
129
+ * Retrieves the environment temperature from the device's sensors.
130
+ *
131
+ * @param {string} jwtToken - The JWT token for authentication.
132
+ * @param {string} macAddress - The MAC address of the device.
133
+ * @returns {Promise<number>} - A promise that resolves to the temperature value.
134
+ */
135
+ (jwtToken, macAddress) => __awaiter(void 0, void 0, void 0, function* () {
136
+ const info = yield deviceInfo(axiosInstance)(jwtToken, macAddress);
137
+ return info.status.temperatures.enviroment;
37
138
  });
38
- const deviceInfo = (axiosInstance) => (jwtToken, macAddress) => axiosInstance.get(`device/${macAddress}/info`, {
39
- headers: headers(jwtToken),
139
+ const getTargetTemperature = (axiosInstance) =>
140
+ /**
141
+ * Retrieves the target temperature value set on the device.
142
+ *
143
+ * @param {string} jwtToken - The JWT token for authentication.
144
+ * @param {string} macAddress - The MAC address of the device.
145
+ * @returns {Promise<number>} - A promise that resolves to the target temperature (degree celsius).
146
+ */
147
+ (jwtToken, macAddress) => __awaiter(void 0, void 0, void 0, function* () {
148
+ const info = yield deviceInfo(axiosInstance)(jwtToken, macAddress);
149
+ return info.nvm.user_parameters.enviroment_1_temperature;
40
150
  });
41
- const mqttCommand = (axiosInstance) => (jwtToken, macAddress, payload) => axiosInstance.put("mqtt/command", Object.assign({ mac_address: macAddress }, payload), { headers: headers(jwtToken) });
42
- const setPower = (axiosInstance) => (jwtToken, macAddress, value) => mqttCommand(axiosInstance)(jwtToken, macAddress, { name: "power", value });
43
- const setPowerOn = (axiosInstance) => (jwtToken, macAddress) => setPower(axiosInstance)(jwtToken, macAddress, 1);
44
- const setPowerOff = (axiosInstance) => (jwtToken, macAddress) => setPower(axiosInstance)(jwtToken, macAddress, 0);
151
+ const setTargetTemperature = (axiosInstance) =>
152
+ /**
153
+ * Sends a command to set the target temperature (degree celsius) of a device.
154
+ *
155
+ * @param {string} jwtToken - The JWT token for authentication.
156
+ * @param {string} macAddress - The MAC address of the device.
157
+ * @param {number} temperature - The desired target temperature (degree celsius).
158
+ * @returns {Promise<string>} - A promise that resolves to the command response.
159
+ */
160
+ (jwtToken, macAddress, temperature) => mqttCommand(axiosInstance)(jwtToken, macAddress, {
161
+ name: "enviroment_1_temperature",
162
+ value: temperature,
163
+ });
164
+ /**
165
+ * Configures the library for API interactions.
166
+ * Initializes API methods with a specified base URL.
167
+ *
168
+ * @param {string} [baseURL=API_URL] - The base URL for the API.
169
+ * @returns {object} - An object containing methods for interacting with the API.
170
+ *
171
+ * @example
172
+ * const api = configure();
173
+ * const power = await api.getPower(jwtToken, macAddress);
174
+ */
45
175
  const configure = (baseURL = API_URL) => {
46
176
  const axiosInstance = axios.create({ baseURL });
47
177
  const deviceInfoInstance = deviceInfo(axiosInstance);
48
178
  const setPowerInstance = setPower(axiosInstance);
49
179
  const setPowerOffInstance = setPowerOff(axiosInstance);
50
180
  const setPowerOnInstance = setPowerOn(axiosInstance);
181
+ const getPowerInstance = getPower(axiosInstance);
182
+ const getEnvironmentTemperatureInstance = getEnvironmentTemperature(axiosInstance);
183
+ const getTargetTemperatureInstance = getTargetTemperature(axiosInstance);
184
+ const setTargetTemperatureInstance = setTargetTemperature(axiosInstance);
51
185
  return {
52
186
  deviceInfo: deviceInfoInstance,
53
187
  setPower: setPowerInstance,
54
188
  setPowerOff: setPowerOffInstance,
55
189
  setPowerOn: setPowerOnInstance,
190
+ getPower: getPowerInstance,
191
+ getEnvironmentTemperature: getEnvironmentTemperatureInstance,
192
+ getTargetTemperature: getTargetTemperatureInstance,
193
+ setTargetTemperature: setTargetTemperatureInstance,
56
194
  };
57
195
  };
58
- export { signIn, configure };
196
+ export { configure, createAuthService, headers, signIn };