@machhub-dev/sdk-ts 0.0.1
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/LICENSE +21 -0
- package/dist/cjs/classes/auth.d.ts +18 -0
- package/dist/cjs/classes/auth.js +90 -0
- package/dist/cjs/classes/collection.d.ts +18 -0
- package/dist/cjs/classes/collection.js +43 -0
- package/dist/cjs/classes/flow.d.ts +6 -0
- package/dist/cjs/classes/flow.js +12 -0
- package/dist/cjs/classes/function.d.ts +10 -0
- package/dist/cjs/classes/function.js +29 -0
- package/dist/cjs/classes/historian.d.ts +12 -0
- package/dist/cjs/classes/historian.js +40 -0
- package/dist/cjs/classes/tag.d.ts +10 -0
- package/dist/cjs/classes/tag.js +25 -0
- package/dist/cjs/client.d.ts +13 -0
- package/dist/cjs/client.js +35 -0
- package/dist/cjs/config.d.ts +21 -0
- package/dist/cjs/config.js +37 -0
- package/dist/cjs/example/functions-file-config.d.ts +0 -0
- package/dist/cjs/example/functions-file-config.js +1 -0
- package/dist/cjs/example/functions.d.ts +1 -0
- package/dist/cjs/example/functions.js +18 -0
- package/dist/cjs/http-client.d.ts +10 -0
- package/dist/cjs/http-client.js +62 -0
- package/dist/cjs/index.d.ts +6 -0
- package/dist/cjs/index.js +7 -0
- package/dist/cjs/sdk-ts-clean.d.ts +108 -0
- package/dist/cjs/sdk-ts-clean.js +294 -0
- package/dist/cjs/sdk-ts.d.ts +71 -0
- package/dist/cjs/sdk-ts.js +227 -0
- package/dist/cjs/services/http.service.d.ts +41 -0
- package/dist/cjs/services/http.service.js +178 -0
- package/dist/cjs/services/mqtt.service.d.ts +15 -0
- package/dist/cjs/services/mqtt.service.js +103 -0
- package/dist/cjs/services/nats.service.d.ts +78 -0
- package/dist/cjs/services/nats.service.js +237 -0
- package/dist/cjs/types/auth.models.d.ts +52 -0
- package/dist/cjs/types/auth.models.js +100 -0
- package/dist/cjs/types/recordID.models.d.ts +7 -0
- package/dist/cjs/types/recordID.models.js +32 -0
- package/dist/cjs/types/response.models.d.ts +4 -0
- package/dist/cjs/types/response.models.js +2 -0
- package/dist/cjs/types/tag.models.d.ts +4 -0
- package/dist/cjs/types/tag.models.js +2 -0
- package/dist/cjs/utils/appConfig.d.ts +5 -0
- package/dist/cjs/utils/appConfig.js +62 -0
- package/dist/cjs/websocket-client.d.ts +15 -0
- package/dist/cjs/websocket-client.js +96 -0
- package/dist/classes/auth.d.ts +18 -0
- package/dist/classes/auth.js +86 -0
- package/dist/classes/collection.d.ts +18 -0
- package/dist/classes/collection.js +39 -0
- package/dist/classes/flow.d.ts +6 -0
- package/dist/classes/flow.js +8 -0
- package/dist/classes/function.d.ts +10 -0
- package/dist/classes/function.js +25 -0
- package/dist/classes/historian.d.ts +12 -0
- package/dist/classes/historian.js +36 -0
- package/dist/classes/tag.d.ts +10 -0
- package/dist/classes/tag.js +21 -0
- package/dist/client.d.ts +13 -0
- package/dist/client.js +31 -0
- package/dist/config.d.ts +21 -0
- package/dist/config.js +33 -0
- package/dist/example/functions-file-config.d.ts +0 -0
- package/dist/example/functions-file-config.js +1 -0
- package/dist/example/functions.d.ts +1 -0
- package/dist/example/functions.js +16 -0
- package/dist/http-client.d.ts +10 -0
- package/dist/http-client.js +58 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +2 -0
- package/dist/sdk-ts-clean.d.ts +108 -0
- package/dist/sdk-ts-clean.js +290 -0
- package/dist/sdk-ts.d.ts +71 -0
- package/dist/sdk-ts.js +223 -0
- package/dist/services/http.service.d.ts +41 -0
- package/dist/services/http.service.js +173 -0
- package/dist/services/mqtt.service.d.ts +15 -0
- package/dist/services/mqtt.service.js +96 -0
- package/dist/services/nats.service.d.ts +78 -0
- package/dist/services/nats.service.js +233 -0
- package/dist/types/auth.models.d.ts +52 -0
- package/dist/types/auth.models.js +97 -0
- package/dist/types/recordID.models.d.ts +7 -0
- package/dist/types/recordID.models.js +27 -0
- package/dist/types/response.models.d.ts +4 -0
- package/dist/types/response.models.js +1 -0
- package/dist/types/tag.models.d.ts +4 -0
- package/dist/types/tag.models.js +1 -0
- package/dist/utils/appConfig.d.ts +5 -0
- package/dist/utils/appConfig.js +26 -0
- package/dist/websocket-client.d.ts +15 -0
- package/dist/websocket-client.js +92 -0
- package/package.json +33 -0
- package/src/classes/auth.ts +103 -0
- package/src/classes/collection.ts +55 -0
- package/src/classes/flow.ts +13 -0
- package/src/classes/function.ts +34 -0
- package/src/classes/historian.ts +49 -0
- package/src/classes/tag.ts +30 -0
- package/src/example/functions.ts +21 -0
- package/src/index.ts +8 -0
- package/src/sdk-ts.ts +255 -0
- package/src/services/http.service.ts +239 -0
- package/src/services/mqtt.service.ts +114 -0
- package/src/services/nats.service.ts +262 -0
- package/src/types/auth.models.ts +157 -0
- package/src/types/recordID.models.ts +33 -0
- package/src/types/response.models.ts +4 -0
- package/src/types/tag.models.ts +4 -0
- package/src/utils/appConfig.ts +30 -0
- package/tsconfig.json +14 -0
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@machhub-dev/sdk-ts",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "MACHHUB TYPESCRIPT SDK",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"machhub",
|
|
7
|
+
"intellogic technology"
|
|
8
|
+
],
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"author": "Intellogic Technology Sdn Bhd",
|
|
11
|
+
"types": "dist/types.d.ts",
|
|
12
|
+
"main": "dist/cjs/index.cjs",
|
|
13
|
+
"module": "dist/index.js",
|
|
14
|
+
"exports": {
|
|
15
|
+
"import": "./dist/index.js",
|
|
16
|
+
"require": "./dist/cjs/index.cjs"
|
|
17
|
+
},
|
|
18
|
+
"type": "module",
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "npx tsc && npx tsc --module CommonJS --outDir dist/cjs"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"mqtt": "^5.10.4",
|
|
24
|
+
"safe-buffer": "^5.2.1",
|
|
25
|
+
"typescript": "^5.8.3",
|
|
26
|
+
"undici-types": "^7.4.0"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@nats-io/nats-core": "^3.0.2",
|
|
30
|
+
"@nats-io/transport-node": "^3.0.2",
|
|
31
|
+
"@types/node": "^22.13.5"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { HTTPService } from "../services/http.service";
|
|
2
|
+
import { Action, ActionResponse, Feature, Group, LoginResponse, User, ValidateJWTResponse } from "../types/auth.models";
|
|
3
|
+
|
|
4
|
+
export class Auth {
|
|
5
|
+
private httpService: HTTPService;
|
|
6
|
+
|
|
7
|
+
constructor(httpService: HTTPService) {
|
|
8
|
+
this.httpService = httpService;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public async login(username: string, password: string): Promise<LoginResponse | undefined> {
|
|
12
|
+
let res: LoginResponse
|
|
13
|
+
try {
|
|
14
|
+
res = await this.httpService.request.withJSON({
|
|
15
|
+
username: username,
|
|
16
|
+
password: password,
|
|
17
|
+
}).post("/auth/login");
|
|
18
|
+
|
|
19
|
+
if (localStorage) {
|
|
20
|
+
localStorage.setItem("x-machhub-auth-tkn", res.tkn); // Set User JWT
|
|
21
|
+
} else {
|
|
22
|
+
console.error("localStorage is not available. The program needs to be in a browser environment.");
|
|
23
|
+
}
|
|
24
|
+
return res
|
|
25
|
+
}
|
|
26
|
+
catch (e: unknown) {
|
|
27
|
+
if ((e as Error).message == "localStorage is not defined") {
|
|
28
|
+
throw new Error("Login failed: localStorage is not available. The program needs to be in a browser environment.");
|
|
29
|
+
}
|
|
30
|
+
throw new Error("Login failed: " + (e as Error).message);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public async validateJWT(token: string): Promise<ValidateJWTResponse>{
|
|
35
|
+
let res:ValidateJWTResponse = await this.httpService.request.withJSON({ token }).post("/auth/jwt/validate");
|
|
36
|
+
return res
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public async logout() {
|
|
40
|
+
localStorage.removeItem("x-machhub-auth-tkn"); // Remove User JWT
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public async checkAction(feature: string, scope: string): Promise<ActionResponse> {
|
|
44
|
+
try {
|
|
45
|
+
const res: ActionResponse = await this.httpService.request.get(`/auth/permission/action/feature/${feature}/scope/${scope}`);
|
|
46
|
+
return res
|
|
47
|
+
}
|
|
48
|
+
catch (e: unknown) {
|
|
49
|
+
throw new Error("failed to checkAction : " + (e as Error).message);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public async checkPermission(feature: string, scope: string, action: Action): Promise<ActionResponse> {
|
|
54
|
+
try {
|
|
55
|
+
const res: ActionResponse = await this.httpService.request.get(`/auth/permission/check/feature/${feature}/scope/${scope}/action/${action}`);
|
|
56
|
+
return res
|
|
57
|
+
}
|
|
58
|
+
catch (e: unknown) {
|
|
59
|
+
throw new Error("failed to checkPermission : " + (e as Error).message);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public async getUsers(): Promise<User[]> {
|
|
64
|
+
return await this.httpService.request.get("/auth/user");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
public async getUserById(userId: string): Promise<User> {
|
|
68
|
+
return await this.httpService.request.get(`/auth/user/${userId}`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public async createUser(firstName: string, lastName: string, username: string, email: string, password: string, number: string, userImage: string): Promise<User> {
|
|
72
|
+
return await this.httpService.request.withJSON({
|
|
73
|
+
firstName: firstName,
|
|
74
|
+
lastName: lastName,
|
|
75
|
+
username: username,
|
|
76
|
+
email: email,
|
|
77
|
+
password: password,
|
|
78
|
+
number: number,
|
|
79
|
+
userImage: userImage
|
|
80
|
+
}).post("/auth/user");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public async getGroups(): Promise<Group[]> {
|
|
84
|
+
return await this.httpService.request.get("/auth/group");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public async createGroup(name: string, features: Feature[]): Promise<Group> {
|
|
88
|
+
return await this.httpService.request.withJSON({
|
|
89
|
+
name: name,
|
|
90
|
+
features: features
|
|
91
|
+
}).post("/auth/group");
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public async addUserToGroup(userId: string, groupId: string): Promise<ActionResponse> {
|
|
95
|
+
return await this.httpService.request.post(`/auth/group/${groupId}/user/${userId}`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public async addPermissionsToGroup(group_id: string, permissions: Feature[]): Promise<ActionResponse> {
|
|
99
|
+
return await this.httpService.request.withJSON({
|
|
100
|
+
group_id, permissions
|
|
101
|
+
}).post("/auth/permission");
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { HTTPService } from "../services/http.service";
|
|
2
|
+
import { MQTTService } from "../services/mqtt.service";
|
|
3
|
+
|
|
4
|
+
export class Collection {
|
|
5
|
+
protected httpService: HTTPService;
|
|
6
|
+
protected mqttService: MQTTService | null;
|
|
7
|
+
protected collectionName: string;
|
|
8
|
+
protected queryParams: Record<string, any> = {};
|
|
9
|
+
|
|
10
|
+
constructor(httpService: HTTPService, mqttService: MQTTService | null, collectionName: string) {
|
|
11
|
+
this.httpService = httpService;
|
|
12
|
+
this.mqttService = mqttService;
|
|
13
|
+
this.collectionName = collectionName;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
filter(fieldName: string, operator: "=" | ">" | "<" | "<=" | ">=" | "!=", value: any): Collection {
|
|
17
|
+
this.queryParams[`filter[${fieldName}][${operator}][${typeof value}]`] = value;
|
|
18
|
+
return this;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
sort(field: string, direction: "asc" | "desc" = "asc"): Collection {
|
|
22
|
+
this.queryParams.sort = `[${field}][${direction}]`;
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
limit(limit: number): Collection {
|
|
27
|
+
this.queryParams.limit = limit;
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
offset(offset: number): Collection {
|
|
32
|
+
this.queryParams.offset = offset;
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async getAll(): Promise<any[]> {
|
|
37
|
+
return this.httpService.request.get(this.collectionName + "/all", this.queryParams);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async getOne(id: string): Promise<any> {
|
|
41
|
+
return this.httpService.request.get(id);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async create(data: Record<string, any>): Promise<any> {
|
|
45
|
+
return this.httpService.request.withJSON(data).post(this.collectionName);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async update(id: string, data: Record<string, any>): Promise<any> {
|
|
49
|
+
return this.httpService.request.withJSON(data).put(id);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async delete(id: string): Promise<any> {
|
|
53
|
+
return this.httpService.request.delete(id);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { HTTPService } from "../services/http.service";
|
|
2
|
+
|
|
3
|
+
export class Flow {
|
|
4
|
+
private httpService: HTTPService;
|
|
5
|
+
|
|
6
|
+
constructor(httpService: HTTPService) {
|
|
7
|
+
this.httpService = httpService;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
public async executeFlow(name: string, payload: any): Promise<any> {
|
|
11
|
+
return await this.httpService.request.withJSON(payload).post("flow/execute/name/" + name);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { HTTPService } from "../services/http.service";
|
|
2
|
+
import { NATSService } from "../services/nats.service";
|
|
3
|
+
|
|
4
|
+
export class Function {
|
|
5
|
+
private httpService: HTTPService;
|
|
6
|
+
private natsService: NATSService | null;
|
|
7
|
+
|
|
8
|
+
constructor(httpService: HTTPService, natsService: NATSService) {
|
|
9
|
+
this.httpService = httpService;
|
|
10
|
+
this.natsService = natsService;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public async executeFunction(function_type: string, function_name: string, payload: any): Promise<any> {
|
|
14
|
+
return await this.httpService.request.withJSON({
|
|
15
|
+
function_type: function_type,
|
|
16
|
+
function_name: function_name,
|
|
17
|
+
payload: payload,
|
|
18
|
+
}).post("function/execute");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public async addFunction(name: string, func: (data: Record<string,any>) => Record<string,any>): Promise<any> {
|
|
22
|
+
if (!this.natsService) {
|
|
23
|
+
throw new Error("NATS service not connected");
|
|
24
|
+
}
|
|
25
|
+
return this.natsService.addFunction(name, func);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public async initializeFunctions(): Promise<any> {
|
|
29
|
+
if (!this.natsService) {
|
|
30
|
+
throw new Error("NATS service not connected");
|
|
31
|
+
}
|
|
32
|
+
return this.natsService.initializeFunctions();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { HTTPService } from "../services/http.service";
|
|
2
|
+
import { MQTTService } from "../services/mqtt.service";
|
|
3
|
+
import { HistorizedData } from "../types/tag.models";
|
|
4
|
+
|
|
5
|
+
export class Historian {
|
|
6
|
+
private httpService: HTTPService;
|
|
7
|
+
private mqttService: MQTTService | null;
|
|
8
|
+
|
|
9
|
+
constructor(httpService: HTTPService, mqttService: MQTTService | null) {
|
|
10
|
+
this.httpService = httpService;
|
|
11
|
+
this.mqttService = mqttService;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async getAllHistorizedTags(): Promise<string[]> {
|
|
15
|
+
return this.httpService.request.get("historian/list");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async getHistoricalData(topic: string, start_time: Date, range?: string): Promise<HistorizedData[]> {
|
|
19
|
+
let isoStartTime = start_time.toISOString();
|
|
20
|
+
return this.httpService.request.withJSON({
|
|
21
|
+
topic: topic,
|
|
22
|
+
start_time: isoStartTime,
|
|
23
|
+
range: range,
|
|
24
|
+
}).patch("historian");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async subscribeLiveData(topic: string, callback: (data: any) => void): Promise<any> {
|
|
28
|
+
if (!this.mqttService) {
|
|
29
|
+
throw new Error("MQTT service not connected");
|
|
30
|
+
}
|
|
31
|
+
this.mqttService.addTopicHandler(topic, callback);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async getLastNValues(topic: string, n: number): Promise<HistorizedData[]> {
|
|
35
|
+
if (n <= 0) {
|
|
36
|
+
throw new Error("The number of values to fetch must be greater than 0.");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (n > 100){
|
|
40
|
+
throw new Error("The number of values to fetch must be less than 100.");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return this.httpService.request.withJSON({
|
|
44
|
+
topic: topic,
|
|
45
|
+
limit: n,
|
|
46
|
+
sort: "desc", // Fetch the latest values
|
|
47
|
+
}).patch("historian/last");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { HTTPService } from "../services/http.service";
|
|
2
|
+
import { MQTTService } from "../services/mqtt.service";
|
|
3
|
+
|
|
4
|
+
export class Tag {
|
|
5
|
+
private httpService: HTTPService;
|
|
6
|
+
private mqttService: MQTTService | null;
|
|
7
|
+
|
|
8
|
+
constructor(httpService: HTTPService, mqttService: MQTTService | null) {
|
|
9
|
+
this.httpService = httpService;
|
|
10
|
+
this.mqttService = mqttService;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async getAllTags(): Promise<string[]> {
|
|
14
|
+
return this.httpService.request.get("tag/list");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async publish(topic: string, data: any): Promise<void> {
|
|
18
|
+
if (!this.mqttService) {
|
|
19
|
+
throw new Error("MQTT service not connected");
|
|
20
|
+
}
|
|
21
|
+
this.mqttService.publish(topic, data);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async subscribe(topic: string, callback: (data: any) => void): Promise<void> {
|
|
25
|
+
if (!this.mqttService) {
|
|
26
|
+
throw new Error("MQTT service not connected");
|
|
27
|
+
}
|
|
28
|
+
this.mqttService.addTopicHandler(topic, callback);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { SDK, SDKConfig } from "../index";
|
|
2
|
+
|
|
3
|
+
let sdk = new SDK();
|
|
4
|
+
let config: SDKConfig = {
|
|
5
|
+
application_id: "machhub_admin",
|
|
6
|
+
natsUrl: "nats://localhost:4222",
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
(async () => {
|
|
10
|
+
await sdk.Initialize(config);
|
|
11
|
+
|
|
12
|
+
function add10(data: Record<string,any>): Record<string,any>{
|
|
13
|
+
data.result = data.a + 10;
|
|
14
|
+
console.log("Function add executed with data:", data);
|
|
15
|
+
return data
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
sdk.function.addFunction("add", add10);
|
|
19
|
+
|
|
20
|
+
await sdk.function.initializeFunctions();
|
|
21
|
+
})();
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { SDK, type SDKConfig } from './sdk-ts';
|
|
2
|
+
export { getAppConfig } from './utils/appConfig';
|
|
3
|
+
|
|
4
|
+
// Export individual types
|
|
5
|
+
export type { LoginResponse, PermissionResponse, User, Group, Feature, Permission, ActionResponse, Action, Scope } from './types/auth.models';
|
|
6
|
+
export type { BaseResponse } from './types/response.models';
|
|
7
|
+
export type { RecordID } from './types/recordID.models';
|
|
8
|
+
export type { HistorizedData } from './types/tag.models';
|
package/src/sdk-ts.ts
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { HTTPService } from "./services/http.service";
|
|
2
|
+
import { MQTTService } from "./services/mqtt.service";
|
|
3
|
+
import { NATSService } from "./services/nats.service";
|
|
4
|
+
import { getAppConfig } from "./utils/appConfig";
|
|
5
|
+
import { Collection } from "./classes/collection";
|
|
6
|
+
import { Historian } from "./classes/historian";
|
|
7
|
+
import { Tag } from "./classes/tag";
|
|
8
|
+
import { Function } from "./classes/function";
|
|
9
|
+
import { Flow } from "./classes/flow";
|
|
10
|
+
import { Auth } from "./classes/auth";
|
|
11
|
+
|
|
12
|
+
const MACHHUB_SDK_PATH = "machhub";
|
|
13
|
+
|
|
14
|
+
// Core HTTP client class
|
|
15
|
+
class HTTPClient {
|
|
16
|
+
private httpService: HTTPService;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new HTTPClient instance
|
|
20
|
+
* @param applicationID The ID for your application (required)
|
|
21
|
+
* @param httpUrl The base URL for HTTP connection (default = http://localhost:80)
|
|
22
|
+
*/
|
|
23
|
+
constructor(applicationID: string, httpUrl: string = "http://localhost:80") {
|
|
24
|
+
if (!applicationID) {
|
|
25
|
+
const config = getAppConfig()
|
|
26
|
+
if (config != undefined) {
|
|
27
|
+
applicationID = config.application_id;
|
|
28
|
+
} else {
|
|
29
|
+
throw new Error("Failed to get Configuration.");
|
|
30
|
+
}
|
|
31
|
+
if (!applicationID) {
|
|
32
|
+
throw new Error("Application ID is required. Set it via the APP_ID environment variable or pass it as a parameter.");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
this.httpService = new HTTPService(httpUrl, MACHHUB_SDK_PATH, applicationID);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Gets server info
|
|
40
|
+
*/
|
|
41
|
+
async getInfo(): Promise<any> {
|
|
42
|
+
return this.httpService.request.get("info");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Core MQTT client class
|
|
47
|
+
class MQTTClient {
|
|
48
|
+
private mqttService: MQTTService;
|
|
49
|
+
private static instance: MQTTClient | undefined;
|
|
50
|
+
|
|
51
|
+
private constructor(mqttService: MQTTService) {
|
|
52
|
+
this.mqttService = mqttService;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Creates a new MQTTClient instance
|
|
57
|
+
* @param applicationID The ID for your application
|
|
58
|
+
* @param mqttUrl The base URL for MQTT connection (default = ws://localhost:180)
|
|
59
|
+
*/
|
|
60
|
+
static async getInstance(applicationID?: string, mqttUrl: string = "ws://localhost:180"): Promise<MQTTClient> {
|
|
61
|
+
// if (!applicationID) {
|
|
62
|
+
// applicationID = process.env.APP_ID;
|
|
63
|
+
// if (!applicationID) {
|
|
64
|
+
// throw new Error("Application ID is required. Set it via the APP_ID environment variable or pass it as a parameter.");
|
|
65
|
+
// }
|
|
66
|
+
// }
|
|
67
|
+
if (!this.instance) {
|
|
68
|
+
const mqttService = await MQTTService.getInstance(mqttUrl);
|
|
69
|
+
this.instance = new MQTTClient(mqttService); // Use the constructor to initialize the instance
|
|
70
|
+
}
|
|
71
|
+
return this.instance;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Subscribes to live tag data updates
|
|
76
|
+
* @param topic The tag topic
|
|
77
|
+
* @param callback The callback function for data updates
|
|
78
|
+
*/
|
|
79
|
+
async subscribeLiveData(topic: string, callback: (data: any) => void): Promise<any> {
|
|
80
|
+
return this.mqttService.addTopicHandler(topic, callback);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Publishes a message to a specific topic
|
|
85
|
+
* @param topic The topic to publish to
|
|
86
|
+
* @param data The data to publish
|
|
87
|
+
*/
|
|
88
|
+
async publish(topic: string, data: any): Promise<any> {
|
|
89
|
+
return this.mqttService.publish(topic, data);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Core NATS client class
|
|
94
|
+
class NATSClient {
|
|
95
|
+
private natsService: NATSService;
|
|
96
|
+
private static instance: NATSClient | undefined;
|
|
97
|
+
|
|
98
|
+
private constructor(natsService: NATSService) {
|
|
99
|
+
this.natsService = natsService;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Creates a new NATSClient instance
|
|
104
|
+
* @param applicationID The ID for your application
|
|
105
|
+
* @param natsUrl The base URL for NATS connection (default = ws://localhost:7500)
|
|
106
|
+
*/
|
|
107
|
+
static async getInstance(applicationID?: string, natsUrl: string = "ws://localhost:7500"): Promise<NATSClient> {
|
|
108
|
+
if (!this.instance) {
|
|
109
|
+
const natsService = await NATSService.getInstance(natsUrl);
|
|
110
|
+
this.instance = new NATSClient(natsService);
|
|
111
|
+
}
|
|
112
|
+
return this.instance;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Subscribes to subject updates
|
|
117
|
+
* @param subject The subject to subscribe to
|
|
118
|
+
* @param callback The callback function for data updates
|
|
119
|
+
*/
|
|
120
|
+
async subscribe(subject: string, callback: (data: any) => void): Promise<any> {
|
|
121
|
+
return this.natsService.addSubjectHandler(subject, callback);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Publishes a message to a specific subject
|
|
126
|
+
* @param subject The subject to publish to
|
|
127
|
+
* @param data The data to publish
|
|
128
|
+
*/
|
|
129
|
+
async publish(subject: string, data: any): Promise<any> {
|
|
130
|
+
return this.natsService.publish(subject, data);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface SDKConfig {
|
|
135
|
+
application_id: string;
|
|
136
|
+
httpUrl?: string;
|
|
137
|
+
mqttUrl?: string;
|
|
138
|
+
natsUrl?: string;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// SDK Class
|
|
142
|
+
export class SDK {
|
|
143
|
+
private http: HTTPClient | null = null;
|
|
144
|
+
private mqtt: MQTTClient | null = null;
|
|
145
|
+
private nats: NATSClient | null = null;
|
|
146
|
+
private _historian: Historian | null = null;
|
|
147
|
+
private _tag: Tag | null = null;
|
|
148
|
+
private _function: Function | null = null;
|
|
149
|
+
private _flow: Flow | null = null;
|
|
150
|
+
private _auth: Auth | null = null;
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Initializes the SDK with the required clients.
|
|
154
|
+
*
|
|
155
|
+
* Example usage:
|
|
156
|
+
* ```typescript
|
|
157
|
+
* import { SDK, type SDKConfig } from '@machhub-dev/sdk-ts';
|
|
158
|
+
*
|
|
159
|
+
* const config: SDKConfig = {
|
|
160
|
+
* application_id: 'your-app-id',
|
|
161
|
+
* httpUrl: 'http://localhost:80', // optional (default = http://localhost:80)
|
|
162
|
+
* mqttUrl: 'ws://localhost:180', // optional (default = ws://localhost:180)
|
|
163
|
+
* natsUrl: 'ws://localhost:7500', // optional (default = ws://localhost:7500)
|
|
164
|
+
* };
|
|
165
|
+
*
|
|
166
|
+
* const sdk = new SDK();
|
|
167
|
+
* await sdk.Initialize(config);
|
|
168
|
+
* ```
|
|
169
|
+
*
|
|
170
|
+
* @param config {SDKConfig} The configuration object containing initialization parameters. See SDKConfig for details.
|
|
171
|
+
* @returns {Promise<boolean>} Resolves to true if initialization is successful.
|
|
172
|
+
*/
|
|
173
|
+
public async Initialize(config: SDKConfig): Promise<boolean> {
|
|
174
|
+
try {
|
|
175
|
+
const { application_id, httpUrl, mqttUrl, natsUrl } = config;
|
|
176
|
+
|
|
177
|
+
this.http = new HTTPClient(application_id, httpUrl);
|
|
178
|
+
this.mqtt = await MQTTClient.getInstance(application_id, mqttUrl);
|
|
179
|
+
this.nats = await NATSClient.getInstance(application_id, natsUrl);
|
|
180
|
+
this._historian = new Historian(this.http["httpService"], this.mqtt["mqttService"]);
|
|
181
|
+
this._tag = new Tag(this.http["httpService"], this.mqtt["mqttService"]);
|
|
182
|
+
this._function = new Function(this.http["httpService"], this.nats["natsService"]);
|
|
183
|
+
this._flow = new Flow(this.http["httpService"]);
|
|
184
|
+
this._auth = new Auth(this.http["httpService"]);
|
|
185
|
+
} catch (error: any) {
|
|
186
|
+
console.error("Failed to initialize:", error);
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Getter for `auth`. Ensures `auth` is accessed only after initialization.
|
|
195
|
+
*/
|
|
196
|
+
public get auth(): Auth {
|
|
197
|
+
if (!this._auth) {
|
|
198
|
+
throw new Error("SDK is not initialized. Call `Initialize` before accessing `auth`.");
|
|
199
|
+
}
|
|
200
|
+
return this._auth;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Getter for `historian`. Ensures `historian` is accessed only after initialization.
|
|
205
|
+
*/
|
|
206
|
+
public get historian(): Historian {
|
|
207
|
+
if (!this._historian) {
|
|
208
|
+
throw new Error("SDK is not initialized. Call `Initialize` before accessing `historian`.");
|
|
209
|
+
}
|
|
210
|
+
return this._historian;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Getter for `tag`. Ensures `tag` is accessed only after initialization.
|
|
215
|
+
*/
|
|
216
|
+
public get tag(): Tag {
|
|
217
|
+
if (!this._tag) {
|
|
218
|
+
throw new Error("SDK is not initialized. Call `Initialize` before accessing `tag`.");
|
|
219
|
+
}
|
|
220
|
+
return this._tag;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Getter for `function`. Ensures `function` is accessed only after initialization.
|
|
225
|
+
*/
|
|
226
|
+
public get function(): Function {
|
|
227
|
+
if (!this._function) {
|
|
228
|
+
throw new Error("SDK is not initialized. Call `Initialize` before accessing `function`.");
|
|
229
|
+
}
|
|
230
|
+
return this._function;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Getter for `flow`. Ensures `flow` is accessed only after initialization.
|
|
235
|
+
*/
|
|
236
|
+
public get flow(): Flow {
|
|
237
|
+
if (!this._flow) {
|
|
238
|
+
throw new Error("SDK is not initialized. Call `Initialize` before accessing `flow`.");
|
|
239
|
+
}
|
|
240
|
+
return this._flow;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Creates a collection instance to interact with the specified table/collection.
|
|
245
|
+
* Throws an error if the SDK is not initialized.
|
|
246
|
+
* @param collectionName {string} The collection/table name.
|
|
247
|
+
* @returns {Collection} An instance of Collection.
|
|
248
|
+
*/
|
|
249
|
+
public collection(collectionName: string): Collection {
|
|
250
|
+
if (!this.http) {
|
|
251
|
+
throw new Error("SDK is not initialized. Call `Initialize` before accessing collection.");
|
|
252
|
+
}
|
|
253
|
+
return new Collection(this.http["httpService"], this.mqtt ? this.mqtt["mqttService"] : null, collectionName);
|
|
254
|
+
}
|
|
255
|
+
}
|