edilkamin 1.7.2 → 1.7.4
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/cli-tests.yml +6 -0
- package/.github/workflows/publish.yml +1 -1
- package/README.md +1 -1
- package/dist/cjs/package.json +84 -0
- package/dist/cjs/src/browser-bundle.test.js +64 -0
- package/dist/cjs/src/buffer-utils.js +78 -0
- package/dist/cjs/src/buffer-utils.test.js +186 -0
- package/dist/cjs/src/cli.js +253 -0
- package/dist/cjs/src/configureAmplify.test.js +42 -0
- package/dist/cjs/src/constants.js +9 -0
- package/dist/{esm → cjs/src}/index.d.ts +1 -2
- package/dist/cjs/src/index.js +22 -0
- package/dist/{esm → cjs/src}/library.d.ts +4 -4
- package/dist/cjs/src/library.js +324 -0
- package/dist/cjs/src/library.test.js +547 -0
- package/dist/cjs/src/serial-utils.js +50 -0
- package/dist/cjs/src/serial-utils.test.d.ts +1 -0
- package/dist/cjs/src/serial-utils.test.js +50 -0
- package/dist/cjs/src/token-storage.js +119 -0
- package/dist/cjs/src/types.js +2 -0
- package/dist/esm/package.json +84 -0
- package/dist/esm/src/browser-bundle.test.d.ts +1 -0
- package/dist/esm/src/browser-bundle.test.js +29 -0
- package/dist/esm/src/buffer-utils.d.ts +25 -0
- package/dist/esm/src/buffer-utils.test.d.ts +1 -0
- package/dist/esm/src/cli.d.ts +3 -0
- package/dist/esm/src/configureAmplify.test.d.ts +1 -0
- package/dist/esm/src/configureAmplify.test.js +37 -0
- package/dist/esm/src/constants.d.ts +4 -0
- package/dist/esm/src/index.d.ts +6 -0
- package/dist/esm/{index.js → src/index.js} +0 -1
- package/dist/esm/src/library.d.ts +55 -0
- package/dist/esm/{library.js → src/library.js} +59 -51
- package/dist/esm/src/library.test.d.ts +1 -0
- package/dist/esm/{library.test.js → src/library.test.js} +167 -190
- package/dist/esm/src/serial-utils.d.ts +33 -0
- package/dist/esm/src/serial-utils.test.d.ts +1 -0
- package/dist/esm/src/token-storage.d.ts +14 -0
- package/dist/esm/src/types.d.ts +73 -0
- package/dist/esm/src/types.js +1 -0
- package/package.json +19 -7
- package/src/browser-bundle.test.ts +21 -0
- package/src/configureAmplify.test.ts +47 -0
- package/src/index.ts +0 -1
- package/src/library.test.ts +195 -197
- package/src/library.ts +76 -62
- package/tsconfig.cjs.json +2 -2
- package/tsconfig.json +2 -3
- /package/dist/{esm/buffer-utils.test.d.ts → cjs/src/browser-bundle.test.d.ts} +0 -0
- /package/dist/{esm → cjs/src}/buffer-utils.d.ts +0 -0
- /package/dist/{esm/library.test.d.ts → cjs/src/buffer-utils.test.d.ts} +0 -0
- /package/dist/{esm → cjs/src}/cli.d.ts +0 -0
- /package/dist/{esm/serial-utils.test.d.ts → cjs/src/configureAmplify.test.d.ts} +0 -0
- /package/dist/{esm → cjs/src}/constants.d.ts +0 -0
- /package/dist/{esm/types.js → cjs/src/library.test.d.ts} +0 -0
- /package/dist/{esm → cjs/src}/serial-utils.d.ts +0 -0
- /package/dist/{esm → cjs/src}/token-storage.d.ts +0 -0
- /package/dist/{esm → cjs/src}/types.d.ts +0 -0
- /package/dist/esm/{buffer-utils.js → src/buffer-utils.js} +0 -0
- /package/dist/esm/{buffer-utils.test.js → src/buffer-utils.test.js} +0 -0
- /package/dist/esm/{cli.js → src/cli.js} +0 -0
- /package/dist/esm/{constants.js → src/constants.js} +0 -0
- /package/dist/esm/{serial-utils.js → src/serial-utils.js} +0 -0
- /package/dist/esm/{serial-utils.test.js → src/serial-utils.test.js} +0 -0
- /package/dist/esm/{token-storage.js → src/token-storage.js} +0 -0
|
@@ -0,0 +1,119 @@
|
|
|
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.clearSession = exports.createFileStorage = void 0;
|
|
46
|
+
const fs_1 = require("fs");
|
|
47
|
+
const os = __importStar(require("os"));
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
const TOKEN_DIR = path.join(os.homedir(), ".edilkamin");
|
|
50
|
+
const TOKEN_FILE = path.join(TOKEN_DIR, "session.json");
|
|
51
|
+
/**
|
|
52
|
+
* Custom storage adapter for AWS Amplify that persists to file system.
|
|
53
|
+
* Used for CLI to maintain sessions between invocations.
|
|
54
|
+
*/
|
|
55
|
+
const createFileStorage = () => {
|
|
56
|
+
let cache = {};
|
|
57
|
+
let loaded = false;
|
|
58
|
+
const ensureDir = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
59
|
+
try {
|
|
60
|
+
yield fs_1.promises.mkdir(TOKEN_DIR, { recursive: true, mode: 0o700 });
|
|
61
|
+
}
|
|
62
|
+
catch (_a) {
|
|
63
|
+
// Directory may already exist
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
const load = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
67
|
+
if (loaded)
|
|
68
|
+
return;
|
|
69
|
+
try {
|
|
70
|
+
const data = yield fs_1.promises.readFile(TOKEN_FILE, "utf-8");
|
|
71
|
+
cache = JSON.parse(data);
|
|
72
|
+
}
|
|
73
|
+
catch (_a) {
|
|
74
|
+
cache = {};
|
|
75
|
+
}
|
|
76
|
+
loaded = true;
|
|
77
|
+
});
|
|
78
|
+
const save = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
79
|
+
yield ensureDir();
|
|
80
|
+
yield fs_1.promises.writeFile(TOKEN_FILE, JSON.stringify(cache), {
|
|
81
|
+
encoding: "utf-8",
|
|
82
|
+
mode: 0o600,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
return {
|
|
86
|
+
setItem: (key, value) => __awaiter(void 0, void 0, void 0, function* () {
|
|
87
|
+
yield load();
|
|
88
|
+
cache[key] = value;
|
|
89
|
+
yield save();
|
|
90
|
+
}),
|
|
91
|
+
getItem: (key) => __awaiter(void 0, void 0, void 0, function* () {
|
|
92
|
+
var _a;
|
|
93
|
+
yield load();
|
|
94
|
+
return (_a = cache[key]) !== null && _a !== void 0 ? _a : null;
|
|
95
|
+
}),
|
|
96
|
+
removeItem: (key) => __awaiter(void 0, void 0, void 0, function* () {
|
|
97
|
+
yield load();
|
|
98
|
+
delete cache[key];
|
|
99
|
+
yield save();
|
|
100
|
+
}),
|
|
101
|
+
clear: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
102
|
+
cache = {};
|
|
103
|
+
yield save();
|
|
104
|
+
}),
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
exports.createFileStorage = createFileStorage;
|
|
108
|
+
/**
|
|
109
|
+
* Clears all stored session data.
|
|
110
|
+
*/
|
|
111
|
+
const clearSession = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
112
|
+
try {
|
|
113
|
+
yield fs_1.promises.unlink(TOKEN_FILE);
|
|
114
|
+
}
|
|
115
|
+
catch (_a) {
|
|
116
|
+
// File may not exist
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
exports.clearSession = clearSession;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "edilkamin",
|
|
3
|
+
"version": "1.7.4",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "dist/cjs/src/index.js",
|
|
6
|
+
"module": "dist/esm/src/index.js",
|
|
7
|
+
"types": "dist/esm/src/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/esm/src/index.d.ts",
|
|
12
|
+
"default": "./dist/esm/src/index.js"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/cjs/src/index.d.ts",
|
|
16
|
+
"default": "./dist/cjs/src/index.js"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"cli": "ts-node src/cli.ts",
|
|
22
|
+
"cli:debug": "node --inspect --require ts-node/register/transpile-only src/cli.ts",
|
|
23
|
+
"test": "nyc mocha --require ts-node/register src/*.test.ts",
|
|
24
|
+
"test:debug": "nyc mocha --require ts-node/register/transpile-only --inspect src/*.test.ts",
|
|
25
|
+
"lint:prettier": "prettier --check src docs .github *.json *.md *.mjs",
|
|
26
|
+
"format:prettier": "prettier --write src docs .github *.json *.md *.mjs",
|
|
27
|
+
"lint:eslint": "eslint src",
|
|
28
|
+
"format:eslint": "eslint --fix src",
|
|
29
|
+
"lint": "yarn lint:prettier && yarn lint:eslint",
|
|
30
|
+
"format": "yarn format:prettier && yarn format:eslint",
|
|
31
|
+
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
32
|
+
"build:esm": "tsc -p tsconfig.esm.json",
|
|
33
|
+
"build": "npm run build:cjs && npm run build:esm"
|
|
34
|
+
},
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/AndreMiras/edilkamin.js.git"
|
|
38
|
+
},
|
|
39
|
+
"author": "Andre Miras",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/AndreMiras/edilkamin.js/issues"
|
|
43
|
+
},
|
|
44
|
+
"homepage": "https://github.com/AndreMiras/edilkamin.js#readme",
|
|
45
|
+
"bin": {
|
|
46
|
+
"edilkamin": "dist/cjs/src/cli.js"
|
|
47
|
+
},
|
|
48
|
+
"nyc": {
|
|
49
|
+
"reporter": [
|
|
50
|
+
"html",
|
|
51
|
+
"lcov",
|
|
52
|
+
"text"
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"aws-amplify": "^6.10.0",
|
|
57
|
+
"pako": "^2.1.0"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@eslint/eslintrc": "^3.2.0",
|
|
61
|
+
"@eslint/js": "^9.16.0",
|
|
62
|
+
"@types/mocha": "^10.0.10",
|
|
63
|
+
"@types/node": "^25.0.2",
|
|
64
|
+
"@types/pako": "^2.0.4",
|
|
65
|
+
"@types/sinon": "^17.0.3",
|
|
66
|
+
"@typescript-eslint/eslint-plugin": "^8.17.0",
|
|
67
|
+
"@typescript-eslint/parser": "^8.17.0",
|
|
68
|
+
"esbuild": "^0.27.1",
|
|
69
|
+
"eslint": "^9.16.0",
|
|
70
|
+
"eslint-config-prettier": "^10.1.8",
|
|
71
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
72
|
+
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
73
|
+
"mocha": "^11.7.5",
|
|
74
|
+
"nyc": "^17.1.0",
|
|
75
|
+
"prettier": "^3.7.4",
|
|
76
|
+
"sinon": "^19.0.2",
|
|
77
|
+
"ts-node": "^10.9.1",
|
|
78
|
+
"typedoc": "^0.28.15",
|
|
79
|
+
"typescript": "^5.7.2"
|
|
80
|
+
},
|
|
81
|
+
"optionalDependencies": {
|
|
82
|
+
"commander": "^12.1.0"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { strict as assert } from "assert";
|
|
11
|
+
import * as esbuild from "esbuild";
|
|
12
|
+
describe("browser-bundle", () => {
|
|
13
|
+
it("should bundle for browser without Node.js built-ins", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
14
|
+
// This test verifies that the library can be bundled for browser environments
|
|
15
|
+
// without requiring Node.js built-in modules (fs, os, path).
|
|
16
|
+
// If this test fails, it means Node.js-only code has leaked into the main exports.
|
|
17
|
+
const result = yield esbuild.build({
|
|
18
|
+
entryPoints: ["dist/esm/src/index.js"],
|
|
19
|
+
platform: "browser",
|
|
20
|
+
bundle: true,
|
|
21
|
+
write: false,
|
|
22
|
+
// External dependencies that are expected (real deps + assert which is used for validation)
|
|
23
|
+
external: ["aws-amplify", "aws-amplify/*", "pako", "assert"],
|
|
24
|
+
logLevel: "silent",
|
|
25
|
+
});
|
|
26
|
+
// If we get here without error, the bundle succeeded
|
|
27
|
+
assert.ok(result.outputFiles.length > 0, "Bundle should produce output");
|
|
28
|
+
}));
|
|
29
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { BufferEncodedType } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Type guard to check if a value is a serialized Node.js Buffer.
|
|
4
|
+
* Node.js Buffers serialize to JSON as: {type: "Buffer", data: [...]}
|
|
5
|
+
*
|
|
6
|
+
* @param value - The value to check
|
|
7
|
+
* @returns True if the value is a Buffer-encoded object
|
|
8
|
+
*/
|
|
9
|
+
declare const isBuffer: (value: unknown) => value is BufferEncodedType;
|
|
10
|
+
/**
|
|
11
|
+
* Decompresses a Buffer-encoded gzip object and parses the resulting JSON.
|
|
12
|
+
*
|
|
13
|
+
* @param bufferObj - A serialized Buffer object containing gzip data
|
|
14
|
+
* @returns The decompressed and parsed JSON data, or the original object on failure
|
|
15
|
+
*/
|
|
16
|
+
declare const decompressBuffer: (bufferObj: BufferEncodedType) => unknown;
|
|
17
|
+
/**
|
|
18
|
+
* Recursively processes an API response to decompress any Buffer-encoded fields.
|
|
19
|
+
* Handles nested objects and arrays, preserving structure while decompressing.
|
|
20
|
+
*
|
|
21
|
+
* @param data - The API response data to process
|
|
22
|
+
* @returns The processed data with all Buffer fields decompressed
|
|
23
|
+
*/
|
|
24
|
+
declare const processResponse: <T>(data: T) => T;
|
|
25
|
+
export { decompressBuffer, isBuffer, processResponse };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { strict as assert } from "assert";
|
|
2
|
+
import sinon from "sinon";
|
|
3
|
+
import { configureAmplify } from "../src/library";
|
|
4
|
+
/**
|
|
5
|
+
* This test file specifically tests the configureAmplify function with custom storage.
|
|
6
|
+
* It tests line 61 in library.ts:
|
|
7
|
+
* cognitoUserPoolsTokenProvider.setKeyValueStorage(storage)
|
|
8
|
+
*
|
|
9
|
+
* IMPORTANT: This file is named to run BEFORE library.test.ts (alphabetically)
|
|
10
|
+
* to ensure amplifyConfigured is still false when these tests run.
|
|
11
|
+
*/
|
|
12
|
+
describe("configureAmplify", () => {
|
|
13
|
+
it("should configure Amplify with custom storage", () => {
|
|
14
|
+
const mockStorage = {
|
|
15
|
+
setItem: sinon.stub().resolves(),
|
|
16
|
+
getItem: sinon.stub().resolves(null),
|
|
17
|
+
removeItem: sinon.stub().resolves(),
|
|
18
|
+
clear: sinon.stub().resolves(),
|
|
19
|
+
};
|
|
20
|
+
// Call configureAmplify with custom storage
|
|
21
|
+
// This is the first call in the test suite, so amplifyConfigured is false
|
|
22
|
+
// This should trigger line 61 in library.ts
|
|
23
|
+
configureAmplify(mockStorage);
|
|
24
|
+
// The test passes if no error is thrown
|
|
25
|
+
// Coverage confirms line 61 is executed
|
|
26
|
+
assert.ok(true, "configureAmplify with storage completed without error");
|
|
27
|
+
});
|
|
28
|
+
it("should only configure Amplify once (idempotent)", () => {
|
|
29
|
+
// Call configureAmplify multiple times without storage
|
|
30
|
+
configureAmplify();
|
|
31
|
+
configureAmplify();
|
|
32
|
+
configureAmplify();
|
|
33
|
+
// Should not throw or have any side effects
|
|
34
|
+
// The function returns early if already configured (line 58)
|
|
35
|
+
assert.ok(true, "Multiple calls to configureAmplify completed without error");
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
declare const OLD_API_URL = "https://fxtj7xkgc6.execute-api.eu-central-1.amazonaws.com/prod/";
|
|
2
|
+
declare const NEW_API_URL = "https://the-mind-api.edilkamin.com/";
|
|
3
|
+
declare const API_URL = "https://the-mind-api.edilkamin.com/";
|
|
4
|
+
export { API_URL, NEW_API_URL, OLD_API_URL };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { decompressBuffer, isBuffer, processResponse } from "./buffer-utils";
|
|
2
|
+
export { API_URL, NEW_API_URL, OLD_API_URL } from "./constants";
|
|
3
|
+
export { configure, getSession, signIn } from "./library";
|
|
4
|
+
export { serialNumberDisplay, serialNumberFromHex, serialNumberToHex, } from "./serial-utils";
|
|
5
|
+
export { BufferEncodedType, CommandsType, DeviceAssociationBody, DeviceAssociationResponse, DeviceInfoRawType, DeviceInfoType, EditDeviceAssociationBody, StatusType, TemperaturesType, UserParametersType, } from "./types";
|
|
6
|
+
export declare const deviceInfo: (jwtToken: string, macAddress: string) => Promise<import("./types").DeviceInfoType>, registerDevice: (jwtToken: string, macAddress: string, serialNumber: string, deviceName?: string, deviceRoom?: string) => Promise<import("./types").DeviceAssociationResponse>, editDevice: (jwtToken: string, macAddress: string, deviceName?: string, deviceRoom?: string) => Promise<import("./types").DeviceAssociationResponse>, setPower: (jwtToken: string, macAddress: string, value: number) => Promise<unknown>, setPowerOff: (jwtToken: string, macAddress: string) => Promise<unknown>, setPowerOn: (jwtToken: string, macAddress: string) => Promise<unknown>, 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<unknown>;
|
|
@@ -3,5 +3,4 @@ export { decompressBuffer, isBuffer, processResponse } from "./buffer-utils";
|
|
|
3
3
|
export { API_URL, NEW_API_URL, OLD_API_URL } from "./constants";
|
|
4
4
|
export { configure, getSession, signIn } from "./library";
|
|
5
5
|
export { serialNumberDisplay, serialNumberFromHex, serialNumberToHex, } from "./serial-utils";
|
|
6
|
-
export { clearSession } from "./token-storage";
|
|
7
6
|
export const { deviceInfo, registerDevice, editDevice, setPower, setPowerOff, setPowerOn, getPower, getEnvironmentTemperature, getTargetTemperature, setTargetTemperature, } = configure();
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as amplifyAuth from "aws-amplify/auth";
|
|
2
|
+
import { DeviceAssociationResponse, DeviceInfoType } from "./types";
|
|
3
|
+
/**
|
|
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.
|
|
7
|
+
*/
|
|
8
|
+
declare const headers: (jwtToken: string) => {
|
|
9
|
+
Authorization: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Configures Amplify if not already configured.
|
|
13
|
+
* Uses a local flag to avoid calling getConfig() which prints a warning.
|
|
14
|
+
* @param {object} [storage] - Optional custom storage adapter for token persistence
|
|
15
|
+
*/
|
|
16
|
+
declare const configureAmplify: (storage?: {
|
|
17
|
+
setItem: (key: string, value: string) => Promise<void>;
|
|
18
|
+
getItem: (key: string) => Promise<string | null>;
|
|
19
|
+
removeItem: (key: string) => Promise<void>;
|
|
20
|
+
clear: () => Promise<void>;
|
|
21
|
+
}) => void;
|
|
22
|
+
/**
|
|
23
|
+
* Creates an authentication service with sign-in functionality.
|
|
24
|
+
* @param {typeof amplifyAuth} auth - The authentication module to use.
|
|
25
|
+
* @returns {object} - An object containing authentication-related methods.
|
|
26
|
+
*/
|
|
27
|
+
declare const createAuthService: (auth: typeof amplifyAuth) => {
|
|
28
|
+
signIn: (username: string, password: string, legacy?: boolean) => Promise<string>;
|
|
29
|
+
getSession: (forceRefresh?: boolean, legacy?: boolean) => Promise<string>;
|
|
30
|
+
};
|
|
31
|
+
declare const signIn: (username: string, password: string, legacy?: boolean) => Promise<string>, getSession: (forceRefresh?: boolean, legacy?: boolean) => Promise<string>;
|
|
32
|
+
/**
|
|
33
|
+
* Configures the library for API interactions.
|
|
34
|
+
* Initializes API methods with a specified base URL.
|
|
35
|
+
*
|
|
36
|
+
* @param {string} [baseURL=API_URL] - The base URL for the API.
|
|
37
|
+
* @returns {object} - An object containing methods for interacting with the API.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* const api = configure();
|
|
41
|
+
* const power = await api.getPower(jwtToken, macAddress);
|
|
42
|
+
*/
|
|
43
|
+
declare const configure: (baseURL?: string) => {
|
|
44
|
+
deviceInfo: (jwtToken: string, macAddress: string) => Promise<DeviceInfoType>;
|
|
45
|
+
registerDevice: (jwtToken: string, macAddress: string, serialNumber: string, deviceName?: string, deviceRoom?: string) => Promise<DeviceAssociationResponse>;
|
|
46
|
+
editDevice: (jwtToken: string, macAddress: string, deviceName?: string, deviceRoom?: string) => Promise<DeviceAssociationResponse>;
|
|
47
|
+
setPower: (jwtToken: string, macAddress: string, value: number) => Promise<unknown>;
|
|
48
|
+
setPowerOff: (jwtToken: string, macAddress: string) => Promise<unknown>;
|
|
49
|
+
setPowerOn: (jwtToken: string, macAddress: string) => Promise<unknown>;
|
|
50
|
+
getPower: (jwtToken: string, macAddress: string) => Promise<boolean>;
|
|
51
|
+
getEnvironmentTemperature: (jwtToken: string, macAddress: string) => Promise<number>;
|
|
52
|
+
getTargetTemperature: (jwtToken: string, macAddress: string) => Promise<number>;
|
|
53
|
+
setTargetTemperature: (jwtToken: string, macAddress: string, temperature: number) => Promise<unknown>;
|
|
54
|
+
};
|
|
55
|
+
export { configure, configureAmplify, createAuthService, getSession, headers, signIn, };
|
|
@@ -11,9 +11,19 @@ import { strict as assert } from "assert";
|
|
|
11
11
|
import { Amplify } from "aws-amplify";
|
|
12
12
|
import * as amplifyAuth from "aws-amplify/auth";
|
|
13
13
|
import { cognitoUserPoolsTokenProvider } from "aws-amplify/auth/cognito";
|
|
14
|
-
import axios from "axios";
|
|
15
14
|
import { processResponse } from "./buffer-utils";
|
|
16
15
|
import { API_URL } from "./constants";
|
|
16
|
+
/**
|
|
17
|
+
* Makes a fetch request and returns parsed JSON response.
|
|
18
|
+
* Throws an error for non-2xx status codes.
|
|
19
|
+
*/
|
|
20
|
+
const fetchJson = (baseURL_1, path_1, ...args_1) => __awaiter(void 0, [baseURL_1, path_1, ...args_1], void 0, function* (baseURL, path, options = {}) {
|
|
21
|
+
const response = yield fetch(`${baseURL}${path}`, options);
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
24
|
+
}
|
|
25
|
+
return response.json();
|
|
26
|
+
});
|
|
17
27
|
const amplifyconfiguration = {
|
|
18
28
|
aws_project_region: "eu-central-1",
|
|
19
29
|
aws_user_pools_id: "eu-central-1_BYmQ2VBlo",
|
|
@@ -91,7 +101,7 @@ const createAuthService = (auth) => {
|
|
|
91
101
|
};
|
|
92
102
|
// Create the default auth service using amplifyAuth
|
|
93
103
|
const { signIn, getSession } = createAuthService(amplifyAuth);
|
|
94
|
-
const deviceInfo = (
|
|
104
|
+
const deviceInfo = (baseURL) =>
|
|
95
105
|
/**
|
|
96
106
|
* Retrieves information about a device by its MAC address.
|
|
97
107
|
* Automatically decompresses any gzip-compressed Buffer fields in the response.
|
|
@@ -101,16 +111,21 @@ const deviceInfo = (axiosInstance) =>
|
|
|
101
111
|
* @returns {Promise<DeviceInfoType>} - A promise that resolves to the device info.
|
|
102
112
|
*/
|
|
103
113
|
(jwtToken, macAddress) => __awaiter(void 0, void 0, void 0, function* () {
|
|
104
|
-
const
|
|
114
|
+
const data = yield fetchJson(baseURL, `device/${macAddress}/info`, {
|
|
115
|
+
method: "GET",
|
|
105
116
|
headers: headers(jwtToken),
|
|
106
117
|
});
|
|
107
118
|
// Process response to decompress any gzipped Buffer fields
|
|
108
|
-
return processResponse(
|
|
119
|
+
return processResponse(data);
|
|
109
120
|
});
|
|
110
|
-
const mqttCommand = (
|
|
121
|
+
const mqttCommand = (baseURL) =>
|
|
111
122
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
112
|
-
(jwtToken, macAddress, payload) =>
|
|
113
|
-
|
|
123
|
+
(jwtToken, macAddress, payload) => fetchJson(baseURL, "mqtt/command", {
|
|
124
|
+
method: "PUT",
|
|
125
|
+
headers: Object.assign({ "Content-Type": "application/json" }, headers(jwtToken)),
|
|
126
|
+
body: JSON.stringify(Object.assign({ mac_address: macAddress }, payload)),
|
|
127
|
+
});
|
|
128
|
+
const setPower = (baseURL) =>
|
|
114
129
|
/**
|
|
115
130
|
* Sends a command to set the power state of a device.
|
|
116
131
|
*
|
|
@@ -119,8 +134,8 @@ const setPower = (axiosInstance) =>
|
|
|
119
134
|
* @param {number} value - The desired power state (1 for ON, 0 for OFF).
|
|
120
135
|
* @returns {Promise<string>} - A promise that resolves to the command response.
|
|
121
136
|
*/
|
|
122
|
-
(jwtToken, macAddress, value) => mqttCommand(
|
|
123
|
-
const setPowerOn = (
|
|
137
|
+
(jwtToken, macAddress, value) => mqttCommand(baseURL)(jwtToken, macAddress, { name: "power", value });
|
|
138
|
+
const setPowerOn = (baseURL) =>
|
|
124
139
|
/**
|
|
125
140
|
* Turns a device ON by setting its power state.
|
|
126
141
|
*
|
|
@@ -132,8 +147,8 @@ const setPowerOn = (axiosInstance) =>
|
|
|
132
147
|
* const response = await api.setPowerOn(jwtToken, macAddress);
|
|
133
148
|
* console.log(response);
|
|
134
149
|
*/
|
|
135
|
-
(jwtToken, macAddress) => setPower(
|
|
136
|
-
const setPowerOff = (
|
|
150
|
+
(jwtToken, macAddress) => setPower(baseURL)(jwtToken, macAddress, 1);
|
|
151
|
+
const setPowerOff = (baseURL) =>
|
|
137
152
|
/**
|
|
138
153
|
* Turns a device OFF by setting its power state.
|
|
139
154
|
*
|
|
@@ -145,8 +160,8 @@ const setPowerOff = (axiosInstance) =>
|
|
|
145
160
|
* const response = await api.setPowerOff(jwtToken, macAddress);
|
|
146
161
|
* console.log(response);
|
|
147
162
|
*/
|
|
148
|
-
(jwtToken, macAddress) => setPower(
|
|
149
|
-
const getPower = (
|
|
163
|
+
(jwtToken, macAddress) => setPower(baseURL)(jwtToken, macAddress, 0);
|
|
164
|
+
const getPower = (baseURL) =>
|
|
150
165
|
/**
|
|
151
166
|
* Retrieves the power status of the device.
|
|
152
167
|
*
|
|
@@ -155,10 +170,10 @@ const getPower = (axiosInstance) =>
|
|
|
155
170
|
* @returns {Promise<boolean>} - A promise that resolves to the power status.
|
|
156
171
|
*/
|
|
157
172
|
(jwtToken, macAddress) => __awaiter(void 0, void 0, void 0, function* () {
|
|
158
|
-
const info = yield deviceInfo(
|
|
173
|
+
const info = yield deviceInfo(baseURL)(jwtToken, macAddress);
|
|
159
174
|
return info.status.commands.power;
|
|
160
175
|
});
|
|
161
|
-
const getEnvironmentTemperature = (
|
|
176
|
+
const getEnvironmentTemperature = (baseURL) =>
|
|
162
177
|
/**
|
|
163
178
|
* Retrieves the environment temperature from the device's sensors.
|
|
164
179
|
*
|
|
@@ -167,10 +182,10 @@ const getEnvironmentTemperature = (axiosInstance) =>
|
|
|
167
182
|
* @returns {Promise<number>} - A promise that resolves to the temperature value.
|
|
168
183
|
*/
|
|
169
184
|
(jwtToken, macAddress) => __awaiter(void 0, void 0, void 0, function* () {
|
|
170
|
-
const info = yield deviceInfo(
|
|
185
|
+
const info = yield deviceInfo(baseURL)(jwtToken, macAddress);
|
|
171
186
|
return info.status.temperatures.enviroment;
|
|
172
187
|
});
|
|
173
|
-
const getTargetTemperature = (
|
|
188
|
+
const getTargetTemperature = (baseURL) =>
|
|
174
189
|
/**
|
|
175
190
|
* Retrieves the target temperature value set on the device.
|
|
176
191
|
*
|
|
@@ -179,10 +194,10 @@ const getTargetTemperature = (axiosInstance) =>
|
|
|
179
194
|
* @returns {Promise<number>} - A promise that resolves to the target temperature (degree celsius).
|
|
180
195
|
*/
|
|
181
196
|
(jwtToken, macAddress) => __awaiter(void 0, void 0, void 0, function* () {
|
|
182
|
-
const info = yield deviceInfo(
|
|
197
|
+
const info = yield deviceInfo(baseURL)(jwtToken, macAddress);
|
|
183
198
|
return info.nvm.user_parameters.enviroment_1_temperature;
|
|
184
199
|
});
|
|
185
|
-
const setTargetTemperature = (
|
|
200
|
+
const setTargetTemperature = (baseURL) =>
|
|
186
201
|
/**
|
|
187
202
|
* Sends a command to set the target temperature (degree celsius) of a device.
|
|
188
203
|
*
|
|
@@ -191,11 +206,11 @@ const setTargetTemperature = (axiosInstance) =>
|
|
|
191
206
|
* @param {number} temperature - The desired target temperature (degree celsius).
|
|
192
207
|
* @returns {Promise<string>} - A promise that resolves to the command response.
|
|
193
208
|
*/
|
|
194
|
-
(jwtToken, macAddress, temperature) => mqttCommand(
|
|
209
|
+
(jwtToken, macAddress, temperature) => mqttCommand(baseURL)(jwtToken, macAddress, {
|
|
195
210
|
name: "enviroment_1_temperature",
|
|
196
211
|
value: temperature,
|
|
197
212
|
});
|
|
198
|
-
const registerDevice = (
|
|
213
|
+
const registerDevice = (baseURL) =>
|
|
199
214
|
/**
|
|
200
215
|
* Registers a device with the user's account.
|
|
201
216
|
* This must be called before other device operations will work on the new API.
|
|
@@ -214,10 +229,13 @@ const registerDevice = (axiosInstance) =>
|
|
|
214
229
|
deviceRoom,
|
|
215
230
|
serialNumber,
|
|
216
231
|
};
|
|
217
|
-
|
|
218
|
-
|
|
232
|
+
return fetchJson(baseURL, "device", {
|
|
233
|
+
method: "POST",
|
|
234
|
+
headers: Object.assign({ "Content-Type": "application/json" }, headers(jwtToken)),
|
|
235
|
+
body: JSON.stringify(body),
|
|
236
|
+
});
|
|
219
237
|
});
|
|
220
|
-
const editDevice = (
|
|
238
|
+
const editDevice = (baseURL) =>
|
|
221
239
|
/**
|
|
222
240
|
* Updates a device's name and room.
|
|
223
241
|
*
|
|
@@ -233,8 +251,11 @@ const editDevice = (axiosInstance) =>
|
|
|
233
251
|
deviceName,
|
|
234
252
|
deviceRoom,
|
|
235
253
|
};
|
|
236
|
-
|
|
237
|
-
|
|
254
|
+
return fetchJson(baseURL, `device/${normalizedMac}`, {
|
|
255
|
+
method: "PUT",
|
|
256
|
+
headers: Object.assign({ "Content-Type": "application/json" }, headers(jwtToken)),
|
|
257
|
+
body: JSON.stringify(body),
|
|
258
|
+
});
|
|
238
259
|
});
|
|
239
260
|
/**
|
|
240
261
|
* Configures the library for API interactions.
|
|
@@ -247,29 +268,16 @@ const editDevice = (axiosInstance) =>
|
|
|
247
268
|
* const api = configure();
|
|
248
269
|
* const power = await api.getPower(jwtToken, macAddress);
|
|
249
270
|
*/
|
|
250
|
-
const configure = (baseURL = API_URL) => {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
return {
|
|
263
|
-
deviceInfo: deviceInfoInstance,
|
|
264
|
-
registerDevice: registerDeviceInstance,
|
|
265
|
-
editDevice: editDeviceInstance,
|
|
266
|
-
setPower: setPowerInstance,
|
|
267
|
-
setPowerOff: setPowerOffInstance,
|
|
268
|
-
setPowerOn: setPowerOnInstance,
|
|
269
|
-
getPower: getPowerInstance,
|
|
270
|
-
getEnvironmentTemperature: getEnvironmentTemperatureInstance,
|
|
271
|
-
getTargetTemperature: getTargetTemperatureInstance,
|
|
272
|
-
setTargetTemperature: setTargetTemperatureInstance,
|
|
273
|
-
};
|
|
274
|
-
};
|
|
271
|
+
const configure = (baseURL = API_URL) => ({
|
|
272
|
+
deviceInfo: deviceInfo(baseURL),
|
|
273
|
+
registerDevice: registerDevice(baseURL),
|
|
274
|
+
editDevice: editDevice(baseURL),
|
|
275
|
+
setPower: setPower(baseURL),
|
|
276
|
+
setPowerOff: setPowerOff(baseURL),
|
|
277
|
+
setPowerOn: setPowerOn(baseURL),
|
|
278
|
+
getPower: getPower(baseURL),
|
|
279
|
+
getEnvironmentTemperature: getEnvironmentTemperature(baseURL),
|
|
280
|
+
getTargetTemperature: getTargetTemperature(baseURL),
|
|
281
|
+
setTargetTemperature: setTargetTemperature(baseURL),
|
|
282
|
+
});
|
|
275
283
|
export { configure, configureAmplify, createAuthService, getSession, headers, signIn, };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|