@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/dist/sdk-ts.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Collection } from "./classes/collection";
|
|
2
|
+
import { Historian } from "./classes/historian";
|
|
3
|
+
import { Tag } from "./classes/tag";
|
|
4
|
+
import { Function } from "./classes/function";
|
|
5
|
+
import { Flow } from "./classes/flow";
|
|
6
|
+
import { Auth } from "./classes/auth";
|
|
7
|
+
export interface SDKConfig {
|
|
8
|
+
application_id: string;
|
|
9
|
+
httpUrl?: string;
|
|
10
|
+
mqttUrl?: string;
|
|
11
|
+
natsUrl?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare class SDK {
|
|
14
|
+
private http;
|
|
15
|
+
private mqtt;
|
|
16
|
+
private nats;
|
|
17
|
+
private _historian;
|
|
18
|
+
private _tag;
|
|
19
|
+
private _function;
|
|
20
|
+
private _flow;
|
|
21
|
+
private _auth;
|
|
22
|
+
/**
|
|
23
|
+
* Initializes the SDK with the required clients.
|
|
24
|
+
*
|
|
25
|
+
* Example usage:
|
|
26
|
+
* ```typescript
|
|
27
|
+
* import { SDK, type SDKConfig } from '@machhub-dev/sdk-ts';
|
|
28
|
+
*
|
|
29
|
+
* const config: SDKConfig = {
|
|
30
|
+
* application_id: 'your-app-id',
|
|
31
|
+
* httpUrl: 'http://localhost:80', // optional (default = http://localhost:80)
|
|
32
|
+
* mqttUrl: 'ws://localhost:180', // optional (default = ws://localhost:180)
|
|
33
|
+
* natsUrl: 'ws://localhost:7500', // optional (default = ws://localhost:7500)
|
|
34
|
+
* };
|
|
35
|
+
*
|
|
36
|
+
* const sdk = new SDK();
|
|
37
|
+
* await sdk.Initialize(config);
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @param config {SDKConfig} The configuration object containing initialization parameters. See SDKConfig for details.
|
|
41
|
+
* @returns {Promise<boolean>} Resolves to true if initialization is successful.
|
|
42
|
+
*/
|
|
43
|
+
Initialize(config: SDKConfig): Promise<boolean>;
|
|
44
|
+
/**
|
|
45
|
+
* Getter for `auth`. Ensures `auth` is accessed only after initialization.
|
|
46
|
+
*/
|
|
47
|
+
get auth(): Auth;
|
|
48
|
+
/**
|
|
49
|
+
* Getter for `historian`. Ensures `historian` is accessed only after initialization.
|
|
50
|
+
*/
|
|
51
|
+
get historian(): Historian;
|
|
52
|
+
/**
|
|
53
|
+
* Getter for `tag`. Ensures `tag` is accessed only after initialization.
|
|
54
|
+
*/
|
|
55
|
+
get tag(): Tag;
|
|
56
|
+
/**
|
|
57
|
+
* Getter for `function`. Ensures `function` is accessed only after initialization.
|
|
58
|
+
*/
|
|
59
|
+
get function(): Function;
|
|
60
|
+
/**
|
|
61
|
+
* Getter for `flow`. Ensures `flow` is accessed only after initialization.
|
|
62
|
+
*/
|
|
63
|
+
get flow(): Flow;
|
|
64
|
+
/**
|
|
65
|
+
* Creates a collection instance to interact with the specified table/collection.
|
|
66
|
+
* Throws an error if the SDK is not initialized.
|
|
67
|
+
* @param collectionName {string} The collection/table name.
|
|
68
|
+
* @returns {Collection} An instance of Collection.
|
|
69
|
+
*/
|
|
70
|
+
collection(collectionName: string): Collection;
|
|
71
|
+
}
|
package/dist/sdk-ts.js
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
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
|
+
const MACHHUB_SDK_PATH = "machhub";
|
|
12
|
+
// Core HTTP client class
|
|
13
|
+
class HTTPClient {
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new HTTPClient instance
|
|
16
|
+
* @param applicationID The ID for your application (required)
|
|
17
|
+
* @param httpUrl The base URL for HTTP connection (default = http://localhost:80)
|
|
18
|
+
*/
|
|
19
|
+
constructor(applicationID, httpUrl = "http://localhost:80") {
|
|
20
|
+
if (!applicationID) {
|
|
21
|
+
const config = getAppConfig();
|
|
22
|
+
if (config != undefined) {
|
|
23
|
+
applicationID = config.application_id;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
throw new Error("Failed to get Configuration.");
|
|
27
|
+
}
|
|
28
|
+
if (!applicationID) {
|
|
29
|
+
throw new Error("Application ID is required. Set it via the APP_ID environment variable or pass it as a parameter.");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
this.httpService = new HTTPService(httpUrl, MACHHUB_SDK_PATH, applicationID);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Gets server info
|
|
36
|
+
*/
|
|
37
|
+
async getInfo() {
|
|
38
|
+
return this.httpService.request.get("info");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// Core MQTT client class
|
|
42
|
+
class MQTTClient {
|
|
43
|
+
constructor(mqttService) {
|
|
44
|
+
this.mqttService = mqttService;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Creates a new MQTTClient instance
|
|
48
|
+
* @param applicationID The ID for your application
|
|
49
|
+
* @param mqttUrl The base URL for MQTT connection (default = ws://localhost:180)
|
|
50
|
+
*/
|
|
51
|
+
static async getInstance(applicationID, mqttUrl = "ws://localhost:180") {
|
|
52
|
+
// if (!applicationID) {
|
|
53
|
+
// applicationID = process.env.APP_ID;
|
|
54
|
+
// if (!applicationID) {
|
|
55
|
+
// throw new Error("Application ID is required. Set it via the APP_ID environment variable or pass it as a parameter.");
|
|
56
|
+
// }
|
|
57
|
+
// }
|
|
58
|
+
if (!this.instance) {
|
|
59
|
+
const mqttService = await MQTTService.getInstance(mqttUrl);
|
|
60
|
+
this.instance = new MQTTClient(mqttService); // Use the constructor to initialize the instance
|
|
61
|
+
}
|
|
62
|
+
return this.instance;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Subscribes to live tag data updates
|
|
66
|
+
* @param topic The tag topic
|
|
67
|
+
* @param callback The callback function for data updates
|
|
68
|
+
*/
|
|
69
|
+
async subscribeLiveData(topic, callback) {
|
|
70
|
+
return this.mqttService.addTopicHandler(topic, callback);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Publishes a message to a specific topic
|
|
74
|
+
* @param topic The topic to publish to
|
|
75
|
+
* @param data The data to publish
|
|
76
|
+
*/
|
|
77
|
+
async publish(topic, data) {
|
|
78
|
+
return this.mqttService.publish(topic, data);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Core NATS client class
|
|
82
|
+
class NATSClient {
|
|
83
|
+
constructor(natsService) {
|
|
84
|
+
this.natsService = natsService;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Creates a new NATSClient instance
|
|
88
|
+
* @param applicationID The ID for your application
|
|
89
|
+
* @param natsUrl The base URL for NATS connection (default = ws://localhost:7500)
|
|
90
|
+
*/
|
|
91
|
+
static async getInstance(applicationID, natsUrl = "ws://localhost:7500") {
|
|
92
|
+
if (!this.instance) {
|
|
93
|
+
const natsService = await NATSService.getInstance(natsUrl);
|
|
94
|
+
this.instance = new NATSClient(natsService);
|
|
95
|
+
}
|
|
96
|
+
return this.instance;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Subscribes to subject updates
|
|
100
|
+
* @param subject The subject to subscribe to
|
|
101
|
+
* @param callback The callback function for data updates
|
|
102
|
+
*/
|
|
103
|
+
async subscribe(subject, callback) {
|
|
104
|
+
return this.natsService.addSubjectHandler(subject, callback);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Publishes a message to a specific subject
|
|
108
|
+
* @param subject The subject to publish to
|
|
109
|
+
* @param data The data to publish
|
|
110
|
+
*/
|
|
111
|
+
async publish(subject, data) {
|
|
112
|
+
return this.natsService.publish(subject, data);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// SDK Class
|
|
116
|
+
export class SDK {
|
|
117
|
+
constructor() {
|
|
118
|
+
this.http = null;
|
|
119
|
+
this.mqtt = null;
|
|
120
|
+
this.nats = null;
|
|
121
|
+
this._historian = null;
|
|
122
|
+
this._tag = null;
|
|
123
|
+
this._function = null;
|
|
124
|
+
this._flow = null;
|
|
125
|
+
this._auth = null;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Initializes the SDK with the required clients.
|
|
129
|
+
*
|
|
130
|
+
* Example usage:
|
|
131
|
+
* ```typescript
|
|
132
|
+
* import { SDK, type SDKConfig } from '@machhub-dev/sdk-ts';
|
|
133
|
+
*
|
|
134
|
+
* const config: SDKConfig = {
|
|
135
|
+
* application_id: 'your-app-id',
|
|
136
|
+
* httpUrl: 'http://localhost:80', // optional (default = http://localhost:80)
|
|
137
|
+
* mqttUrl: 'ws://localhost:180', // optional (default = ws://localhost:180)
|
|
138
|
+
* natsUrl: 'ws://localhost:7500', // optional (default = ws://localhost:7500)
|
|
139
|
+
* };
|
|
140
|
+
*
|
|
141
|
+
* const sdk = new SDK();
|
|
142
|
+
* await sdk.Initialize(config);
|
|
143
|
+
* ```
|
|
144
|
+
*
|
|
145
|
+
* @param config {SDKConfig} The configuration object containing initialization parameters. See SDKConfig for details.
|
|
146
|
+
* @returns {Promise<boolean>} Resolves to true if initialization is successful.
|
|
147
|
+
*/
|
|
148
|
+
async Initialize(config) {
|
|
149
|
+
try {
|
|
150
|
+
const { application_id, httpUrl, mqttUrl, natsUrl } = config;
|
|
151
|
+
this.http = new HTTPClient(application_id, httpUrl);
|
|
152
|
+
this.mqtt = await MQTTClient.getInstance(application_id, mqttUrl);
|
|
153
|
+
this.nats = await NATSClient.getInstance(application_id, natsUrl);
|
|
154
|
+
this._historian = new Historian(this.http["httpService"], this.mqtt["mqttService"]);
|
|
155
|
+
this._tag = new Tag(this.http["httpService"], this.mqtt["mqttService"]);
|
|
156
|
+
this._function = new Function(this.http["httpService"], this.nats["natsService"]);
|
|
157
|
+
this._flow = new Flow(this.http["httpService"]);
|
|
158
|
+
this._auth = new Auth(this.http["httpService"]);
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
console.error("Failed to initialize:", error);
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Getter for `auth`. Ensures `auth` is accessed only after initialization.
|
|
168
|
+
*/
|
|
169
|
+
get auth() {
|
|
170
|
+
if (!this._auth) {
|
|
171
|
+
throw new Error("SDK is not initialized. Call `Initialize` before accessing `auth`.");
|
|
172
|
+
}
|
|
173
|
+
return this._auth;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Getter for `historian`. Ensures `historian` is accessed only after initialization.
|
|
177
|
+
*/
|
|
178
|
+
get historian() {
|
|
179
|
+
if (!this._historian) {
|
|
180
|
+
throw new Error("SDK is not initialized. Call `Initialize` before accessing `historian`.");
|
|
181
|
+
}
|
|
182
|
+
return this._historian;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Getter for `tag`. Ensures `tag` is accessed only after initialization.
|
|
186
|
+
*/
|
|
187
|
+
get tag() {
|
|
188
|
+
if (!this._tag) {
|
|
189
|
+
throw new Error("SDK is not initialized. Call `Initialize` before accessing `tag`.");
|
|
190
|
+
}
|
|
191
|
+
return this._tag;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Getter for `function`. Ensures `function` is accessed only after initialization.
|
|
195
|
+
*/
|
|
196
|
+
get function() {
|
|
197
|
+
if (!this._function) {
|
|
198
|
+
throw new Error("SDK is not initialized. Call `Initialize` before accessing `function`.");
|
|
199
|
+
}
|
|
200
|
+
return this._function;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Getter for `flow`. Ensures `flow` is accessed only after initialization.
|
|
204
|
+
*/
|
|
205
|
+
get flow() {
|
|
206
|
+
if (!this._flow) {
|
|
207
|
+
throw new Error("SDK is not initialized. Call `Initialize` before accessing `flow`.");
|
|
208
|
+
}
|
|
209
|
+
return this._flow;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Creates a collection instance to interact with the specified table/collection.
|
|
213
|
+
* Throws an error if the SDK is not initialized.
|
|
214
|
+
* @param collectionName {string} The collection/table name.
|
|
215
|
+
* @returns {Collection} An instance of Collection.
|
|
216
|
+
*/
|
|
217
|
+
collection(collectionName) {
|
|
218
|
+
if (!this.http) {
|
|
219
|
+
throw new Error("SDK is not initialized. Call `Initialize` before accessing collection.");
|
|
220
|
+
}
|
|
221
|
+
return new Collection(this.http["httpService"], this.mqtt ? this.mqtt["mqttService"] : null, collectionName);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export declare class HTTPException extends Error {
|
|
2
|
+
status: number;
|
|
3
|
+
statusText: string;
|
|
4
|
+
body: string;
|
|
5
|
+
constructor(status: number, statusText: string, body: string);
|
|
6
|
+
get message(): string;
|
|
7
|
+
}
|
|
8
|
+
export declare class HTTPService {
|
|
9
|
+
private url;
|
|
10
|
+
private applicationID;
|
|
11
|
+
constructor(url: string, prefix?: string, applicationID?: string);
|
|
12
|
+
get request(): RequestParameters;
|
|
13
|
+
}
|
|
14
|
+
declare class RequestParameters {
|
|
15
|
+
private base;
|
|
16
|
+
private applicationID;
|
|
17
|
+
query?: Record<string, string>;
|
|
18
|
+
init?: RequestInit;
|
|
19
|
+
headers?: Record<string, string>;
|
|
20
|
+
constructor(base: URL, applicationID: string, query?: Record<string, string>);
|
|
21
|
+
private withQuery;
|
|
22
|
+
private parseInit;
|
|
23
|
+
withBody(body: BodyInit): RequestParameters;
|
|
24
|
+
includeCredentials(): RequestParameters;
|
|
25
|
+
includeSameOriginCredentials(): RequestParameters;
|
|
26
|
+
keepAlive(): RequestParameters;
|
|
27
|
+
followRedirect(): RequestParameters;
|
|
28
|
+
errorOnRedirect(): RequestParameters;
|
|
29
|
+
setHeader(key: string, value: string): RequestParameters;
|
|
30
|
+
setBearerToken(token: string): RequestParameters;
|
|
31
|
+
withAccessToken(): RequestParameters;
|
|
32
|
+
withDomain(): RequestParameters;
|
|
33
|
+
withContentType(mime: string): RequestParameters;
|
|
34
|
+
withJSON(body: Record<string, unknown>): RequestParameters;
|
|
35
|
+
get<ReturnType>(path: string, query?: Record<string, string>): Promise<ReturnType>;
|
|
36
|
+
post<ReturnType>(path: string, query?: Record<string, string>, body?: FormData | Record<string, string>): Promise<ReturnType>;
|
|
37
|
+
put<ReturnType>(path: string, query?: Record<string, string>): Promise<ReturnType>;
|
|
38
|
+
delete<ReturnType>(path: string, query?: Record<string, string>): Promise<ReturnType>;
|
|
39
|
+
patch<ReturnType>(path: string, query?: Record<string, string>): Promise<ReturnType>;
|
|
40
|
+
}
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
export class HTTPException extends Error {
|
|
2
|
+
constructor(status, statusText, body) {
|
|
3
|
+
super();
|
|
4
|
+
this.status = status;
|
|
5
|
+
this.statusText = statusText;
|
|
6
|
+
this.body = body;
|
|
7
|
+
}
|
|
8
|
+
get message() {
|
|
9
|
+
return `(EXCEPTION) ${this.statusText} - ${this.body}`;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export class HTTPService {
|
|
13
|
+
constructor(url, prefix, applicationID) {
|
|
14
|
+
if (prefix == null)
|
|
15
|
+
prefix = "";
|
|
16
|
+
this.url = new URL(prefix, url);
|
|
17
|
+
this.applicationID = "domains:" + applicationID;
|
|
18
|
+
}
|
|
19
|
+
get request() {
|
|
20
|
+
return new RequestParameters(this.url, this.applicationID);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
class RequestParameters {
|
|
24
|
+
constructor(base, applicationID, query) {
|
|
25
|
+
this.base = base;
|
|
26
|
+
this.applicationID = applicationID;
|
|
27
|
+
this.query = query;
|
|
28
|
+
this.withDomain(); // Ensure withDomain() is called by default
|
|
29
|
+
this.withAccessToken(); // Ensure withAccessToken() is called by default
|
|
30
|
+
}
|
|
31
|
+
withQuery(path, query) {
|
|
32
|
+
const newPath = [this.base.pathname, path].map(pathPart => pathPart.replace(/(^\/|\/$)/g, "")).join("/");
|
|
33
|
+
const newURL = new URL(newPath, this.base);
|
|
34
|
+
for (const key in query) {
|
|
35
|
+
newURL.searchParams.append(key, query[key]);
|
|
36
|
+
}
|
|
37
|
+
return newURL;
|
|
38
|
+
}
|
|
39
|
+
parseInit(method) {
|
|
40
|
+
if (method == null && this.headers == null)
|
|
41
|
+
return;
|
|
42
|
+
let tempInit = Object.assign({}, this.init);
|
|
43
|
+
if (tempInit == null) {
|
|
44
|
+
tempInit = {};
|
|
45
|
+
}
|
|
46
|
+
if (method != null && tempInit != null)
|
|
47
|
+
tempInit.method = method;
|
|
48
|
+
if (this.headers != null && tempInit != null) {
|
|
49
|
+
tempInit.headers = Object.assign({}, this.headers);
|
|
50
|
+
}
|
|
51
|
+
return tempInit;
|
|
52
|
+
}
|
|
53
|
+
withBody(body) {
|
|
54
|
+
if (this.init == null) {
|
|
55
|
+
this.init = {};
|
|
56
|
+
}
|
|
57
|
+
this.init.body = body;
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
includeCredentials() {
|
|
61
|
+
if (this.init == null) {
|
|
62
|
+
this.init = {};
|
|
63
|
+
}
|
|
64
|
+
this.init.credentials = "include";
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
includeSameOriginCredentials() {
|
|
68
|
+
if (this.init == null) {
|
|
69
|
+
this.init = {};
|
|
70
|
+
}
|
|
71
|
+
this.init.credentials = "same-origin";
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
keepAlive() {
|
|
75
|
+
if (this.init == null) {
|
|
76
|
+
this.init = {};
|
|
77
|
+
}
|
|
78
|
+
this.init.keepalive = true;
|
|
79
|
+
return this;
|
|
80
|
+
}
|
|
81
|
+
followRedirect() {
|
|
82
|
+
if (this.init == null) {
|
|
83
|
+
this.init = {};
|
|
84
|
+
}
|
|
85
|
+
this.init.redirect = "follow";
|
|
86
|
+
return this;
|
|
87
|
+
}
|
|
88
|
+
errorOnRedirect() {
|
|
89
|
+
if (this.init == null) {
|
|
90
|
+
this.init = {};
|
|
91
|
+
}
|
|
92
|
+
this.init.redirect = "error";
|
|
93
|
+
return this;
|
|
94
|
+
}
|
|
95
|
+
setHeader(key, value) {
|
|
96
|
+
if (this.headers == null) {
|
|
97
|
+
this.headers = {
|
|
98
|
+
key: value
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
this.headers[key] = value;
|
|
102
|
+
return this;
|
|
103
|
+
}
|
|
104
|
+
setBearerToken(token) {
|
|
105
|
+
this.setHeader("Authorization", `Bearer ${token}`);
|
|
106
|
+
return this;
|
|
107
|
+
}
|
|
108
|
+
withAccessToken() {
|
|
109
|
+
const tkn = localStorage.getItem("x-machhub-auth-tkn");
|
|
110
|
+
this.setHeader("Authorization", `Bearer ${tkn}`);
|
|
111
|
+
return this;
|
|
112
|
+
}
|
|
113
|
+
withDomain() {
|
|
114
|
+
this.setHeader("Domain", this.applicationID);
|
|
115
|
+
return this;
|
|
116
|
+
}
|
|
117
|
+
withContentType(mime) {
|
|
118
|
+
this.setHeader("Content-Type", mime);
|
|
119
|
+
return this;
|
|
120
|
+
}
|
|
121
|
+
withJSON(body) {
|
|
122
|
+
const bd = JSON.stringify(body);
|
|
123
|
+
return this.withBody(bd).withContentType("application/json");
|
|
124
|
+
}
|
|
125
|
+
async get(path, query) {
|
|
126
|
+
const response = await fetch(this.withQuery(path, query), this.parseInit());
|
|
127
|
+
if (!response.ok) {
|
|
128
|
+
throw new HTTPException(response.status, response.statusText, await response.text());
|
|
129
|
+
}
|
|
130
|
+
return response.json();
|
|
131
|
+
}
|
|
132
|
+
async post(path, query, body) {
|
|
133
|
+
const init = this.parseInit("POST") || {};
|
|
134
|
+
if (body) {
|
|
135
|
+
if (body instanceof FormData) {
|
|
136
|
+
init.body = body;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
init.body = JSON.stringify(body);
|
|
140
|
+
init.headers = {
|
|
141
|
+
...init.headers,
|
|
142
|
+
'Content-Type': 'application/json'
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const response = await fetch(this.withQuery(path, query), init);
|
|
147
|
+
if (!response.ok) {
|
|
148
|
+
throw new HTTPException(response.status, response.statusText, await response.text());
|
|
149
|
+
}
|
|
150
|
+
return response.json();
|
|
151
|
+
}
|
|
152
|
+
async put(path, query) {
|
|
153
|
+
const response = await fetch(this.withQuery(path, query), this.parseInit("PUT"));
|
|
154
|
+
if (!response.ok) {
|
|
155
|
+
throw new HTTPException(response.status, response.statusText, await response.text());
|
|
156
|
+
}
|
|
157
|
+
return response.json();
|
|
158
|
+
}
|
|
159
|
+
async delete(path, query) {
|
|
160
|
+
const response = await fetch(this.withQuery(path, query), this.parseInit("DELETE"));
|
|
161
|
+
if (!response.ok) {
|
|
162
|
+
throw new HTTPException(response.status, response.statusText, await response.text());
|
|
163
|
+
}
|
|
164
|
+
return response.json();
|
|
165
|
+
}
|
|
166
|
+
async patch(path, query) {
|
|
167
|
+
const response = await fetch(this.withQuery(path, query), this.parseInit("PATCH"));
|
|
168
|
+
if (!response.ok) {
|
|
169
|
+
throw new HTTPException(response.status, response.statusText, await response.text());
|
|
170
|
+
}
|
|
171
|
+
return response.json();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import mqtt from 'mqtt';
|
|
2
|
+
export declare class MQTTService {
|
|
3
|
+
private url;
|
|
4
|
+
client: mqtt.MqttClient;
|
|
5
|
+
private static instance;
|
|
6
|
+
private subscribedTopics;
|
|
7
|
+
constructor(url: string);
|
|
8
|
+
static getInstance(url?: string): Promise<MQTTService>;
|
|
9
|
+
static resetInstance(): void;
|
|
10
|
+
addTopicHandler(topic: string, handler: (message: unknown) => void): void;
|
|
11
|
+
clearTopics(): void;
|
|
12
|
+
publish(topic: string, message: unknown): boolean;
|
|
13
|
+
private attachMessageListener;
|
|
14
|
+
private parseMessage;
|
|
15
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import mqtt from 'mqtt';
|
|
2
|
+
export class MQTTService {
|
|
3
|
+
constructor(url) {
|
|
4
|
+
this.subscribedTopics = [];
|
|
5
|
+
this.url = url;
|
|
6
|
+
}
|
|
7
|
+
static async getInstance(url = "ws://localhost:180") {
|
|
8
|
+
if (!this.instance || !this.instance.client) {
|
|
9
|
+
this.instance = new MQTTService(url);
|
|
10
|
+
// Ensure the URL is set correctly
|
|
11
|
+
this.instance.url = url;
|
|
12
|
+
// Initialize the MQTT client
|
|
13
|
+
this.instance.client = mqtt.connect(this.instance.url, { protocolVersion: 5 });
|
|
14
|
+
this.instance.attachMessageListener();
|
|
15
|
+
// console.log("MQTT Client initialized with URL:", this.instance.url);
|
|
16
|
+
}
|
|
17
|
+
return this.instance;
|
|
18
|
+
}
|
|
19
|
+
// Method to reset the instance
|
|
20
|
+
static resetInstance() {
|
|
21
|
+
if (this.instance) {
|
|
22
|
+
this.instance.client.end();
|
|
23
|
+
this.instance = undefined;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// addTopicHandler Adds a topic and handler to the subscribed list
|
|
27
|
+
addTopicHandler(topic, handler) {
|
|
28
|
+
try {
|
|
29
|
+
this.subscribedTopics.push({ topic, handler });
|
|
30
|
+
if (topic == "")
|
|
31
|
+
return;
|
|
32
|
+
console.log("New Subscription Handler:", topic);
|
|
33
|
+
this.client.subscribe(topic, { qos: 2 }, (err) => {
|
|
34
|
+
if (err) {
|
|
35
|
+
console.error(`Failed to subscribe to topic ${topic}:`, err);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
console.error(`Failed to subscribe to topic ${topic}:`, e);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// clearTopics clears all the topics subscribed to
|
|
44
|
+
clearTopics() {
|
|
45
|
+
this.subscribedTopics = [];
|
|
46
|
+
}
|
|
47
|
+
// Publishes a message to a specific topic
|
|
48
|
+
publish(topic, message) {
|
|
49
|
+
try {
|
|
50
|
+
const payload = JSON.stringify(message);
|
|
51
|
+
console.log("Publishing to", topic, "with payload:", payload);
|
|
52
|
+
this.client.publish(topic, payload, {
|
|
53
|
+
qos: 2,
|
|
54
|
+
retain: true,
|
|
55
|
+
properties: {
|
|
56
|
+
contentType: "json",
|
|
57
|
+
},
|
|
58
|
+
}, (err) => {
|
|
59
|
+
if (err) {
|
|
60
|
+
console.error(`Failed to publish message to ${topic}:`, err);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
console.error(`Failed to publish to topic ${topic}:`, e);
|
|
66
|
+
throw e;
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
attachMessageListener() {
|
|
71
|
+
this.client.on('connect', () => {
|
|
72
|
+
console.log("MQTT connected to", this.url);
|
|
73
|
+
});
|
|
74
|
+
this.client.on('error', (error) => {
|
|
75
|
+
console.error("MQTT connection error:", error);
|
|
76
|
+
});
|
|
77
|
+
this.client.on('message', (topic, message) => {
|
|
78
|
+
for (const subscribedTopic of this.subscribedTopics) {
|
|
79
|
+
if (topic === subscribedTopic.topic) {
|
|
80
|
+
const parsedMessage = this.parseMessage(message);
|
|
81
|
+
subscribedTopic.handler(parsedMessage);
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
parseMessage(message) {
|
|
88
|
+
try {
|
|
89
|
+
return JSON.parse(message.toString());
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
console.error("Error parsing message:", error);
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|