ogi-addon 0.1.1 → 0.1.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/build/EventResponse.cjs +46 -0
- package/build/EventResponse.cjs.map +1 -0
- package/build/EventResponse.d.cts +13 -0
- package/build/EventResponse.d.ts +3 -1
- package/build/EventResponse.js +24 -22
- package/build/EventResponse.js.map +1 -1
- package/build/SearchEngine.cjs +19 -0
- package/build/SearchEngine.cjs.map +1 -0
- package/build/SearchEngine.d.cts +11 -0
- package/build/SearchEngine.d.ts +3 -1
- package/build/SearchEngine.js +0 -1
- package/build/SearchEngine.js.map +1 -1
- package/build/config/Configuration.cjs +282 -0
- package/build/config/Configuration.cjs.map +1 -0
- package/build/config/Configuration.d.cts +20 -0
- package/build/config/Configuration.d.ts +6 -3
- package/build/config/Configuration.js +230 -60
- package/build/config/Configuration.js.map +1 -1
- package/build/config/ConfigurationBuilder.cjs +208 -0
- package/build/config/ConfigurationBuilder.cjs.map +1 -0
- package/build/config/ConfigurationBuilder.d.cts +57 -0
- package/build/config/ConfigurationBuilder.d.ts +12 -10
- package/build/config/ConfigurationBuilder.js +159 -163
- package/build/config/ConfigurationBuilder.js.map +1 -1
- package/build/main.cjs +434 -0
- package/build/main.cjs.map +1 -0
- package/build/main.d.cts +76 -0
- package/build/main.d.ts +17 -14
- package/build/main.js +391 -150
- package/build/main.js.map +1 -1
- package/package.json +49 -23
- package/src/config/Configuration.ts +4 -2
- package/tsconfig.json +2 -3
- package/tsup.config.js +11 -0
package/build/main.js
CHANGED
|
@@ -1,156 +1,397 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
// src/main.ts
|
|
2
|
+
import ws from "ws";
|
|
3
|
+
import events from "node:events";
|
|
4
|
+
|
|
5
|
+
// src/config/ConfigurationBuilder.ts
|
|
6
|
+
import z, { ZodError } from "zod";
|
|
7
|
+
var configValidation = z.object({
|
|
8
|
+
name: z.string().min(1),
|
|
9
|
+
displayName: z.string().min(1),
|
|
10
|
+
description: z.string().min(1)
|
|
11
|
+
});
|
|
12
|
+
var ConfigurationBuilder = class {
|
|
13
|
+
options = [];
|
|
14
|
+
addNumberOption(option) {
|
|
15
|
+
let newOption = new NumberOption();
|
|
16
|
+
newOption = option(newOption);
|
|
17
|
+
this.options.push(newOption);
|
|
18
|
+
return this;
|
|
19
|
+
}
|
|
20
|
+
addStringOption(option) {
|
|
21
|
+
let newOption = new StringOption();
|
|
22
|
+
newOption = option(newOption);
|
|
23
|
+
this.options.push(newOption);
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
addBooleanOption(option) {
|
|
27
|
+
let newOption = new BooleanOption();
|
|
28
|
+
newOption = option(newOption);
|
|
29
|
+
this.options.push(newOption);
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
build(includeFunctions) {
|
|
33
|
+
let config = {};
|
|
34
|
+
this.options.forEach((option) => {
|
|
35
|
+
if (!includeFunctions) {
|
|
36
|
+
option = JSON.parse(JSON.stringify(option));
|
|
37
|
+
const optionData = configValidation.safeParse(option);
|
|
38
|
+
if (!optionData.success) {
|
|
39
|
+
throw new ZodError(optionData.error.errors);
|
|
40
|
+
}
|
|
41
|
+
config[option.name] = option;
|
|
42
|
+
} else {
|
|
43
|
+
config[option.name] = option;
|
|
44
|
+
}
|
|
8
45
|
});
|
|
46
|
+
return config;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var ConfigurationOption = class {
|
|
50
|
+
name = "";
|
|
51
|
+
defaultValue = "";
|
|
52
|
+
displayName = "";
|
|
53
|
+
description = "";
|
|
54
|
+
type = "unset";
|
|
55
|
+
setName(name) {
|
|
56
|
+
this.name = name;
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
setDisplayName(displayName) {
|
|
60
|
+
this.displayName = displayName;
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
63
|
+
setDescription(description) {
|
|
64
|
+
this.description = description;
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
validate(input) {
|
|
68
|
+
throw new Error("Validation code not implemented. Value: " + input);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
var StringOption = class extends ConfigurationOption {
|
|
72
|
+
allowedValues = [];
|
|
73
|
+
minTextLength = 0;
|
|
74
|
+
maxTextLength = Number.MAX_SAFE_INTEGER;
|
|
75
|
+
defaultValue = "";
|
|
76
|
+
type = "string";
|
|
77
|
+
setAllowedValues(allowedValues) {
|
|
78
|
+
this.allowedValues = allowedValues;
|
|
79
|
+
return this;
|
|
80
|
+
}
|
|
81
|
+
setDefaultValue(defaultValue) {
|
|
82
|
+
this.defaultValue = defaultValue;
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
setMinTextLength(minTextLength) {
|
|
86
|
+
this.minTextLength = minTextLength;
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
89
|
+
setMaxTextLength(maxTextLength) {
|
|
90
|
+
this.maxTextLength = maxTextLength;
|
|
91
|
+
return this;
|
|
92
|
+
}
|
|
93
|
+
validate(input) {
|
|
94
|
+
if (typeof input !== "string") {
|
|
95
|
+
return [false, "Input is not a string"];
|
|
96
|
+
}
|
|
97
|
+
if (this.allowedValues.length === 0 && input.length !== 0)
|
|
98
|
+
return [true, ""];
|
|
99
|
+
if (input.length < this.minTextLength || input.length > this.maxTextLength) {
|
|
100
|
+
return [false, "Input is not within the text length " + this.minTextLength + " and " + this.maxTextLength + " characters (currently " + input.length + " characters)"];
|
|
101
|
+
}
|
|
102
|
+
return [this.allowedValues.includes(input), "Input is not an allowed value"];
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
var NumberOption = class extends ConfigurationOption {
|
|
106
|
+
min = 0;
|
|
107
|
+
max = Number.MAX_SAFE_INTEGER;
|
|
108
|
+
defaultValue = 0;
|
|
109
|
+
type = "number";
|
|
110
|
+
inputType = "number";
|
|
111
|
+
setMin(min) {
|
|
112
|
+
this.min = min;
|
|
113
|
+
return this;
|
|
114
|
+
}
|
|
115
|
+
setInputType(type) {
|
|
116
|
+
this.inputType = type;
|
|
117
|
+
return this;
|
|
118
|
+
}
|
|
119
|
+
setMax(max) {
|
|
120
|
+
this.max = max;
|
|
121
|
+
return this;
|
|
122
|
+
}
|
|
123
|
+
setDefaultValue(defaultValue) {
|
|
124
|
+
this.defaultValue = defaultValue;
|
|
125
|
+
return this;
|
|
126
|
+
}
|
|
127
|
+
validate(input) {
|
|
128
|
+
if (isNaN(Number(input))) {
|
|
129
|
+
return [false, "Input is not a number"];
|
|
130
|
+
}
|
|
131
|
+
if (Number(input) < this.min || Number(input) > this.max) {
|
|
132
|
+
return [false, "Input is not within the range of " + this.min + " and " + this.max];
|
|
133
|
+
}
|
|
134
|
+
return [true, ""];
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
var BooleanOption = class extends ConfigurationOption {
|
|
138
|
+
type = "boolean";
|
|
139
|
+
defaultValue = false;
|
|
140
|
+
setDefaultValue(defaultValue) {
|
|
141
|
+
this.defaultValue = defaultValue;
|
|
142
|
+
return this;
|
|
143
|
+
}
|
|
144
|
+
validate(input) {
|
|
145
|
+
if (typeof input !== "boolean") {
|
|
146
|
+
return [false, "Input is not a boolean"];
|
|
147
|
+
}
|
|
148
|
+
return [true, ""];
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// src/config/Configuration.ts
|
|
153
|
+
var Configuration = class {
|
|
154
|
+
storedConfigTemplate;
|
|
155
|
+
definiteConfig = {};
|
|
156
|
+
constructor(configTemplate) {
|
|
157
|
+
this.storedConfigTemplate = configTemplate;
|
|
158
|
+
}
|
|
159
|
+
updateConfig(config, validate = true) {
|
|
160
|
+
this.definiteConfig = config;
|
|
161
|
+
if (validate) {
|
|
162
|
+
const result = this.validateConfig();
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
return [true, {}];
|
|
166
|
+
}
|
|
167
|
+
// provides falsey or truthy value, and an error message if falsey
|
|
168
|
+
validateConfig() {
|
|
169
|
+
const erroredKeys = /* @__PURE__ */ new Map();
|
|
170
|
+
for (const key in this.storedConfigTemplate) {
|
|
171
|
+
if (this.definiteConfig[key] === null || this.definiteConfig[key] === void 0) {
|
|
172
|
+
console.warn("Option " + key + " is not defined. Using default value Value: " + this.definiteConfig[key]);
|
|
173
|
+
this.definiteConfig[key] = this.storedConfigTemplate[key].defaultValue;
|
|
174
|
+
}
|
|
175
|
+
if (this.storedConfigTemplate[key].type !== typeof this.definiteConfig[key]) {
|
|
176
|
+
throw new Error("Option " + key + " is not of the correct type");
|
|
177
|
+
}
|
|
178
|
+
const result = this.storedConfigTemplate[key].validate(this.definiteConfig[key]);
|
|
179
|
+
if (!result[0]) {
|
|
180
|
+
erroredKeys.set(key, result[1]);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
for (const key in this.definiteConfig) {
|
|
184
|
+
if (!this.storedConfigTemplate[key]) {
|
|
185
|
+
throw new Error("Option " + key + " is not defined in the configuration template");
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (erroredKeys.size > 0) {
|
|
189
|
+
return [false, Object.fromEntries(erroredKeys)];
|
|
190
|
+
}
|
|
191
|
+
return [true, Object.fromEntries(erroredKeys)];
|
|
192
|
+
}
|
|
193
|
+
getStringValue(optionName) {
|
|
194
|
+
if (!this.definiteConfig[optionName] === null) {
|
|
195
|
+
throw new Error("Option " + optionName + " is not defined");
|
|
196
|
+
}
|
|
197
|
+
if (typeof this.definiteConfig[optionName] !== "string") {
|
|
198
|
+
throw new Error("Option " + optionName + " is not a string");
|
|
199
|
+
}
|
|
200
|
+
return this.definiteConfig[optionName];
|
|
201
|
+
}
|
|
202
|
+
getNumberValue(optionName) {
|
|
203
|
+
if (!this.definiteConfig[optionName] === null) {
|
|
204
|
+
throw new Error("Option " + optionName + " is not defined");
|
|
205
|
+
}
|
|
206
|
+
if (typeof this.definiteConfig[optionName] !== "number") {
|
|
207
|
+
throw new Error("Option " + optionName + " is not a number");
|
|
208
|
+
}
|
|
209
|
+
return this.definiteConfig[optionName];
|
|
210
|
+
}
|
|
211
|
+
getBooleanValue(optionName) {
|
|
212
|
+
if (this.definiteConfig[optionName] === null) {
|
|
213
|
+
throw new Error("Option " + optionName + " is not defined");
|
|
214
|
+
}
|
|
215
|
+
if (typeof this.definiteConfig[optionName] !== "boolean") {
|
|
216
|
+
throw new Error("Option " + optionName + " is not a boolean");
|
|
217
|
+
}
|
|
218
|
+
return this.definiteConfig[optionName];
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
// src/EventResponse.ts
|
|
223
|
+
var EventResponse = class {
|
|
224
|
+
data = void 0;
|
|
225
|
+
deffered = false;
|
|
226
|
+
resolved = false;
|
|
227
|
+
progress = 0;
|
|
228
|
+
logs = [];
|
|
229
|
+
defer() {
|
|
230
|
+
this.deffered = true;
|
|
231
|
+
}
|
|
232
|
+
resolve(data) {
|
|
233
|
+
this.resolved = true;
|
|
234
|
+
this.data = data;
|
|
235
|
+
}
|
|
236
|
+
complete() {
|
|
237
|
+
this.resolved = true;
|
|
238
|
+
}
|
|
239
|
+
log(message) {
|
|
240
|
+
this.logs.push(message);
|
|
241
|
+
}
|
|
9
242
|
};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
243
|
+
|
|
244
|
+
// src/main.ts
|
|
245
|
+
var defaultPort = 7654;
|
|
246
|
+
var OGIAddon = class {
|
|
247
|
+
eventEmitter = new events.EventEmitter();
|
|
248
|
+
addonWSListener;
|
|
249
|
+
addonInfo;
|
|
250
|
+
config = new Configuration({});
|
|
251
|
+
constructor(addonInfo) {
|
|
252
|
+
this.addonInfo = addonInfo;
|
|
253
|
+
this.addonWSListener = new OGIAddonWSListener(this, this.eventEmitter);
|
|
254
|
+
}
|
|
255
|
+
on(event, listener) {
|
|
256
|
+
this.eventEmitter.on(event, listener);
|
|
257
|
+
}
|
|
258
|
+
emit(event, ...args) {
|
|
259
|
+
this.eventEmitter.emit(event, ...args);
|
|
260
|
+
}
|
|
261
|
+
notify(notification) {
|
|
262
|
+
this.addonWSListener.send("notification", [notification]);
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
var OGIAddonWSListener = class {
|
|
266
|
+
socket;
|
|
267
|
+
eventEmitter;
|
|
268
|
+
addon;
|
|
269
|
+
constructor(ogiAddon, eventEmitter) {
|
|
270
|
+
if (process.argv[process.argv.length - 1].split("=")[0] !== "--addonSecret") {
|
|
271
|
+
throw new Error("No secret provided. This usually happens because the addon was not started by the OGI Addon Server.");
|
|
272
|
+
}
|
|
273
|
+
this.addon = ogiAddon;
|
|
274
|
+
this.eventEmitter = eventEmitter;
|
|
275
|
+
this.socket = new ws("ws://localhost:" + defaultPort);
|
|
276
|
+
this.socket.on("open", () => {
|
|
277
|
+
console.log("Connected to OGI Addon Server");
|
|
278
|
+
this.socket.send(JSON.stringify({
|
|
279
|
+
event: "authenticate",
|
|
280
|
+
args: {
|
|
281
|
+
...this.addon.addonInfo,
|
|
282
|
+
secret: process.argv[process.argv.length - 1].split("=")[1]
|
|
38
283
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
284
|
+
}));
|
|
285
|
+
this.eventEmitter.emit("connect");
|
|
286
|
+
let configBuilder = new ConfigurationBuilder();
|
|
287
|
+
this.eventEmitter.emit("configure", configBuilder);
|
|
288
|
+
this.socket.send(JSON.stringify({
|
|
289
|
+
event: "configure",
|
|
290
|
+
args: configBuilder.build(false)
|
|
291
|
+
}));
|
|
292
|
+
this.addon.config = new Configuration(configBuilder.build(true));
|
|
293
|
+
});
|
|
294
|
+
this.socket.on("error", (error) => {
|
|
295
|
+
if (error.message.includes("Failed to connect")) {
|
|
296
|
+
throw new Error("OGI Addon Server is not running/is unreachable. Please start the server and try again.");
|
|
297
|
+
}
|
|
298
|
+
console.error("An error occurred:", error);
|
|
299
|
+
});
|
|
300
|
+
this.socket.on("close", (code, reason) => {
|
|
301
|
+
if (code === 1008) {
|
|
302
|
+
console.error("Authentication failed:", reason);
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
this.eventEmitter.emit("disconnect", reason);
|
|
306
|
+
console.log("Disconnected from OGI Addon Server");
|
|
307
|
+
this.socket.close();
|
|
308
|
+
});
|
|
309
|
+
this.registerMessageReceiver();
|
|
310
|
+
}
|
|
311
|
+
registerMessageReceiver() {
|
|
312
|
+
this.socket.on("message", async (data) => {
|
|
313
|
+
const message = JSON.parse(data);
|
|
314
|
+
switch (message.event) {
|
|
315
|
+
case "config-update":
|
|
316
|
+
const result = this.addon.config.updateConfig(message.args);
|
|
317
|
+
if (!result[0]) {
|
|
318
|
+
this.respondToMessage(message.id, { success: false, error: result[1] });
|
|
319
|
+
} else {
|
|
320
|
+
this.respondToMessage(message.id, { success: true });
|
|
321
|
+
}
|
|
322
|
+
break;
|
|
323
|
+
case "search":
|
|
324
|
+
let searchResultEvent = new EventResponse();
|
|
325
|
+
this.eventEmitter.emit("search", message.args, searchResultEvent);
|
|
326
|
+
const searchResult = await this.waitForEventToRespond(searchResultEvent);
|
|
327
|
+
console.log(searchResult.data);
|
|
328
|
+
this.respondToMessage(message.id, searchResult.data);
|
|
329
|
+
break;
|
|
330
|
+
case "setup":
|
|
331
|
+
let setupEvent = new EventResponse();
|
|
332
|
+
this.eventEmitter.emit("setup", message.args.path, setupEvent);
|
|
333
|
+
const interval = setInterval(() => {
|
|
334
|
+
if (setupEvent.resolved) {
|
|
335
|
+
clearInterval(interval);
|
|
336
|
+
return;
|
|
67
337
|
}
|
|
68
|
-
this.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
let setupEvent = new EventResponse();
|
|
96
|
-
this.eventEmitter.emit('setup', message.args.path, setupEvent);
|
|
97
|
-
const interval = setInterval(() => {
|
|
98
|
-
if (setupEvent.resolved) {
|
|
99
|
-
clearInterval(interval);
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
this.send('defer-update', {
|
|
103
|
-
logs: setupEvent.logs,
|
|
104
|
-
deferID: message.args.deferID,
|
|
105
|
-
progress: setupEvent.progress
|
|
106
|
-
});
|
|
107
|
-
}, 100);
|
|
108
|
-
const setupResult = yield this.waitForEventToRespond(setupEvent);
|
|
109
|
-
this.respondToMessage(message.id, setupResult.data);
|
|
110
|
-
break;
|
|
338
|
+
this.send("defer-update", {
|
|
339
|
+
logs: setupEvent.logs,
|
|
340
|
+
deferID: message.args.deferID,
|
|
341
|
+
progress: setupEvent.progress
|
|
342
|
+
});
|
|
343
|
+
}, 100);
|
|
344
|
+
const setupResult = await this.waitForEventToRespond(setupEvent);
|
|
345
|
+
this.respondToMessage(message.id, setupResult.data);
|
|
346
|
+
break;
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
waitForEventToRespond(event) {
|
|
351
|
+
return new Promise((resolve, reject) => {
|
|
352
|
+
const dataGet = setInterval(() => {
|
|
353
|
+
if (event.resolved) {
|
|
354
|
+
resolve(event);
|
|
355
|
+
clearTimeout(timeout);
|
|
356
|
+
}
|
|
357
|
+
}, 5);
|
|
358
|
+
const timeout = setTimeout(() => {
|
|
359
|
+
if (event.deffered) {
|
|
360
|
+
clearInterval(dataGet);
|
|
361
|
+
const interval = setInterval(() => {
|
|
362
|
+
if (event.resolved) {
|
|
363
|
+
clearInterval(interval);
|
|
364
|
+
resolve(event);
|
|
111
365
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}));
|
|
144
|
-
console.log("dispatched response to " + messageID);
|
|
145
|
-
}
|
|
146
|
-
send(event, args) {
|
|
147
|
-
this.socket.send(JSON.stringify({
|
|
148
|
-
event,
|
|
149
|
-
args
|
|
150
|
-
}));
|
|
151
|
-
}
|
|
152
|
-
close() {
|
|
153
|
-
this.socket.close();
|
|
154
|
-
}
|
|
155
|
-
}
|
|
366
|
+
}, 100);
|
|
367
|
+
} else {
|
|
368
|
+
reject("Event did not respond in time");
|
|
369
|
+
}
|
|
370
|
+
}, 5e3);
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
respondToMessage(messageID, response) {
|
|
374
|
+
this.socket.send(JSON.stringify({
|
|
375
|
+
event: "response",
|
|
376
|
+
id: messageID,
|
|
377
|
+
args: response
|
|
378
|
+
}));
|
|
379
|
+
console.log("dispatched response to " + messageID);
|
|
380
|
+
}
|
|
381
|
+
send(event, args) {
|
|
382
|
+
this.socket.send(JSON.stringify({
|
|
383
|
+
event,
|
|
384
|
+
args
|
|
385
|
+
}));
|
|
386
|
+
}
|
|
387
|
+
close() {
|
|
388
|
+
this.socket.close();
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
export {
|
|
392
|
+
Configuration,
|
|
393
|
+
ConfigurationBuilder,
|
|
394
|
+
EventResponse,
|
|
395
|
+
OGIAddon as default
|
|
396
|
+
};
|
|
156
397
|
//# sourceMappingURL=main.js.map
|
package/build/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"/","sources":["main.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/main.ts","../src/config/ConfigurationBuilder.ts","../src/config/Configuration.ts","../src/EventResponse.ts"],"sourcesContent":["import ws, { WebSocket } from 'ws';\r\nimport events from 'node:events';\r\nimport { ConfigurationBuilder, ConfigurationFile } from './config/ConfigurationBuilder';\r\nimport { Configuration } from './config/Configuration';\r\nimport EventResponse from './EventResponse';\r\nimport { SearchResult } from './SearchEngine';\r\n\r\nexport type OGIAddonEvent = 'connect' | 'disconnect' | 'configure' | 'authenticate' | 'search' | 'setup';\r\nexport type OGIAddonClientSentEvent = 'response' | 'authenticate' | 'configure' | 'defer-update' | 'notification';\r\n\r\nexport type OGIAddonServerSentEvent = 'authenticate' | 'configure' | 'config-update' | 'search' | 'setup';\r\nexport { ConfigurationBuilder, Configuration, EventResponse, SearchResult };\r\nconst defaultPort = 7654;\r\n\r\nexport interface ClientSentEventTypes {\r\n response: any;\r\n authenticate: any;\r\n configure: ConfigurationFile;\r\n 'defer-update': {\r\n logs: string[], \r\n progress: number\r\n };\r\n notification: Notification;\r\n}\r\n\r\nexport interface EventListenerTypes {\r\n connect: (socket: ws) => void;\r\n disconnect: (reason: string) => void;\r\n configure: (config: ConfigurationBuilder) => ConfigurationBuilder;\r\n response: (response: any) => void;\r\n authenticate: (config: any) => void;\r\n search: (query: string, event: EventResponse<SearchResult[]>) => void;\r\n setup: (path: string, event: EventResponse<undefined | null>) => void;\r\n}\r\n\r\nexport interface WebsocketMessageClient {\r\n event: OGIAddonClientSentEvent;\r\n id?: string;\r\n args: any;\r\n}\r\nexport interface WebsocketMessageServer {\r\n event: OGIAddonServerSentEvent;\r\n id?: string;\r\n args: any;\r\n}\r\nexport interface OGIAddonConfiguration {\r\n name: string;\r\n id: string;\r\n description: string;\r\n version: string;\r\n\r\n author: string;\r\n repository: string;\r\n}\r\nexport default class OGIAddon {\r\n public eventEmitter = new events.EventEmitter();\r\n public addonWSListener: OGIAddonWSListener;\r\n public addonInfo: OGIAddonConfiguration;\r\n public config: Configuration = new Configuration({});\r\n\r\n constructor(addonInfo: OGIAddonConfiguration) {\r\n this.addonInfo = addonInfo;\r\n this.addonWSListener = new OGIAddonWSListener(this, this.eventEmitter);\r\n }\r\n \r\n public on<T extends OGIAddonEvent>(event: T, listener: EventListenerTypes[T]) {\r\n this.eventEmitter.on(event, listener);\r\n }\r\n\r\n public emit<T extends OGIAddonEvent>(event: T, ...args: Parameters<EventListenerTypes[T]>) {\r\n this.eventEmitter.emit(event, ...args);\r\n }\r\n\r\n public notify(notification: Notification) {\r\n this.addonWSListener.send('notification', [ notification ]);\r\n }\r\n}\r\ninterface Notification {\r\n type: 'warning' | 'error' | 'info' | 'success';\r\n message: string;\r\n id: string\r\n}\r\nclass OGIAddonWSListener {\r\n private socket: WebSocket;\r\n public eventEmitter: events.EventEmitter;\r\n public addon: OGIAddon;\r\n\r\n constructor(ogiAddon: OGIAddon, eventEmitter: events.EventEmitter) {\r\n if (process.argv[process.argv.length - 1].split('=')[0] !== '--addonSecret') {\r\n throw new Error('No secret provided. This usually happens because the addon was not started by the OGI Addon Server.');\r\n }\r\n this.addon = ogiAddon;\r\n this.eventEmitter = eventEmitter;\r\n this.socket = new ws('ws://localhost:' + defaultPort);\r\n this.socket.on('open', () => {\r\n console.log('Connected to OGI Addon Server');\r\n\r\n // Authenticate with OGI Addon Server\r\n this.socket.send(JSON.stringify({\r\n event: 'authenticate',\r\n args: {\r\n ...this.addon.addonInfo,\r\n secret: process.argv[process.argv.length - 1].split('=')[1]\r\n }\r\n }));\r\n\r\n this.eventEmitter.emit('connect');\r\n\r\n // send a configuration request\r\n let configBuilder = new ConfigurationBuilder();\r\n this.eventEmitter.emit('configure', configBuilder);\r\n \r\n this.socket.send(JSON.stringify({\r\n event: 'configure',\r\n args: configBuilder.build(false) \r\n }));\r\n this.addon.config = new Configuration(configBuilder.build(true));\r\n });\r\n\r\n this.socket.on('error', (error) => {\r\n if (error.message.includes('Failed to connect')) {\r\n throw new Error('OGI Addon Server is not running/is unreachable. Please start the server and try again.');\r\n }\r\n console.error('An error occurred:', error);\r\n })\r\n\r\n this.socket.on('close', (code, reason) => {\r\n if (code === 1008) {\r\n console.error('Authentication failed:', reason);\r\n return;\r\n }\r\n this.eventEmitter.emit('disconnect', reason);\r\n console.log(\"Disconnected from OGI Addon Server\")\r\n this.socket.close();\r\n });\r\n\r\n this.registerMessageReceiver();\r\n }\r\n\r\n private registerMessageReceiver() {\r\n this.socket.on('message', async (data: string) => {\r\n const message: WebsocketMessageServer = JSON.parse(data);\r\n switch (message.event) {\r\n case 'config-update':\r\n const result = this.addon.config.updateConfig(message.args);\r\n if (!result[0]) {\r\n this.respondToMessage(message.id!!, { success: false, error: result[1] });\r\n }\r\n else {\r\n this.respondToMessage(message.id!!, { success: true });\r\n }\r\n break \r\n case 'search':\r\n let searchResultEvent = new EventResponse<SearchResult[]>();\r\n this.eventEmitter.emit('search', message.args, searchResultEvent);\r\n const searchResult = await this.waitForEventToRespond(searchResultEvent); \r\n console.log(searchResult.data)\r\n this.respondToMessage(message.id!!, searchResult.data);\r\n break\r\n case 'setup':\r\n let setupEvent = new EventResponse<undefined | null>();\r\n this.eventEmitter.emit('setup', message.args.path, setupEvent);\r\n const interval = setInterval(() => {\r\n if (setupEvent.resolved) {\r\n clearInterval(interval);\r\n return;\r\n }\r\n this.send('defer-update', { \r\n logs: setupEvent.logs,\r\n deferID: message.args.deferID,\r\n progress: setupEvent.progress\r\n } as any);\r\n }, 100);\r\n const setupResult = await this.waitForEventToRespond(setupEvent);\r\n this.respondToMessage(message.id!!, setupResult.data);\r\n break\r\n }\r\n });\r\n }\r\n\r\n private waitForEventToRespond<T>(event: EventResponse<T>): Promise<EventResponse<T>> {\r\n return new Promise((resolve, reject) => {\r\n const dataGet = setInterval(() => {\r\n if (event.resolved) {\r\n resolve(event);\r\n clearTimeout(timeout);\r\n }\r\n }, 5); \r\n\r\n const timeout = setTimeout(() => {\r\n if (event.deffered) {\r\n clearInterval(dataGet);\r\n const interval = setInterval(() => {\r\n if (event.resolved) {\r\n clearInterval(interval);\r\n resolve(event);\r\n }\r\n }, 100);\r\n }\r\n else {\r\n reject('Event did not respond in time');\r\n }\r\n }, 5000)\r\n });\r\n }\r\n\r\n public respondToMessage(messageID: string, response: any) {\r\n this.socket.send(JSON.stringify({\r\n event: 'response',\r\n id: messageID,\r\n args: response\r\n }));\r\n console.log(\"dispatched response to \" + messageID)\r\n }\r\n\r\n public send(event: OGIAddonClientSentEvent, args: Parameters<ClientSentEventTypes[OGIAddonClientSentEvent]>) {\r\n this.socket.send(JSON.stringify({\r\n event,\r\n args\r\n }));\r\n }\r\n\r\n public close() {\r\n this.socket.close();\r\n }\r\n\r\n \r\n}","import z, { ZodError } from \"zod\"\r\n\r\nexport interface ConfigurationFile {\r\n [key: string]: ConfigurationOption\r\n}\r\n\r\nconst configValidation = z.object({\r\n name: z.string().min(1),\r\n displayName: z.string().min(1),\r\n description: z.string().min(1),\r\n})\r\n\r\nexport function isStringOption(option: ConfigurationOption): option is StringOption {\r\n return option.type === 'string';\r\n }\r\n\r\nexport function isNumberOption(option: ConfigurationOption): option is NumberOption {\r\n return option.type === 'number';\r\n}\r\n\r\nexport function isBooleanOption(option: ConfigurationOption): option is BooleanOption {\r\n return option.type === 'boolean';\r\n}\r\n\r\nexport class ConfigurationBuilder {\r\n private options: ConfigurationOption[] = [];\r\n public addNumberOption(option: (option: NumberOption) => NumberOption): ConfigurationBuilder {\r\n let newOption = new NumberOption();\r\n newOption = option(newOption);\r\n this.options.push(newOption);\r\n return this;\r\n }\r\n\r\n public addStringOption(option: (option: StringOption) => StringOption) {\r\n let newOption = new StringOption();\r\n newOption = option(newOption);\r\n this.options.push(newOption);\r\n return this;\r\n }\r\n\r\n public addBooleanOption(option: (option: BooleanOption) => BooleanOption) {\r\n let newOption = new BooleanOption();\r\n newOption = option(newOption);\r\n this.options.push(newOption);\r\n return this;\r\n }\r\n\r\n public build(includeFunctions: boolean): ConfigurationFile {\r\n let config: ConfigurationFile = {};\r\n this.options.forEach(option => {\r\n // remove all functions from the option object\r\n if (!includeFunctions) {\r\n option = JSON.parse(JSON.stringify(option));\r\n const optionData = configValidation.safeParse(option)\r\n if (!optionData.success) {\r\n throw new ZodError(optionData.error.errors)\r\n }\r\n\r\n config[option.name] = option;\r\n }\r\n else {\r\n config[option.name] = option;\r\n }\r\n });\r\n return config;\r\n }\r\n}\r\n\r\nexport type ConfigurationOptionType = 'string' | 'number' | 'boolean' | 'unset'\r\nexport class ConfigurationOption {\r\n public name: string = '';\r\n public defaultValue: unknown = '';\r\n public displayName: string = '';\r\n public description: string = '';\r\n public type: ConfigurationOptionType = 'unset'\r\n \r\n setName(name: string) {\r\n this.name = name;\r\n return this;\r\n }\r\n\r\n setDisplayName(displayName: string) {\r\n this.displayName = displayName;\r\n return this;\r\n }\r\n\r\n setDescription(description: string) {\r\n this.description = description;\r\n return this;\r\n }\r\n\r\n\r\n validate(input: unknown): [ boolean, string ] {\r\n throw new Error('Validation code not implemented. Value: ' + input)\r\n };\r\n}\r\n\r\nexport class StringOption extends ConfigurationOption {\r\n public allowedValues: string[] = [];\r\n public minTextLength: number = 0;\r\n public maxTextLength: number = Number.MAX_SAFE_INTEGER;\r\n public defaultValue: string = '';\r\n public type: ConfigurationOptionType = 'string'\r\n\r\n setAllowedValues(allowedValues: string[]): this {\r\n this.allowedValues = allowedValues;\r\n return this;\r\n }\r\n\r\n setDefaultValue(defaultValue: string): this {\r\n this.defaultValue = defaultValue;\r\n return this;\r\n }\r\n\r\n setMinTextLength(minTextLength: number): this {\r\n this.minTextLength = minTextLength;\r\n return this;\r\n }\r\n\r\n setMaxTextLength(maxTextLength: number): this {\r\n this.maxTextLength = maxTextLength;\r\n return this;\r\n }\r\n\r\n override validate(input: unknown): [ boolean, string ] {\r\n if (typeof input !== 'string') {\r\n return [ false, 'Input is not a string' ];\r\n }\r\n if (this.allowedValues.length === 0 && input.length !== 0)\r\n return [ true, '' ];\r\n if (input.length < this.minTextLength || input.length > this.maxTextLength) {\r\n return [ false, 'Input is not within the text length ' + this.minTextLength + ' and ' + this.maxTextLength + ' characters (currently ' + input.length + ' characters)' ];\r\n }\r\n\r\n return [ this.allowedValues.includes(input), 'Input is not an allowed value' ];\r\n }\r\n}\r\n\r\nexport class NumberOption extends ConfigurationOption {\r\n public min: number = 0;\r\n public max: number = Number.MAX_SAFE_INTEGER;\r\n public defaultValue: number = 0;\r\n public type: ConfigurationOptionType = 'number'\r\n public inputType: 'range' | 'number' = 'number';\r\n setMin(min: number): this {\r\n this.min = min;\r\n return this;\r\n }\r\n\r\n setInputType(type: 'range' | 'number'): this {\r\n this.inputType = type;\r\n return this;\r\n }\r\n\r\n setMax(max: number): this {\r\n this.max = max;\r\n return this\r\n }\r\n\r\n setDefaultValue(defaultValue: number): this {\r\n this.defaultValue = defaultValue;\r\n return this;\r\n }\r\n\r\n override validate(input: unknown): [ boolean, string ] {\r\n if (isNaN(Number(input))) {\r\n return [ false, 'Input is not a number' ];\r\n }\r\n if (Number(input) < this.min || Number(input) > this.max) {\r\n return [ false, 'Input is not within the range of ' + this.min + ' and ' + this.max ];\r\n }\r\n return [ true, '' ];\r\n }\r\n\r\n}\r\n\r\nexport class BooleanOption extends ConfigurationOption {\r\n public type: ConfigurationOptionType = 'boolean'\r\n public defaultValue: boolean = false;\r\n\r\n setDefaultValue(defaultValue: boolean): this {\r\n this.defaultValue = defaultValue;\r\n return this;\r\n }\r\n\r\n override validate(input: unknown): [ boolean, string ] {\r\n if (typeof input !== 'boolean') {\r\n return [ false, 'Input is not a boolean' ];\r\n }\r\n return [ true, '' ];\r\n }\r\n\r\n}","import { ConfigurationFile, ConfigurationBuilder, BooleanOption, ConfigurationOption, ConfigurationOptionType, NumberOption, StringOption, isBooleanOption, isNumberOption, isStringOption } from \"./ConfigurationBuilder\";\r\n\r\ninterface DefiniteConfig {\r\n [key: string]: string | number | boolean;\r\n}\r\nexport class Configuration {\r\n readonly storedConfigTemplate: ConfigurationFile;\r\n definiteConfig: DefiniteConfig = {};\r\n constructor(configTemplate: ConfigurationFile) {\r\n this.storedConfigTemplate = configTemplate;\r\n }\r\n\r\n updateConfig(config: DefiniteConfig, validate: boolean = true): [ boolean, { [key: string]: string } ] {\r\n this.definiteConfig = config;\r\n if (validate) {\r\n const result = this.validateConfig();\r\n return result;\r\n }\r\n return [ true, {} ];\r\n }\r\n // provides falsey or truthy value, and an error message if falsey\r\n private validateConfig(): [ boolean, { [key: string]: string } ] {\r\n const erroredKeys = new Map<string, string>();\r\n for (const key in this.storedConfigTemplate) {\r\n if (this.definiteConfig[key] === null || this.definiteConfig[key] === undefined) {\r\n console.warn('Option ' + key + ' is not defined. Using default value Value: ' + this.definiteConfig[key]);\r\n this.definiteConfig[key] = this.storedConfigTemplate[key].defaultValue as string | number | boolean;\r\n }\r\n if (this.storedConfigTemplate[key].type !== typeof this.definiteConfig[key]) {\r\n throw new Error('Option ' + key + ' is not of the correct type');\r\n }\r\n\r\n const result = this.storedConfigTemplate[key].validate(this.definiteConfig[key]);\r\n if (!result[0]) {\r\n erroredKeys.set(key, result[1]);\r\n }\r\n }\r\n\r\n for (const key in this.definiteConfig) {\r\n if (!this.storedConfigTemplate[key]) {\r\n throw new Error('Option ' + key + ' is not defined in the configuration template');\r\n }\r\n }\r\n\r\n if (erroredKeys.size > 0) {\r\n return [ false, Object.fromEntries(erroredKeys) ];\r\n }\r\n\r\n return [ true, Object.fromEntries(erroredKeys) ];\r\n }\r\n\r\n getStringValue(optionName: string): string {\r\n if (!this.definiteConfig[optionName] === null) {\r\n throw new Error('Option ' + optionName + ' is not defined');\r\n }\r\n if (typeof this.definiteConfig[optionName] !== 'string') {\r\n throw new Error('Option ' + optionName + ' is not a string');\r\n }\r\n return this.definiteConfig[optionName];\r\n }\r\n\r\n getNumberValue(optionName: string): number {\r\n if (!this.definiteConfig[optionName] === null) {\r\n throw new Error('Option ' + optionName + ' is not defined');\r\n }\r\n if (typeof this.definiteConfig[optionName] !== 'number') {\r\n throw new Error('Option ' + optionName + ' is not a number');\r\n }\r\n return this.definiteConfig[optionName];\r\n }\r\n\r\n getBooleanValue(optionName: string): boolean {\r\n if (this.definiteConfig[optionName] === null) {\r\n throw new Error('Option ' + optionName + ' is not defined');\r\n }\r\n if (typeof this.definiteConfig[optionName] !== 'boolean') {\r\n throw new Error('Option ' + optionName + ' is not a boolean');\r\n }\r\n return this.definiteConfig[optionName];\r\n }\r\n}\r\n\r\nexport { ConfigurationFile, ConfigurationBuilder, BooleanOption, ConfigurationOption, ConfigurationOptionType, NumberOption, StringOption, isBooleanOption, isNumberOption, isStringOption };","export default class EventResponse<T> {\r\n data: T | undefined = undefined;\r\n deffered: boolean = false;\r\n resolved: boolean = false;\r\n progress: number = 0;\r\n logs: string[] = [];\r\n\r\n public defer() {\r\n this.deffered = true;\r\n }\r\n\r\n public resolve(data: T) {\r\n this.resolved = true;\r\n this.data = data;\r\n }\r\n\r\n public complete() {\r\n this.resolved = true;\r\n }\r\n\r\n public log(message: string) {\r\n this.logs.push(message);\r\n }\r\n\r\n \r\n}"],"mappings":"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","names":[]}
|