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.
- package/.github/workflows/publish.yml +3 -2
- package/.github/workflows/tests.yml +8 -1
- package/README.md +1 -0
- package/dist/esm/cli.js +82 -15
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +2 -2
- package/dist/esm/library.d.ts +32 -3
- package/dist/esm/library.js +158 -20
- package/dist/esm/library.test.js +207 -38
- package/eslint.config.mjs +35 -0
- package/package.json +25 -5
- package/src/cli.ts +143 -16
- package/src/index.ts +11 -4
- package/src/library.test.ts +238 -38
- package/src/library.ts +176 -22
package/dist/esm/library.test.js
CHANGED
|
@@ -8,69 +8,238 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { strict as assert } from "assert";
|
|
11
|
-
import sinon from "sinon";
|
|
12
11
|
import axios from "axios";
|
|
13
|
-
import
|
|
12
|
+
import sinon from "sinon";
|
|
13
|
+
import { configure, createAuthService } from "../src/library";
|
|
14
|
+
import { API_URL } from "./constants";
|
|
14
15
|
describe("library", () => {
|
|
15
16
|
let axiosStub;
|
|
17
|
+
const expectedToken = "mockJwtToken";
|
|
16
18
|
beforeEach(() => {
|
|
17
19
|
axiosStub = sinon.stub(axios, "create").returns({
|
|
18
20
|
get: sinon.stub(),
|
|
19
21
|
put: sinon.stub(),
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
23
|
});
|
|
21
24
|
});
|
|
22
25
|
afterEach(() => {
|
|
23
26
|
sinon.restore();
|
|
24
27
|
});
|
|
28
|
+
describe("signIn", () => {
|
|
29
|
+
it("should sign in and return the JWT token", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
30
|
+
const expectedUsername = "testuser";
|
|
31
|
+
const expectedPassword = "testpassword";
|
|
32
|
+
const signIn = sinon.stub().resolves({ isSignedIn: true });
|
|
33
|
+
const signOut = sinon.stub();
|
|
34
|
+
const fetchAuthSession = sinon.stub().resolves({
|
|
35
|
+
tokens: {
|
|
36
|
+
accessToken: { toString: () => expectedToken },
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
const authStub = {
|
|
40
|
+
signIn,
|
|
41
|
+
signOut,
|
|
42
|
+
fetchAuthSession,
|
|
43
|
+
};
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
+
const authService = createAuthService(authStub);
|
|
46
|
+
const token = yield authService.signIn(expectedUsername, expectedPassword);
|
|
47
|
+
assert.deepEqual(authStub.signOut.args, [[]]);
|
|
48
|
+
assert.deepEqual(signIn.args, [
|
|
49
|
+
[{ username: expectedUsername, password: expectedPassword }],
|
|
50
|
+
]);
|
|
51
|
+
assert.equal(token, expectedToken);
|
|
52
|
+
}));
|
|
53
|
+
it("should throw an error if sign-in fails", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
54
|
+
const expectedUsername = "testuser";
|
|
55
|
+
const expectedPassword = "testpassword";
|
|
56
|
+
const signIn = sinon.stub().resolves({ isSignedIn: false });
|
|
57
|
+
const signOut = sinon.stub();
|
|
58
|
+
const fetchAuthSession = sinon.stub().resolves({
|
|
59
|
+
tokens: {
|
|
60
|
+
accessToken: { toString: () => expectedToken },
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
const authStub = {
|
|
64
|
+
signIn,
|
|
65
|
+
signOut,
|
|
66
|
+
fetchAuthSession,
|
|
67
|
+
};
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
69
|
+
const authService = createAuthService(authStub);
|
|
70
|
+
yield assert.rejects(() => __awaiter(void 0, void 0, void 0, function* () { return authService.signIn(expectedUsername, expectedPassword); }), {
|
|
71
|
+
name: "AssertionError",
|
|
72
|
+
message: "Sign-in failed",
|
|
73
|
+
});
|
|
74
|
+
}));
|
|
75
|
+
});
|
|
25
76
|
describe("configure", () => {
|
|
77
|
+
const expectedApi = [
|
|
78
|
+
"deviceInfo",
|
|
79
|
+
"setPower",
|
|
80
|
+
"setPowerOff",
|
|
81
|
+
"setPowerOn",
|
|
82
|
+
"getPower",
|
|
83
|
+
"getEnvironmentTemperature",
|
|
84
|
+
"getTargetTemperature",
|
|
85
|
+
"setTargetTemperature",
|
|
86
|
+
];
|
|
26
87
|
it("should create API methods with the correct baseURL", () => {
|
|
27
88
|
const baseURL = "https://example.com/api";
|
|
28
89
|
const api = configure(baseURL);
|
|
29
|
-
assert.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
90
|
+
assert.deepEqual(axiosStub.args, [
|
|
91
|
+
[
|
|
92
|
+
{
|
|
93
|
+
baseURL,
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
]);
|
|
97
|
+
assert.deepEqual(Object.keys(api), expectedApi);
|
|
98
|
+
});
|
|
99
|
+
it("should create API methods with the default baseURL", () => {
|
|
100
|
+
const api = configure();
|
|
101
|
+
assert.deepEqual(axiosStub.args, [
|
|
102
|
+
[
|
|
103
|
+
{
|
|
104
|
+
baseURL: API_URL,
|
|
105
|
+
},
|
|
106
|
+
],
|
|
36
107
|
]);
|
|
108
|
+
assert.deepEqual(Object.keys(api), expectedApi);
|
|
37
109
|
});
|
|
38
110
|
});
|
|
39
111
|
describe("API Methods", () => {
|
|
112
|
+
const mockDeviceInfo = {
|
|
113
|
+
status: {
|
|
114
|
+
commands: {
|
|
115
|
+
power: true,
|
|
116
|
+
},
|
|
117
|
+
temperatures: {
|
|
118
|
+
enviroment: 19,
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
nvm: {
|
|
122
|
+
user_parameters: {
|
|
123
|
+
enviroment_1_temperature: 22,
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
};
|
|
40
127
|
it("should call axios for deviceInfo", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
41
128
|
const mockAxios = {
|
|
42
|
-
get: sinon
|
|
43
|
-
.stub()
|
|
44
|
-
.resolves({ data: { id: "123", name: "Mock Device" } }),
|
|
129
|
+
get: sinon.stub().resolves({ data: mockDeviceInfo }),
|
|
45
130
|
};
|
|
46
131
|
axiosStub.returns(mockAxios);
|
|
47
132
|
const api = configure("https://example.com/api");
|
|
48
|
-
const result = yield api.deviceInfo(
|
|
49
|
-
assert.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
it("should call axios for setPowerOn", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
57
|
-
const mockAxios = {
|
|
58
|
-
put: sinon.stub().resolves({ status: 200 }),
|
|
59
|
-
};
|
|
60
|
-
axiosStub.returns(mockAxios);
|
|
61
|
-
const api = configure("https://example.com/api");
|
|
62
|
-
const result = yield api.setPowerOn("mockToken", "mockMacAddress");
|
|
63
|
-
assert.ok(mockAxios.put.calledOnce);
|
|
64
|
-
assert.equal(mockAxios.put.firstCall.args[0], "mqtt/command");
|
|
65
|
-
assert.deepEqual(mockAxios.put.firstCall.args[1], {
|
|
66
|
-
mac_address: "mockMacAddress",
|
|
67
|
-
name: "power",
|
|
68
|
-
value: 1,
|
|
69
|
-
});
|
|
70
|
-
assert.deepEqual(mockAxios.put.firstCall.args[2], {
|
|
71
|
-
headers: { Authorization: "Bearer mockToken" },
|
|
72
|
-
});
|
|
73
|
-
assert.equal(result.status, 200);
|
|
133
|
+
const result = yield api.deviceInfo(expectedToken, "mockMacAddress");
|
|
134
|
+
assert.deepEqual(mockAxios.get.args, [
|
|
135
|
+
[
|
|
136
|
+
"device/mockMacAddress/info",
|
|
137
|
+
{ headers: { Authorization: `Bearer ${expectedToken}` } },
|
|
138
|
+
],
|
|
139
|
+
]);
|
|
140
|
+
assert.deepEqual(result, mockDeviceInfo);
|
|
74
141
|
}));
|
|
142
|
+
// Tests for setPowerOn and setPowerOff
|
|
143
|
+
[
|
|
144
|
+
{
|
|
145
|
+
method: "setPowerOn",
|
|
146
|
+
call: (api) => api.setPowerOn("mockToken", "mockMacAddress"),
|
|
147
|
+
expectedValue: 1,
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
method: "setPowerOff",
|
|
151
|
+
call: (api) => api.setPowerOff("mockToken", "mockMacAddress"),
|
|
152
|
+
expectedValue: 0,
|
|
153
|
+
},
|
|
154
|
+
].forEach(({ method, call, expectedValue }) => {
|
|
155
|
+
it(`should call axios for ${method}`, () => __awaiter(void 0, void 0, void 0, function* () {
|
|
156
|
+
const mockAxios = {
|
|
157
|
+
put: sinon.stub().resolves({ status: 200 }),
|
|
158
|
+
};
|
|
159
|
+
axiosStub.returns(mockAxios);
|
|
160
|
+
const api = configure("https://example.com/api");
|
|
161
|
+
// Invoke the method using the mapped call function
|
|
162
|
+
const result = yield call(api);
|
|
163
|
+
assert.deepEqual(mockAxios.put.args, [
|
|
164
|
+
[
|
|
165
|
+
"mqtt/command",
|
|
166
|
+
{
|
|
167
|
+
mac_address: "mockMacAddress",
|
|
168
|
+
name: "power",
|
|
169
|
+
value: expectedValue,
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
headers: { Authorization: "Bearer mockToken" },
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
]);
|
|
176
|
+
assert.equal(result.status, 200);
|
|
177
|
+
}));
|
|
178
|
+
});
|
|
179
|
+
const getterTests = [
|
|
180
|
+
{
|
|
181
|
+
method: "getPower",
|
|
182
|
+
call: (api, token, mac) => api.getPower(token, mac),
|
|
183
|
+
expectedResult: true,
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
method: "getEnvironmentTemperature",
|
|
187
|
+
call: (api, token, mac) => api.getEnvironmentTemperature(token, mac),
|
|
188
|
+
expectedResult: 19,
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
method: "getTargetTemperature",
|
|
192
|
+
call: (api, token, mac) => api.getTargetTemperature(token, mac),
|
|
193
|
+
expectedResult: 22,
|
|
194
|
+
},
|
|
195
|
+
];
|
|
196
|
+
getterTests.forEach(({ method, call, expectedResult }) => {
|
|
197
|
+
it(`should call axios and return the correct value for ${method}`, () => __awaiter(void 0, void 0, void 0, function* () {
|
|
198
|
+
const mockAxios = {
|
|
199
|
+
get: sinon.stub().resolves({ data: mockDeviceInfo }),
|
|
200
|
+
};
|
|
201
|
+
axiosStub.returns(mockAxios);
|
|
202
|
+
const api = configure("https://example.com/api");
|
|
203
|
+
const result = yield call(api, expectedToken, "mockMacAddress");
|
|
204
|
+
assert.deepEqual(mockAxios.get.args, [
|
|
205
|
+
[
|
|
206
|
+
"device/mockMacAddress/info",
|
|
207
|
+
{ headers: { Authorization: `Bearer ${expectedToken}` } },
|
|
208
|
+
],
|
|
209
|
+
]);
|
|
210
|
+
assert.equal(result, expectedResult);
|
|
211
|
+
}));
|
|
212
|
+
});
|
|
213
|
+
// Setter tests
|
|
214
|
+
const setterTests = [
|
|
215
|
+
{
|
|
216
|
+
method: "setTargetTemperature",
|
|
217
|
+
call: (api, token, mac, value) => api.setTargetTemperature(token, mac, value),
|
|
218
|
+
payload: {
|
|
219
|
+
name: "enviroment_1_temperature",
|
|
220
|
+
value: 20,
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
];
|
|
224
|
+
setterTests.forEach(({ method, call, payload }) => {
|
|
225
|
+
it(`should call axios and send the correct payload for ${method}`, () => __awaiter(void 0, void 0, void 0, function* () {
|
|
226
|
+
const mockAxios = {
|
|
227
|
+
put: sinon.stub().resolves({ status: 200 }),
|
|
228
|
+
};
|
|
229
|
+
axiosStub.returns(mockAxios);
|
|
230
|
+
const api = configure("https://example.com/api");
|
|
231
|
+
const result = yield call(api, expectedToken, "mockMacAddress", payload.value);
|
|
232
|
+
assert.deepEqual(mockAxios.put.args, [
|
|
233
|
+
[
|
|
234
|
+
"mqtt/command",
|
|
235
|
+
Object.assign({ mac_address: "mockMacAddress" }, payload),
|
|
236
|
+
{
|
|
237
|
+
headers: { Authorization: `Bearer ${expectedToken}` },
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
]);
|
|
241
|
+
assert.equal(result.status, 200);
|
|
242
|
+
}));
|
|
243
|
+
});
|
|
75
244
|
});
|
|
76
245
|
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import typescriptEslint from "@typescript-eslint/eslint-plugin";
|
|
2
|
+
import simpleImportSort from "eslint-plugin-simple-import-sort";
|
|
3
|
+
import globals from "globals";
|
|
4
|
+
import tsParser from "@typescript-eslint/parser";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import js from "@eslint/js";
|
|
8
|
+
import { FlatCompat } from "@eslint/eslintrc";
|
|
9
|
+
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = path.dirname(__filename);
|
|
12
|
+
|
|
13
|
+
const compat = new FlatCompat({
|
|
14
|
+
baseDirectory: __dirname,
|
|
15
|
+
recommendedConfig: js.configs.recommended,
|
|
16
|
+
allConfig: js.configs.all,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export default [
|
|
20
|
+
...compat.extends(
|
|
21
|
+
"eslint:recommended",
|
|
22
|
+
"plugin:@typescript-eslint/recommended"
|
|
23
|
+
),
|
|
24
|
+
{
|
|
25
|
+
plugins: {
|
|
26
|
+
"@typescript-eslint": typescriptEslint,
|
|
27
|
+
"simple-import-sort": simpleImportSort,
|
|
28
|
+
},
|
|
29
|
+
rules: {
|
|
30
|
+
// Sorting imports and exports
|
|
31
|
+
"simple-import-sort/imports": "error",
|
|
32
|
+
"simple-import-sort/exports": "error",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "edilkamin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -8,10 +8,14 @@
|
|
|
8
8
|
"scripts": {
|
|
9
9
|
"cli": "ts-node src/cli.ts",
|
|
10
10
|
"cli:debug": "node --inspect --require ts-node/register/transpile-only src/cli.ts",
|
|
11
|
-
"test": "mocha --require ts-node/register src/*.test.ts",
|
|
12
|
-
"test:debug": "mocha --require ts-node/register/transpile-only --inspect src/*.test.ts",
|
|
13
|
-
"lint": "prettier --check src docs .github *.md *.
|
|
14
|
-
"format": "prettier --write src docs .github *.md *.
|
|
11
|
+
"test": "nyc mocha --require ts-node/register src/*.test.ts",
|
|
12
|
+
"test:debug": "nyc mocha --require ts-node/register/transpile-only --inspect src/*.test.ts",
|
|
13
|
+
"lint:prettier": "prettier --check src docs .github *.json *.md *.mjs",
|
|
14
|
+
"format:prettier": "prettier --write src docs .github *.json *.md *.mjs",
|
|
15
|
+
"lint:eslint": "eslint src",
|
|
16
|
+
"format:eslint": "eslint --fix src",
|
|
17
|
+
"lint": "yarn lint:prettier && yarn lint:eslint",
|
|
18
|
+
"format": "yarn format:prettier && yarn format:eslint",
|
|
15
19
|
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
16
20
|
"build:esm": "tsc -p tsconfig.esm.json",
|
|
17
21
|
"build": "npm run build:cjs && npm run build:esm"
|
|
@@ -29,15 +33,31 @@
|
|
|
29
33
|
"bin": {
|
|
30
34
|
"edilkamin": "dist/cjs/cli.js"
|
|
31
35
|
},
|
|
36
|
+
"nyc": {
|
|
37
|
+
"reporter": [
|
|
38
|
+
"html",
|
|
39
|
+
"lcov",
|
|
40
|
+
"text"
|
|
41
|
+
]
|
|
42
|
+
},
|
|
32
43
|
"dependencies": {
|
|
33
44
|
"aws-amplify": "^6.10.0",
|
|
34
45
|
"axios": "^0.26.0"
|
|
35
46
|
},
|
|
36
47
|
"devDependencies": {
|
|
37
48
|
"@aws-amplify/cli": "^7.6.21",
|
|
49
|
+
"@eslint/eslintrc": "^3.2.0",
|
|
50
|
+
"@eslint/js": "^9.16.0",
|
|
38
51
|
"@types/mocha": "^10.0.10",
|
|
39
52
|
"@types/sinon": "^17.0.3",
|
|
53
|
+
"@typescript-eslint/eslint-plugin": "^8.17.0",
|
|
54
|
+
"@typescript-eslint/parser": "^8.17.0",
|
|
55
|
+
"eslint": "^9.16.0",
|
|
56
|
+
"eslint-config-prettier": "^9.1.0",
|
|
57
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
58
|
+
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
40
59
|
"mocha": "^10.8.2",
|
|
60
|
+
"nyc": "^17.1.0",
|
|
41
61
|
"prettier": "^2.5.1",
|
|
42
62
|
"sinon": "^19.0.2",
|
|
43
63
|
"ts-node": "^10.9.1",
|
package/src/cli.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { signIn, configure } from "./library";
|
|
3
2
|
import { Command } from "commander";
|
|
4
3
|
import readline from "readline";
|
|
4
|
+
|
|
5
5
|
import { version } from "../package.json";
|
|
6
|
+
import { configure, signIn } from "./library";
|
|
6
7
|
|
|
7
8
|
const promptPassword = (): Promise<string> => {
|
|
8
9
|
const rl = readline.createInterface({
|
|
@@ -31,11 +32,78 @@ const promptPassword = (): Promise<string> => {
|
|
|
31
32
|
* @param command The command to which options should be added.
|
|
32
33
|
* @returns The command with options added.
|
|
33
34
|
*/
|
|
34
|
-
const
|
|
35
|
+
const addAuthOptions = (command: Command): Command =>
|
|
35
36
|
command
|
|
36
37
|
.requiredOption("-u, --username <username>", "Username")
|
|
37
38
|
.option("-p, --password <password>", "Password");
|
|
38
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Adds MAC address option to a command.
|
|
42
|
+
* @param command The command to which the MAC address option should be added.
|
|
43
|
+
* @returns The command with the MAC address option added.
|
|
44
|
+
*/
|
|
45
|
+
const addMacOption = (command: Command): Command =>
|
|
46
|
+
command.requiredOption("-m, --mac <macAddress>", "MAC address of the device");
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Handles common authentication and API initialization logic.
|
|
50
|
+
* @param options The options passed from the CLI command.
|
|
51
|
+
* @returns An object containing the normalized MAC, JWT token, and configured API instance.
|
|
52
|
+
*/
|
|
53
|
+
const initializeCommand = async (options: {
|
|
54
|
+
username: string;
|
|
55
|
+
password?: string;
|
|
56
|
+
mac: string;
|
|
57
|
+
}): Promise<{
|
|
58
|
+
normalizedMac: string;
|
|
59
|
+
jwtToken: string;
|
|
60
|
+
api: ReturnType<typeof configure>;
|
|
61
|
+
}> => {
|
|
62
|
+
const { username, password, mac } = options;
|
|
63
|
+
const normalizedMac = mac.replace(/:/g, "");
|
|
64
|
+
const pwd = password || (await promptPassword());
|
|
65
|
+
const jwtToken = await signIn(username, pwd);
|
|
66
|
+
const api = configure();
|
|
67
|
+
return { normalizedMac, jwtToken, api };
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Executes a getter command by handling common steps (authentication, API initialization).
|
|
72
|
+
* @param options The options passed from the CLI command.
|
|
73
|
+
* @param getter A function to call on the configured API object.
|
|
74
|
+
*/
|
|
75
|
+
const executeGetter = async (
|
|
76
|
+
options: { username: string; password?: string; mac: string },
|
|
77
|
+
getter: (
|
|
78
|
+
api: ReturnType<typeof configure>,
|
|
79
|
+
jwtToken: string,
|
|
80
|
+
mac: string
|
|
81
|
+
) => Promise<unknown>
|
|
82
|
+
): Promise<void> => {
|
|
83
|
+
const { normalizedMac, jwtToken, api } = await initializeCommand(options);
|
|
84
|
+
const result = await getter(api, jwtToken, normalizedMac);
|
|
85
|
+
console.log(result);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Executes a setter command by handling common steps (authentication, API initialization).
|
|
90
|
+
* @param options The options passed from the CLI command.
|
|
91
|
+
* @param setter A function to call on the configured API object.
|
|
92
|
+
*/
|
|
93
|
+
const executeSetter = async (
|
|
94
|
+
options: { username: string; password?: string; mac: string; value: number },
|
|
95
|
+
setter: (
|
|
96
|
+
api: ReturnType<typeof configure>,
|
|
97
|
+
jwtToken: string,
|
|
98
|
+
mac: string,
|
|
99
|
+
value: number
|
|
100
|
+
) => Promise<unknown>
|
|
101
|
+
): Promise<void> => {
|
|
102
|
+
const { normalizedMac, jwtToken, api } = await initializeCommand(options);
|
|
103
|
+
const result = await setter(api, jwtToken, normalizedMac, options.value);
|
|
104
|
+
console.log(result);
|
|
105
|
+
};
|
|
106
|
+
|
|
39
107
|
const createProgram = (): Command => {
|
|
40
108
|
const program = new Command();
|
|
41
109
|
program
|
|
@@ -43,7 +111,7 @@ const createProgram = (): Command => {
|
|
|
43
111
|
.description("CLI tool for interacting with the Edilkamin API")
|
|
44
112
|
.version(version);
|
|
45
113
|
// Command: signIn
|
|
46
|
-
|
|
114
|
+
addAuthOptions(
|
|
47
115
|
program.command("signIn").description("Sign in and retrieve a JWT token")
|
|
48
116
|
).action(async (options) => {
|
|
49
117
|
const { username, password } = options;
|
|
@@ -51,20 +119,79 @@ const createProgram = (): Command => {
|
|
|
51
119
|
const jwtToken = await signIn(username, pwd);
|
|
52
120
|
console.log("JWT Token:", jwtToken);
|
|
53
121
|
});
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
122
|
+
// Generic getter commands
|
|
123
|
+
[
|
|
124
|
+
{
|
|
125
|
+
commandName: "deviceInfo",
|
|
126
|
+
description: "Retrieve device info for a specific MAC address",
|
|
127
|
+
getter: (
|
|
128
|
+
api: ReturnType<typeof configure>,
|
|
129
|
+
jwtToken: string,
|
|
130
|
+
mac: string
|
|
131
|
+
) => api.deviceInfo(jwtToken, mac),
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
commandName: "getPower",
|
|
135
|
+
description: "Retrieve device power status",
|
|
136
|
+
getter: (
|
|
137
|
+
api: ReturnType<typeof configure>,
|
|
138
|
+
jwtToken: string,
|
|
139
|
+
mac: string
|
|
140
|
+
) => api.getPower(jwtToken, mac),
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
commandName: "getEnvironmentTemperature",
|
|
144
|
+
description: "Retrieve environment temperature",
|
|
145
|
+
getter: (
|
|
146
|
+
api: ReturnType<typeof configure>,
|
|
147
|
+
jwtToken: string,
|
|
148
|
+
mac: string
|
|
149
|
+
) => api.getEnvironmentTemperature(jwtToken, mac),
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
commandName: "getTargetTemperature",
|
|
153
|
+
description: "Retrieve target temperature",
|
|
154
|
+
getter: (
|
|
155
|
+
api: ReturnType<typeof configure>,
|
|
156
|
+
jwtToken: string,
|
|
157
|
+
mac: string
|
|
158
|
+
) => api.getTargetTemperature(jwtToken, mac),
|
|
159
|
+
},
|
|
160
|
+
].forEach(({ commandName, description, getter }) => {
|
|
161
|
+
addMacOption(
|
|
162
|
+
addAuthOptions(program.command(commandName).description(description))
|
|
163
|
+
).action((options) => executeGetter(options, getter));
|
|
67
164
|
});
|
|
165
|
+
// Generic setter commands
|
|
166
|
+
[
|
|
167
|
+
{
|
|
168
|
+
commandName: "setPower",
|
|
169
|
+
description: "Set the power state of the device (1 for ON, 0 for OFF)",
|
|
170
|
+
setter: (
|
|
171
|
+
api: ReturnType<typeof configure>,
|
|
172
|
+
jwtToken: string,
|
|
173
|
+
mac: string,
|
|
174
|
+
value: number
|
|
175
|
+
) => api.setPower(jwtToken, mac, value),
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
commandName: "setTargetTemperature",
|
|
179
|
+
description: "Set the target temperature (degree celsius) for a device",
|
|
180
|
+
setter: (
|
|
181
|
+
api: ReturnType<typeof configure>,
|
|
182
|
+
jwtToken: string,
|
|
183
|
+
mac: string,
|
|
184
|
+
value: number
|
|
185
|
+
) => api.setTargetTemperature(jwtToken, mac, value),
|
|
186
|
+
},
|
|
187
|
+
].forEach(({ commandName, description, setter }) => {
|
|
188
|
+
addMacOption(
|
|
189
|
+
addAuthOptions(
|
|
190
|
+
program.command(commandName).description(description)
|
|
191
|
+
).requiredOption("-v, --value <number>", "Value to set", parseFloat)
|
|
192
|
+
).action((options) => executeSetter(options, setter));
|
|
193
|
+
});
|
|
194
|
+
|
|
68
195
|
return program;
|
|
69
196
|
};
|
|
70
197
|
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { configure } from "./library";
|
|
2
2
|
|
|
3
3
|
export { API_URL } from "./constants";
|
|
4
|
-
|
|
4
|
+
export { configure, signIn } from "./library";
|
|
5
5
|
export {
|
|
6
6
|
CommandsType,
|
|
7
7
|
DeviceInfoType,
|
|
@@ -10,6 +10,13 @@ export {
|
|
|
10
10
|
UserParametersType,
|
|
11
11
|
} from "./types";
|
|
12
12
|
|
|
13
|
-
export {
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
export const {
|
|
14
|
+
deviceInfo,
|
|
15
|
+
setPower,
|
|
16
|
+
setPowerOff,
|
|
17
|
+
setPowerOn,
|
|
18
|
+
getPower,
|
|
19
|
+
getEnvironmentTemperature,
|
|
20
|
+
getTargetTemperature,
|
|
21
|
+
setTargetTemperature,
|
|
22
|
+
} = configure();
|