ogi-addon 1.9.2 → 1.9.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/Configuration-CdRZbO6z.d.mts +21 -0
- package/build/Configuration-WeOm-F0_.d.cts +21 -0
- package/build/ConfigurationBuilder-BSuJ4rSI.cjs +302 -0
- package/build/ConfigurationBuilder-BSuJ4rSI.cjs.map +1 -0
- package/build/ConfigurationBuilder-BbZDA_xx.d.mts +132 -0
- package/build/ConfigurationBuilder-CfHLKMTO.d.cts +132 -0
- package/build/EventResponse-CQhmdz3C.d.mts +430 -0
- package/build/EventResponse-D1c-Df5W.d.cts +430 -0
- package/build/EventResponse.cjs +55 -79
- package/build/EventResponse.cjs.map +1 -1
- package/build/EventResponse.d.cts +2 -45
- package/build/EventResponse.d.mts +2 -0
- package/build/EventResponse.mjs +58 -0
- package/build/EventResponse.mjs.map +1 -0
- package/build/SearchEngine-CRQWXfo6.d.mts +22 -0
- package/build/SearchEngine-DBSUNM4A.d.cts +22 -0
- package/build/SearchEngine.cjs +0 -19
- package/build/SearchEngine.d.cts +2 -20
- package/build/SearchEngine.d.mts +2 -0
- package/build/SearchEngine.mjs +1 -0
- package/build/config/Configuration.cjs +56 -370
- package/build/config/Configuration.cjs.map +1 -1
- package/build/config/Configuration.d.cts +3 -20
- package/build/config/Configuration.d.mts +3 -0
- package/build/config/Configuration.mjs +52 -0
- package/build/config/Configuration.mjs.map +1 -0
- package/build/config/ConfigurationBuilder.cjs +9 -292
- package/build/config/ConfigurationBuilder.d.cts +2 -130
- package/build/config/ConfigurationBuilder.d.mts +2 -0
- package/build/config/ConfigurationBuilder.mjs +221 -0
- package/build/config/ConfigurationBuilder.mjs.map +1 -0
- package/build/main.cjs +510 -1074
- package/build/main.cjs.map +1 -1
- package/build/main.d.cts +5 -385
- package/build/main.d.mts +5 -0
- package/build/main.mjs +510 -0
- package/build/main.mjs.map +1 -0
- package/package.json +9 -9
- package/src/config/Configuration.ts +18 -7
- package/src/main.ts +19 -12
- package/{tsup.config.js → tsdown.config.js} +2 -1
- package/build/EventResponse.d.ts +0 -45
- package/build/EventResponse.js +0 -62
- package/build/EventResponse.js.map +0 -1
- package/build/SearchEngine.cjs.map +0 -1
- package/build/SearchEngine.d.ts +0 -20
- package/build/SearchEngine.js +0 -1
- package/build/SearchEngine.js.map +0 -1
- package/build/config/Configuration.d.ts +0 -20
- package/build/config/Configuration.js +0 -329
- package/build/config/Configuration.js.map +0 -1
- package/build/config/ConfigurationBuilder.cjs.map +0 -1
- package/build/config/ConfigurationBuilder.d.ts +0 -130
- package/build/config/ConfigurationBuilder.js +0 -251
- package/build/config/ConfigurationBuilder.js.map +0 -1
- package/build/main.d.ts +0 -385
- package/build/main.js +0 -1045
- package/build/main.js.map +0 -1
package/build/main.cjs
CHANGED
|
@@ -1,1086 +1,522 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
-
}
|
|
18
|
-
return to;
|
|
19
|
-
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
1
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
|
+
const require_ConfigurationBuilder = require('./ConfigurationBuilder-BSuJ4rSI.cjs');
|
|
3
|
+
const require_EventResponse = require('./EventResponse.cjs');
|
|
4
|
+
const require_config_Configuration = require('./config/Configuration.cjs');
|
|
5
|
+
let ws = require("ws");
|
|
6
|
+
ws = require_ConfigurationBuilder.__toESM(ws);
|
|
7
|
+
let node_events = require("node:events");
|
|
8
|
+
node_events = require_ConfigurationBuilder.__toESM(node_events);
|
|
9
|
+
let zod = require("zod");
|
|
10
|
+
let fuse_js = require("fuse.js");
|
|
11
|
+
fuse_js = require_ConfigurationBuilder.__toESM(fuse_js);
|
|
12
|
+
let node_child_process = require("node:child_process");
|
|
13
|
+
let node_fs = require("node:fs");
|
|
14
|
+
node_fs = require_ConfigurationBuilder.__toESM(node_fs);
|
|
29
15
|
|
|
30
|
-
|
|
31
|
-
var
|
|
32
|
-
__export(main_exports, {
|
|
33
|
-
Configuration: () => Configuration,
|
|
34
|
-
ConfigurationBuilder: () => ConfigurationBuilder,
|
|
35
|
-
CustomTask: () => CustomTask,
|
|
36
|
-
EventResponse: () => EventResponse,
|
|
37
|
-
SearchTool: () => SearchTool,
|
|
38
|
-
VERSION: () => VERSION,
|
|
39
|
-
ZodLibraryInfo: () => ZodLibraryInfo,
|
|
40
|
-
default: () => OGIAddon
|
|
41
|
-
});
|
|
42
|
-
module.exports = __toCommonJS(main_exports);
|
|
43
|
-
var import_ws = __toESM(require("ws"), 1);
|
|
44
|
-
var import_node_events = __toESM(require("events"), 1);
|
|
45
|
-
|
|
46
|
-
// src/config/ConfigurationBuilder.ts
|
|
47
|
-
var import_zod = __toESM(require("zod"), 1);
|
|
48
|
-
var configValidation = import_zod.default.object({
|
|
49
|
-
name: import_zod.default.string().min(1),
|
|
50
|
-
displayName: import_zod.default.string().min(1),
|
|
51
|
-
description: import_zod.default.string().min(1)
|
|
52
|
-
});
|
|
53
|
-
var ConfigurationBuilder = class {
|
|
54
|
-
options = [];
|
|
55
|
-
/**
|
|
56
|
-
* Add a number option to the configuration builder and return the builder for chaining. You must provide a name, display name, and description for the option.
|
|
57
|
-
* @param option { (option: NumberOption) => NumberOption }
|
|
58
|
-
* @returns
|
|
59
|
-
*/
|
|
60
|
-
addNumberOption(option) {
|
|
61
|
-
let newOption = new NumberOption();
|
|
62
|
-
newOption = option(newOption);
|
|
63
|
-
this.options.push(newOption);
|
|
64
|
-
return this;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Add a string option to the configuration builder and return the builder for chaining. You must provide a name, display name, and description for the option.
|
|
68
|
-
* @param option { (option: StringOption) => StringOption }
|
|
69
|
-
*/
|
|
70
|
-
addStringOption(option) {
|
|
71
|
-
let newOption = new StringOption();
|
|
72
|
-
newOption = option(newOption);
|
|
73
|
-
this.options.push(newOption);
|
|
74
|
-
return this;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Add a boolean option to the configuration builder and return the builder for chaining. You must provide a name, display name, and description for the option.
|
|
78
|
-
* @param option { (option: BooleanOption) => BooleanOption }
|
|
79
|
-
*/
|
|
80
|
-
addBooleanOption(option) {
|
|
81
|
-
let newOption = new BooleanOption();
|
|
82
|
-
newOption = option(newOption);
|
|
83
|
-
this.options.push(newOption);
|
|
84
|
-
return this;
|
|
85
|
-
}
|
|
86
|
-
build(includeFunctions) {
|
|
87
|
-
let config = {};
|
|
88
|
-
this.options.forEach((option) => {
|
|
89
|
-
if (!includeFunctions) {
|
|
90
|
-
option = JSON.parse(JSON.stringify(option));
|
|
91
|
-
const optionData = configValidation.safeParse(option);
|
|
92
|
-
if (!optionData.success) {
|
|
93
|
-
throw new import_zod.ZodError(optionData.error.errors);
|
|
94
|
-
}
|
|
95
|
-
config[option.name] = option;
|
|
96
|
-
} else {
|
|
97
|
-
config[option.name] = option;
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
return config;
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
var ConfigurationOption = class {
|
|
104
|
-
name = "";
|
|
105
|
-
defaultValue = "";
|
|
106
|
-
displayName = "";
|
|
107
|
-
description = "";
|
|
108
|
-
type = "unset";
|
|
109
|
-
/**
|
|
110
|
-
* Set the name of the option. **REQUIRED**
|
|
111
|
-
* @param name {string} The name of the option. This is used to reference the option in the configuration file.
|
|
112
|
-
*/
|
|
113
|
-
setName(name) {
|
|
114
|
-
this.name = name;
|
|
115
|
-
return this;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Set the display name of the option. This is used to show the user a human readable version of what the option is. **REQUIRED**
|
|
119
|
-
* @param displayName {string} The display name of the option.
|
|
120
|
-
* @returns
|
|
121
|
-
*/
|
|
122
|
-
setDisplayName(displayName) {
|
|
123
|
-
this.displayName = displayName;
|
|
124
|
-
return this;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Set the description of the option. This is to show the user a brief description of what this option does. **REQUIRED**
|
|
128
|
-
* @param description {string} The description of the option.
|
|
129
|
-
* @returns
|
|
130
|
-
*/
|
|
131
|
-
setDescription(description) {
|
|
132
|
-
this.description = description;
|
|
133
|
-
return this;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Validation code for the option. This is called when the user provides input to the option. If the validation fails, the user will be prompted to provide input again.
|
|
137
|
-
* @param input {unknown} The input to validate
|
|
138
|
-
*/
|
|
139
|
-
validate(input) {
|
|
140
|
-
throw new Error("Validation code not implemented. Value: " + input);
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
var StringOption = class extends ConfigurationOption {
|
|
144
|
-
allowedValues = [];
|
|
145
|
-
minTextLength = 0;
|
|
146
|
-
maxTextLength = Number.MAX_SAFE_INTEGER;
|
|
147
|
-
defaultValue = "";
|
|
148
|
-
inputType = "text";
|
|
149
|
-
type = "string";
|
|
150
|
-
/**
|
|
151
|
-
* Set the allowed values for the string. If the array is empty, any value is allowed. When provided, the client will act like this option is a dropdown.
|
|
152
|
-
* @param allowedValues {string[]} An array of allowed values for the string. If the array is empty, any value is allowed.
|
|
153
|
-
*/
|
|
154
|
-
setAllowedValues(allowedValues) {
|
|
155
|
-
this.allowedValues = allowedValues;
|
|
156
|
-
return this;
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Set the default value for the string. This value will be used if the user does not provide a value. **HIGHLY RECOMMENDED**
|
|
160
|
-
* @param defaultValue {string} The default value for the string.
|
|
161
|
-
*/
|
|
162
|
-
setDefaultValue(defaultValue) {
|
|
163
|
-
this.defaultValue = defaultValue;
|
|
164
|
-
return this;
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Set the minimum text length for the string. If the user provides a string that is less than this value, the validation will fail.
|
|
168
|
-
* @param minTextLength {number} The minimum text length for the string.
|
|
169
|
-
*/
|
|
170
|
-
setMinTextLength(minTextLength) {
|
|
171
|
-
this.minTextLength = minTextLength;
|
|
172
|
-
return this;
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Set the maximum text length for the string. If the user provides a string that is greater than this value, the validation will fail.
|
|
176
|
-
* @param maxTextLength {number} The maximum text length for the string.
|
|
177
|
-
*/
|
|
178
|
-
setMaxTextLength(maxTextLength) {
|
|
179
|
-
this.maxTextLength = maxTextLength;
|
|
180
|
-
return this;
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Set the input type for the string. This will change how the client renders the input.
|
|
184
|
-
* @param inputType {'text' | 'file' | 'password' | 'folder'} The input type for the string.
|
|
185
|
-
*/
|
|
186
|
-
setInputType(inputType) {
|
|
187
|
-
this.inputType = inputType;
|
|
188
|
-
return this;
|
|
189
|
-
}
|
|
190
|
-
validate(input) {
|
|
191
|
-
if (typeof input !== "string") {
|
|
192
|
-
return [false, "Input is not a string"];
|
|
193
|
-
}
|
|
194
|
-
if (this.allowedValues.length === 0 && input.length !== 0)
|
|
195
|
-
return [true, ""];
|
|
196
|
-
if (input.length < this.minTextLength || input.length > this.maxTextLength) {
|
|
197
|
-
return [
|
|
198
|
-
false,
|
|
199
|
-
"Input is not within the text length " + this.minTextLength + " and " + this.maxTextLength + " characters (currently " + input.length + " characters)"
|
|
200
|
-
];
|
|
201
|
-
}
|
|
202
|
-
return [
|
|
203
|
-
this.allowedValues.includes(input),
|
|
204
|
-
"Input is not an allowed value"
|
|
205
|
-
];
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
var NumberOption = class extends ConfigurationOption {
|
|
209
|
-
min = 0;
|
|
210
|
-
max = Number.MAX_SAFE_INTEGER;
|
|
211
|
-
defaultValue = 0;
|
|
212
|
-
type = "number";
|
|
213
|
-
inputType = "number";
|
|
214
|
-
/**
|
|
215
|
-
* Set the minimum value for the number. If the user provides a number that is less than this value, the validation will fail.
|
|
216
|
-
* @param min {number} The minimum value for the number.
|
|
217
|
-
*/
|
|
218
|
-
setMin(min) {
|
|
219
|
-
this.min = min;
|
|
220
|
-
return this;
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Set the input type for the number. This will change how the client renders the input.
|
|
224
|
-
* @param type {'range' | 'number'} The input type for the number.
|
|
225
|
-
*/
|
|
226
|
-
setInputType(type) {
|
|
227
|
-
this.inputType = type;
|
|
228
|
-
return this;
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* Set the maximum value for the number. If the user provides a number that is greater than this value, the validation will fail.
|
|
232
|
-
* @param max {number} The maximum value for the number.
|
|
233
|
-
*/
|
|
234
|
-
setMax(max) {
|
|
235
|
-
this.max = max;
|
|
236
|
-
return this;
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Set the default value for the number. This value will be used if the user does not provide a value. **HIGHLY RECOMMENDED**
|
|
240
|
-
* @param defaultValue {number} The default value for the number.
|
|
241
|
-
*/
|
|
242
|
-
setDefaultValue(defaultValue) {
|
|
243
|
-
this.defaultValue = defaultValue;
|
|
244
|
-
return this;
|
|
245
|
-
}
|
|
246
|
-
validate(input) {
|
|
247
|
-
if (isNaN(Number(input))) {
|
|
248
|
-
return [false, "Input is not a number"];
|
|
249
|
-
}
|
|
250
|
-
if (Number(input) < this.min || Number(input) > this.max) {
|
|
251
|
-
return [
|
|
252
|
-
false,
|
|
253
|
-
"Input is not within the range of " + this.min + " and " + this.max
|
|
254
|
-
];
|
|
255
|
-
}
|
|
256
|
-
return [true, ""];
|
|
257
|
-
}
|
|
258
|
-
};
|
|
259
|
-
var BooleanOption = class extends ConfigurationOption {
|
|
260
|
-
type = "boolean";
|
|
261
|
-
defaultValue = false;
|
|
262
|
-
/**
|
|
263
|
-
* Set the default value for the boolean. This value will be used if the user does not provide a value. **HIGHLY RECOMMENDED**
|
|
264
|
-
* @param defaultValue {boolean} The default value for the boolean.
|
|
265
|
-
*/
|
|
266
|
-
setDefaultValue(defaultValue) {
|
|
267
|
-
this.defaultValue = defaultValue;
|
|
268
|
-
return this;
|
|
269
|
-
}
|
|
270
|
-
validate(input) {
|
|
271
|
-
if (typeof input !== "boolean") {
|
|
272
|
-
return [false, "Input is not a boolean"];
|
|
273
|
-
}
|
|
274
|
-
return [true, ""];
|
|
275
|
-
}
|
|
276
|
-
};
|
|
16
|
+
//#region package.json
|
|
17
|
+
var version = "1.9.4";
|
|
277
18
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
if (this.definiteConfig[key] === null || this.definiteConfig[key] === void 0) {
|
|
298
|
-
console.warn(
|
|
299
|
-
"Option " + key + " is not defined. Using default value Value: " + this.storedConfigTemplate[key].defaultValue
|
|
300
|
-
);
|
|
301
|
-
this.definiteConfig[key] = this.storedConfigTemplate[key].defaultValue;
|
|
302
|
-
}
|
|
303
|
-
if (this.storedConfigTemplate[key].type !== typeof this.definiteConfig[key]) {
|
|
304
|
-
throw new Error("Option " + key + " is not of the correct type");
|
|
305
|
-
}
|
|
306
|
-
const result = this.storedConfigTemplate[key].validate(
|
|
307
|
-
this.definiteConfig[key]
|
|
308
|
-
);
|
|
309
|
-
if (!result[0]) {
|
|
310
|
-
erroredKeys.set(key, result[1]);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
for (const key in this.definiteConfig) {
|
|
314
|
-
if (this.storedConfigTemplate[key] === void 0) {
|
|
315
|
-
delete this.definiteConfig[key];
|
|
316
|
-
console.warn(
|
|
317
|
-
"Option " + key + " is not defined in the configuration template. Removing from config."
|
|
318
|
-
);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
if (erroredKeys.size > 0) {
|
|
322
|
-
return [false, Object.fromEntries(erroredKeys)];
|
|
323
|
-
}
|
|
324
|
-
return [true, Object.fromEntries(erroredKeys)];
|
|
325
|
-
}
|
|
326
|
-
getStringValue(optionName) {
|
|
327
|
-
if (!this.definiteConfig[optionName] === null) {
|
|
328
|
-
throw new Error("Option " + optionName + " is not defined");
|
|
329
|
-
}
|
|
330
|
-
if (typeof this.definiteConfig[optionName] !== "string") {
|
|
331
|
-
throw new Error("Option " + optionName + " is not a string");
|
|
332
|
-
}
|
|
333
|
-
return this.definiteConfig[optionName];
|
|
334
|
-
}
|
|
335
|
-
getNumberValue(optionName) {
|
|
336
|
-
if (!this.definiteConfig[optionName] === null) {
|
|
337
|
-
throw new Error("Option " + optionName + " is not defined");
|
|
338
|
-
}
|
|
339
|
-
if (typeof this.definiteConfig[optionName] !== "number") {
|
|
340
|
-
throw new Error("Option " + optionName + " is not a number");
|
|
341
|
-
}
|
|
342
|
-
return this.definiteConfig[optionName];
|
|
343
|
-
}
|
|
344
|
-
getBooleanValue(optionName) {
|
|
345
|
-
if (this.definiteConfig[optionName] === null) {
|
|
346
|
-
throw new Error("Option " + optionName + " is not defined");
|
|
347
|
-
}
|
|
348
|
-
if (typeof this.definiteConfig[optionName] !== "boolean") {
|
|
349
|
-
throw new Error("Option " + optionName + " is not a boolean");
|
|
350
|
-
}
|
|
351
|
-
return this.definiteConfig[optionName];
|
|
352
|
-
}
|
|
353
|
-
};
|
|
354
|
-
|
|
355
|
-
// src/EventResponse.ts
|
|
356
|
-
var EventResponse = class {
|
|
357
|
-
data = void 0;
|
|
358
|
-
deffered = false;
|
|
359
|
-
resolved = false;
|
|
360
|
-
progress = 0;
|
|
361
|
-
logs = [];
|
|
362
|
-
failed = void 0;
|
|
363
|
-
onInputAsked;
|
|
364
|
-
constructor(onInputAsked) {
|
|
365
|
-
this.onInputAsked = onInputAsked;
|
|
366
|
-
}
|
|
367
|
-
defer(promise) {
|
|
368
|
-
this.deffered = true;
|
|
369
|
-
if (promise) {
|
|
370
|
-
promise();
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
/**
|
|
374
|
-
* Resolve the event with data. This acts like a promise resolve, and will stop the event from being processed further. **You must always call this method when you are done with the event.**
|
|
375
|
-
* @param data {T}
|
|
376
|
-
*/
|
|
377
|
-
resolve(data) {
|
|
378
|
-
this.resolved = true;
|
|
379
|
-
this.data = data;
|
|
380
|
-
}
|
|
381
|
-
/**
|
|
382
|
-
* Completes the event and resolves it, but does not return any data. **You must always call this method when you are done with the event.**
|
|
383
|
-
*/
|
|
384
|
-
complete() {
|
|
385
|
-
this.resolved = true;
|
|
386
|
-
}
|
|
387
|
-
fail(message) {
|
|
388
|
-
this.resolved = true;
|
|
389
|
-
this.failed = message;
|
|
390
|
-
}
|
|
391
|
-
/**
|
|
392
|
-
* Logs a message to the event. This is useful for debugging and logging information to the user.
|
|
393
|
-
* @param message {string}
|
|
394
|
-
*/
|
|
395
|
-
log(message) {
|
|
396
|
-
this.logs.push(message);
|
|
397
|
-
}
|
|
398
|
-
/**
|
|
399
|
-
* Send a screen to the client to ask for input. Use the `ConfigurationBuilder` system to build the screen. Once sent to the user, the addon cannot change the screen.
|
|
400
|
-
* @async
|
|
401
|
-
* @param name {string}
|
|
402
|
-
* @param description {string}
|
|
403
|
-
* @param screen {ConfigurationBuilder}
|
|
404
|
-
* @returns {Promise<{ [key: string]: boolean | string | number }>}
|
|
405
|
-
*/
|
|
406
|
-
async askForInput(name, description, screen) {
|
|
407
|
-
if (!this.onInputAsked) {
|
|
408
|
-
throw new Error("No input asked callback");
|
|
409
|
-
}
|
|
410
|
-
return await this.onInputAsked(screen, name, description);
|
|
411
|
-
}
|
|
412
|
-
};
|
|
413
|
-
|
|
414
|
-
// src/main.ts
|
|
415
|
-
var import_fuse = __toESM(require("fuse.js"), 1);
|
|
416
|
-
|
|
417
|
-
// package.json
|
|
418
|
-
var package_default = {
|
|
419
|
-
name: "ogi-addon",
|
|
420
|
-
module: "./build/main.js",
|
|
421
|
-
type: "module",
|
|
422
|
-
main: "./build/main.cjs",
|
|
423
|
-
version: "1.9.2",
|
|
424
|
-
exports: {
|
|
425
|
-
".": {
|
|
426
|
-
import: {
|
|
427
|
-
default: "./build/main.js",
|
|
428
|
-
types: "./build/main.d.ts"
|
|
429
|
-
},
|
|
430
|
-
require: {
|
|
431
|
-
default: "./build/main.cjs",
|
|
432
|
-
types: "./build/main.d.cts"
|
|
433
|
-
}
|
|
434
|
-
},
|
|
435
|
-
"./config": {
|
|
436
|
-
import: {
|
|
437
|
-
default: "./build/config/Configuration.js",
|
|
438
|
-
types: "./build/config/Configuration.d.ts"
|
|
439
|
-
},
|
|
440
|
-
require: {
|
|
441
|
-
default: "./build/config/Configuration.cjs",
|
|
442
|
-
types: "./build/config/Configuration.d.cts"
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
},
|
|
446
|
-
typings: "./build/main.d.ts",
|
|
447
|
-
author: {
|
|
448
|
-
name: "Nat3z",
|
|
449
|
-
email: "me@nat3z.com",
|
|
450
|
-
url: "https://nat3z.com/"
|
|
451
|
-
},
|
|
452
|
-
repository: {
|
|
453
|
-
type: "git",
|
|
454
|
-
url: "https://github.com/Nat3z/OpenGameInstaller",
|
|
455
|
-
directory: "packages/ogi-addon"
|
|
456
|
-
},
|
|
457
|
-
dependencies: {
|
|
458
|
-
"fuse.js": "^7.1.0",
|
|
459
|
-
ws: "^8.4.0",
|
|
460
|
-
zod: "^3.23.8"
|
|
461
|
-
},
|
|
462
|
-
scripts: {
|
|
463
|
-
"auto-build": "tsc -w",
|
|
464
|
-
build: "tsup --config tsup.config.js",
|
|
465
|
-
release: "bun run build && npm publish",
|
|
466
|
-
"release-beta": "bun run build && npm publish --tag future"
|
|
467
|
-
},
|
|
468
|
-
devDependencies: {
|
|
469
|
-
"@types/minimatch": "^6.0.0",
|
|
470
|
-
"@types/node": "^20.14.12",
|
|
471
|
-
"@types/ws": "^8.4.0",
|
|
472
|
-
prettier: "^3.6.0",
|
|
473
|
-
tsup: "^8.2.3",
|
|
474
|
-
typescript: "^5.0.0"
|
|
475
|
-
}
|
|
476
|
-
};
|
|
477
|
-
|
|
478
|
-
// src/main.ts
|
|
479
|
-
var import_node_child_process = require("child_process");
|
|
480
|
-
var import_node_fs = __toESM(require("fs"), 1);
|
|
481
|
-
var import_zod2 = require("zod");
|
|
482
|
-
var defaultPort = 7654;
|
|
483
|
-
var VERSION = package_default.version;
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/main.ts
|
|
21
|
+
const defaultPort = 7654;
|
|
22
|
+
const VERSION = version;
|
|
23
|
+
/**
|
|
24
|
+
* The main class for the OGI Addon. This class is used to interact with the OGI Addon Server. The OGI Addon Server provides a `--addonSecret` to the addon so it can securely connect.
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* const addon = new OGIAddon({
|
|
28
|
+
* name: 'Test Addon',
|
|
29
|
+
* id: 'test-addon',
|
|
30
|
+
* description: 'A test addon',
|
|
31
|
+
* version: '1.0.0',
|
|
32
|
+
* author: 'OGI Developers',
|
|
33
|
+
* repository: ''
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
*/
|
|
484
38
|
var OGIAddon = class {
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
console.log(`[unrar stdout]: ${data}`);
|
|
646
|
-
});
|
|
647
|
-
unrarProcess.stderr.on("data", (data) => {
|
|
648
|
-
console.error(`[unrar stderr]: ${data}`);
|
|
649
|
-
});
|
|
650
|
-
unrarProcess.on("close", (code) => {
|
|
651
|
-
if (code !== 0) {
|
|
652
|
-
console.error(`unrar process exited with code ${code}`);
|
|
653
|
-
reject(new Error("Failed to extract RAR file"));
|
|
654
|
-
return;
|
|
655
|
-
}
|
|
656
|
-
resolve();
|
|
657
|
-
});
|
|
658
|
-
}
|
|
659
|
-
} else {
|
|
660
|
-
reject(new Error("Unknown extraction type"));
|
|
661
|
-
}
|
|
662
|
-
});
|
|
663
|
-
}
|
|
39
|
+
eventEmitter = new node_events.default.EventEmitter();
|
|
40
|
+
addonWSListener;
|
|
41
|
+
addonInfo;
|
|
42
|
+
config = new require_config_Configuration.Configuration({});
|
|
43
|
+
eventsAvailable = [];
|
|
44
|
+
registeredConnectEvent = false;
|
|
45
|
+
constructor(addonInfo) {
|
|
46
|
+
this.addonInfo = addonInfo;
|
|
47
|
+
this.addonWSListener = new OGIAddonWSListener(this, this.eventEmitter);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Register an event listener for the addon. (See EventListenerTypes)
|
|
51
|
+
* @param event {OGIAddonEvent}
|
|
52
|
+
* @param listener {EventListenerTypes[OGIAddonEvent]}
|
|
53
|
+
*/
|
|
54
|
+
on(event, listener) {
|
|
55
|
+
this.eventEmitter.on(event, listener);
|
|
56
|
+
this.eventsAvailable.push(event);
|
|
57
|
+
if (!this.registeredConnectEvent) {
|
|
58
|
+
this.addonWSListener.eventEmitter.once("connect", () => {
|
|
59
|
+
this.addonWSListener.send("flag", {
|
|
60
|
+
flag: "events-available",
|
|
61
|
+
value: this.eventsAvailable
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
this.registeredConnectEvent = true;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
emit(event, ...args) {
|
|
68
|
+
this.eventEmitter.emit(event, ...args);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Notify the client using a notification. Provide the type of notification, the message, and an ID.
|
|
72
|
+
* @param notification {Notification}
|
|
73
|
+
*/
|
|
74
|
+
notify(notification) {
|
|
75
|
+
this.addonWSListener.send("notification", [notification]);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Get the app details for a given appID and storefront.
|
|
79
|
+
* @param appID {number}
|
|
80
|
+
* @param storefront {string}
|
|
81
|
+
* @returns {Promise<StoreData>}
|
|
82
|
+
*/
|
|
83
|
+
async getAppDetails(appID, storefront) {
|
|
84
|
+
const id = this.addonWSListener.send("get-app-details", {
|
|
85
|
+
appID,
|
|
86
|
+
storefront
|
|
87
|
+
});
|
|
88
|
+
return await this.addonWSListener.waitForResponseFromServer(id);
|
|
89
|
+
}
|
|
90
|
+
async searchGame(query, storefront) {
|
|
91
|
+
const id = this.addonWSListener.send("search-app-name", {
|
|
92
|
+
query,
|
|
93
|
+
storefront
|
|
94
|
+
});
|
|
95
|
+
return await this.addonWSListener.waitForResponseFromServer(id);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Notify the OGI Addon Server that you are performing a background task. This can be used to help users understand what is happening in the background.
|
|
99
|
+
* @param id {string}
|
|
100
|
+
* @param progress {number}
|
|
101
|
+
* @param logs {string[]}
|
|
102
|
+
*/
|
|
103
|
+
async task() {
|
|
104
|
+
const id = Math.random().toString(36).substring(7);
|
|
105
|
+
const progress = 0;
|
|
106
|
+
const logs = [];
|
|
107
|
+
const task = new CustomTask(this.addonWSListener, id, progress, logs);
|
|
108
|
+
this.addonWSListener.send("task-update", {
|
|
109
|
+
id,
|
|
110
|
+
progress,
|
|
111
|
+
logs,
|
|
112
|
+
finished: false,
|
|
113
|
+
failed: void 0
|
|
114
|
+
});
|
|
115
|
+
return task;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Extract a file using 7-Zip on Windows, unzip on Linux/Mac.
|
|
119
|
+
* @param path {string}
|
|
120
|
+
* @param outputPath {string}
|
|
121
|
+
* @param type {'unrar' | 'unzip'}
|
|
122
|
+
* @returns {Promise<void>}
|
|
123
|
+
*/
|
|
124
|
+
async extractFile(path, outputPath, type) {
|
|
125
|
+
return new Promise((resolve, reject) => {
|
|
126
|
+
if (!node_fs.default.existsSync(outputPath)) node_fs.default.mkdirSync(outputPath, { recursive: true });
|
|
127
|
+
if (type === "unzip") if (process.platform === "win32") (0, node_child_process.exec)(`"C:\\Program Files\\7-Zip\\7z.exe" x "${path}" -o"${outputPath}"`, (err, stdout, stderr) => {
|
|
128
|
+
if (err) {
|
|
129
|
+
console.error(err);
|
|
130
|
+
console.log(stderr);
|
|
131
|
+
reject(/* @__PURE__ */ new Error("Failed to extract ZIP file"));
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
console.log(stdout);
|
|
135
|
+
console.log(stderr);
|
|
136
|
+
resolve();
|
|
137
|
+
});
|
|
138
|
+
else {
|
|
139
|
+
const unzipProcess = (0, node_child_process.spawn)("unzip", [
|
|
140
|
+
"-o",
|
|
141
|
+
path,
|
|
142
|
+
"-d",
|
|
143
|
+
outputPath
|
|
144
|
+
], { env: {
|
|
145
|
+
...process.env,
|
|
146
|
+
UNZIP_DISABLE_ZIPBOMB_DETECTION: "TRUE"
|
|
147
|
+
} });
|
|
148
|
+
unzipProcess.stdout.on("data", (data) => {
|
|
149
|
+
console.log(`[unzip stdout]: ${data}`);
|
|
150
|
+
});
|
|
151
|
+
unzipProcess.stderr.on("data", (data) => {
|
|
152
|
+
console.error(`[unzip stderr]: ${data}`);
|
|
153
|
+
});
|
|
154
|
+
unzipProcess.on("close", (code) => {
|
|
155
|
+
if (code !== 0) {
|
|
156
|
+
console.error(`unzip process exited with code ${code}`);
|
|
157
|
+
reject(/* @__PURE__ */ new Error("Failed to extract ZIP file"));
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
resolve();
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
else if (type === "unrar") if (process.platform === "win32") (0, node_child_process.exec)(`"C:\\Program Files\\7-Zip\\7z.exe" x "${path}" -o"${outputPath}"`, (err, stdout, stderr) => {
|
|
164
|
+
if (err) {
|
|
165
|
+
console.error(err);
|
|
166
|
+
console.log(stderr);
|
|
167
|
+
reject(/* @__PURE__ */ new Error("Failed to extract RAR file"));
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
console.log(stdout);
|
|
171
|
+
console.log(stderr);
|
|
172
|
+
resolve();
|
|
173
|
+
});
|
|
174
|
+
else {
|
|
175
|
+
const unrarProcess = (0, node_child_process.spawn)("unrar", [
|
|
176
|
+
"x",
|
|
177
|
+
"-y",
|
|
178
|
+
path,
|
|
179
|
+
outputPath
|
|
180
|
+
]);
|
|
181
|
+
unrarProcess.stdout.on("data", (data) => {
|
|
182
|
+
console.log(`[unrar stdout]: ${data}`);
|
|
183
|
+
});
|
|
184
|
+
unrarProcess.stderr.on("data", (data) => {
|
|
185
|
+
console.error(`[unrar stderr]: ${data}`);
|
|
186
|
+
});
|
|
187
|
+
unrarProcess.on("close", (code) => {
|
|
188
|
+
if (code !== 0) {
|
|
189
|
+
console.error(`unrar process exited with code ${code}`);
|
|
190
|
+
reject(/* @__PURE__ */ new Error("Failed to extract RAR file"));
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
resolve();
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
else reject(/* @__PURE__ */ new Error("Unknown extraction type"));
|
|
197
|
+
});
|
|
198
|
+
}
|
|
664
199
|
};
|
|
665
200
|
var CustomTask = class {
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
201
|
+
id;
|
|
202
|
+
progress;
|
|
203
|
+
logs;
|
|
204
|
+
finished = false;
|
|
205
|
+
ws;
|
|
206
|
+
failed = void 0;
|
|
207
|
+
constructor(ws$2, id, progress, logs) {
|
|
208
|
+
this.id = id;
|
|
209
|
+
this.progress = progress;
|
|
210
|
+
this.logs = logs;
|
|
211
|
+
this.ws = ws$2;
|
|
212
|
+
}
|
|
213
|
+
log(log) {
|
|
214
|
+
this.logs.push(log);
|
|
215
|
+
this.update();
|
|
216
|
+
}
|
|
217
|
+
finish() {
|
|
218
|
+
this.finished = true;
|
|
219
|
+
this.update();
|
|
220
|
+
}
|
|
221
|
+
fail(message) {
|
|
222
|
+
this.failed = message;
|
|
223
|
+
this.update();
|
|
224
|
+
}
|
|
225
|
+
setProgress(progress) {
|
|
226
|
+
this.progress = progress;
|
|
227
|
+
this.update();
|
|
228
|
+
}
|
|
229
|
+
update() {
|
|
230
|
+
this.ws.send("task-update", {
|
|
231
|
+
id: this.id,
|
|
232
|
+
progress: this.progress,
|
|
233
|
+
logs: this.logs,
|
|
234
|
+
finished: this.finished,
|
|
235
|
+
failed: this.failed
|
|
236
|
+
});
|
|
237
|
+
}
|
|
703
238
|
};
|
|
239
|
+
/**
|
|
240
|
+
* A search tool wrapper over Fuse.js for the OGI Addon. This tool is used to search for items in the library.
|
|
241
|
+
* @example
|
|
242
|
+
* ```typescript
|
|
243
|
+
* const searchTool = new SearchTool<LibraryInfo>([{ name: 'test', appID: 123 }, { name: 'test2', appID: 124 }], ['name']);
|
|
244
|
+
* const results = searchTool.search('test', 10);
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
704
247
|
var SearchTool = class {
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
248
|
+
fuse;
|
|
249
|
+
constructor(items, keys, options = {
|
|
250
|
+
threshold: .3,
|
|
251
|
+
includeScore: true
|
|
252
|
+
}) {
|
|
253
|
+
this.fuse = new fuse_js.default(items, {
|
|
254
|
+
keys,
|
|
255
|
+
...options
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
search(query, limit = 10) {
|
|
259
|
+
return this.fuse.search(query).slice(0, limit).map((result) => result.item);
|
|
260
|
+
}
|
|
261
|
+
addItems(items) {
|
|
262
|
+
items.map((item) => this.fuse.add(item));
|
|
263
|
+
}
|
|
721
264
|
};
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
265
|
+
/**
|
|
266
|
+
* Library Info is the metadata for a library entry after setting up a game.
|
|
267
|
+
*/
|
|
268
|
+
const ZodLibraryInfo = zod.z.object({
|
|
269
|
+
name: zod.z.string(),
|
|
270
|
+
version: zod.z.string(),
|
|
271
|
+
cwd: zod.z.string(),
|
|
272
|
+
appID: zod.z.number(),
|
|
273
|
+
launchExecutable: zod.z.string(),
|
|
274
|
+
launchArguments: zod.z.string().optional(),
|
|
275
|
+
capsuleImage: zod.z.string(),
|
|
276
|
+
storefront: zod.z.string(),
|
|
277
|
+
addonsource: zod.z.string(),
|
|
278
|
+
coverImage: zod.z.string(),
|
|
279
|
+
titleImage: zod.z.string().optional()
|
|
734
280
|
});
|
|
735
281
|
var OGIAddonWSListener = class {
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
this.respondToMessage(message.id, void 0, requestDLEvent);
|
|
966
|
-
break;
|
|
967
|
-
}
|
|
968
|
-
if (requestDLEvent.data === void 0 || requestDLEvent.data?.downloadType === "request") {
|
|
969
|
-
throw new Error(
|
|
970
|
-
"Request DL event did not return a valid result. Please ensure that the event does not resolve with another `request` download type."
|
|
971
|
-
);
|
|
972
|
-
}
|
|
973
|
-
this.respondToMessage(
|
|
974
|
-
message.id,
|
|
975
|
-
requestDLResult.data,
|
|
976
|
-
requestDLEvent
|
|
977
|
-
);
|
|
978
|
-
break;
|
|
979
|
-
case "catalog":
|
|
980
|
-
let catalogEvent = new EventResponse();
|
|
981
|
-
this.eventEmitter.emit("catalog", catalogEvent);
|
|
982
|
-
const catalogResult = await this.waitForEventToRespond(catalogEvent);
|
|
983
|
-
this.respondToMessage(message.id, catalogResult.data, catalogEvent);
|
|
984
|
-
break;
|
|
985
|
-
case "task-run": {
|
|
986
|
-
let taskRunEvent = new EventResponse(
|
|
987
|
-
(screen, name, description) => this.userInputAsked(screen, name, description, this.socket)
|
|
988
|
-
);
|
|
989
|
-
this.eventEmitter.emit("task-run", message.args, taskRunEvent);
|
|
990
|
-
const interval = setInterval(() => {
|
|
991
|
-
if (taskRunEvent.resolved) {
|
|
992
|
-
clearInterval(interval);
|
|
993
|
-
return;
|
|
994
|
-
}
|
|
995
|
-
this.send("defer-update", {
|
|
996
|
-
logs: taskRunEvent.logs,
|
|
997
|
-
deferID: message.args.deferID,
|
|
998
|
-
progress: taskRunEvent.progress,
|
|
999
|
-
failed: taskRunEvent.failed
|
|
1000
|
-
});
|
|
1001
|
-
}, 100);
|
|
1002
|
-
const taskRunResult = await this.waitForEventToRespond(taskRunEvent);
|
|
1003
|
-
this.respondToMessage(message.id, taskRunResult.data, taskRunEvent);
|
|
1004
|
-
break;
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1007
|
-
});
|
|
1008
|
-
}
|
|
1009
|
-
waitForEventToRespond(event) {
|
|
1010
|
-
return new Promise((resolve, reject) => {
|
|
1011
|
-
const dataGet = setInterval(() => {
|
|
1012
|
-
if (event.resolved) {
|
|
1013
|
-
resolve(event);
|
|
1014
|
-
clearTimeout(timeout);
|
|
1015
|
-
}
|
|
1016
|
-
}, 5);
|
|
1017
|
-
const timeout = setTimeout(() => {
|
|
1018
|
-
if (event.deffered) {
|
|
1019
|
-
clearInterval(dataGet);
|
|
1020
|
-
const interval = setInterval(() => {
|
|
1021
|
-
if (event.resolved) {
|
|
1022
|
-
clearInterval(interval);
|
|
1023
|
-
resolve(event);
|
|
1024
|
-
}
|
|
1025
|
-
}, 100);
|
|
1026
|
-
} else {
|
|
1027
|
-
reject("Event did not respond in time");
|
|
1028
|
-
}
|
|
1029
|
-
}, 5e3);
|
|
1030
|
-
});
|
|
1031
|
-
}
|
|
1032
|
-
respondToMessage(messageID, response, originalEvent) {
|
|
1033
|
-
this.socket.send(
|
|
1034
|
-
JSON.stringify({
|
|
1035
|
-
event: "response",
|
|
1036
|
-
id: messageID,
|
|
1037
|
-
args: response,
|
|
1038
|
-
statusError: originalEvent ? originalEvent.failed : void 0
|
|
1039
|
-
})
|
|
1040
|
-
);
|
|
1041
|
-
console.log("dispatched response to " + messageID);
|
|
1042
|
-
}
|
|
1043
|
-
waitForResponseFromServer(messageID) {
|
|
1044
|
-
return new Promise((resolve) => {
|
|
1045
|
-
const waiter = (data) => {
|
|
1046
|
-
const message = JSON.parse(data);
|
|
1047
|
-
if (message.event !== "response") {
|
|
1048
|
-
this.socket.once("message", waiter);
|
|
1049
|
-
return;
|
|
1050
|
-
}
|
|
1051
|
-
console.log("received response from " + messageID);
|
|
1052
|
-
if (message.id === messageID) {
|
|
1053
|
-
resolve(message.args);
|
|
1054
|
-
} else {
|
|
1055
|
-
this.socket.once("message", waiter);
|
|
1056
|
-
}
|
|
1057
|
-
};
|
|
1058
|
-
this.socket.once("message", waiter);
|
|
1059
|
-
});
|
|
1060
|
-
}
|
|
1061
|
-
send(event, args) {
|
|
1062
|
-
const id = Math.random().toString(36).substring(7);
|
|
1063
|
-
this.socket.send(
|
|
1064
|
-
JSON.stringify({
|
|
1065
|
-
event,
|
|
1066
|
-
args,
|
|
1067
|
-
id
|
|
1068
|
-
})
|
|
1069
|
-
);
|
|
1070
|
-
return id;
|
|
1071
|
-
}
|
|
1072
|
-
close() {
|
|
1073
|
-
this.socket.close();
|
|
1074
|
-
}
|
|
282
|
+
socket;
|
|
283
|
+
eventEmitter;
|
|
284
|
+
addon;
|
|
285
|
+
constructor(ogiAddon, eventEmitter) {
|
|
286
|
+
if (process.argv[process.argv.length - 1].split("=")[0] !== "--addonSecret") throw new Error("No secret provided. This usually happens because the addon was not started by the OGI Addon Server.");
|
|
287
|
+
this.addon = ogiAddon;
|
|
288
|
+
this.eventEmitter = eventEmitter;
|
|
289
|
+
this.socket = new ws.default("ws://localhost:" + defaultPort);
|
|
290
|
+
this.socket.on("open", () => {
|
|
291
|
+
console.log("Connected to OGI Addon Server");
|
|
292
|
+
console.log("OGI Addon Server Version:", VERSION);
|
|
293
|
+
this.send("authenticate", {
|
|
294
|
+
...this.addon.addonInfo,
|
|
295
|
+
secret: process.argv[process.argv.length - 1].split("=")[1],
|
|
296
|
+
ogiVersion: VERSION
|
|
297
|
+
});
|
|
298
|
+
let configBuilder = new require_ConfigurationBuilder.ConfigurationBuilder();
|
|
299
|
+
this.eventEmitter.emit("configure", configBuilder);
|
|
300
|
+
this.send("configure", configBuilder.build(false));
|
|
301
|
+
this.addon.config = new require_config_Configuration.Configuration(configBuilder.build(true));
|
|
302
|
+
const configListener = (event) => {
|
|
303
|
+
if (event === void 0) return;
|
|
304
|
+
let data;
|
|
305
|
+
if (typeof event === "string") data = event;
|
|
306
|
+
else if (event instanceof Buffer) data = event.toString();
|
|
307
|
+
else if (event && typeof event.data === "string") data = event.data;
|
|
308
|
+
else if (event && event.data instanceof Buffer) data = event.data.toString();
|
|
309
|
+
else data = event.toString();
|
|
310
|
+
if (JSON.parse(data).event === "config-update") {
|
|
311
|
+
console.log("Config update received");
|
|
312
|
+
this.socket.off("message", configListener);
|
|
313
|
+
this.eventEmitter.emit("connect", new require_EventResponse((screen, name, description) => {
|
|
314
|
+
return this.userInputAsked(screen, name, description, this.socket);
|
|
315
|
+
}));
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
this.socket.on("message", configListener);
|
|
319
|
+
});
|
|
320
|
+
this.socket.on("error", (error) => {
|
|
321
|
+
if (error.message.includes("Failed to connect")) throw new Error("OGI Addon Server is not running/is unreachable. Please start the server and try again.");
|
|
322
|
+
console.error("An error occurred:", error);
|
|
323
|
+
});
|
|
324
|
+
this.socket.on("close", (code, reason) => {
|
|
325
|
+
if (code === 1008) {
|
|
326
|
+
console.error("Authentication failed:", reason);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
this.eventEmitter.emit("disconnect", reason);
|
|
330
|
+
console.log("Disconnected from OGI Addon Server");
|
|
331
|
+
console.error(reason.toString());
|
|
332
|
+
this.eventEmitter.emit("exit");
|
|
333
|
+
this.socket.close();
|
|
334
|
+
});
|
|
335
|
+
this.registerMessageReceiver();
|
|
336
|
+
}
|
|
337
|
+
async userInputAsked(configBuilt, name, description, socket) {
|
|
338
|
+
const config = configBuilt.build(false);
|
|
339
|
+
const id = Math.random().toString(36).substring(7);
|
|
340
|
+
if (!socket) return {};
|
|
341
|
+
socket.send(JSON.stringify({
|
|
342
|
+
event: "input-asked",
|
|
343
|
+
args: {
|
|
344
|
+
config,
|
|
345
|
+
name,
|
|
346
|
+
description
|
|
347
|
+
},
|
|
348
|
+
id
|
|
349
|
+
}));
|
|
350
|
+
return await this.waitForResponseFromServer(id);
|
|
351
|
+
}
|
|
352
|
+
registerMessageReceiver() {
|
|
353
|
+
this.socket.on("message", async (data) => {
|
|
354
|
+
const message = JSON.parse(data);
|
|
355
|
+
switch (message.event) {
|
|
356
|
+
case "config-update":
|
|
357
|
+
const result = this.addon.config.updateConfig(message.args);
|
|
358
|
+
if (!result[0]) this.respondToMessage(message.id, {
|
|
359
|
+
success: false,
|
|
360
|
+
error: result[1]
|
|
361
|
+
}, void 0);
|
|
362
|
+
else this.respondToMessage(message.id, { success: true }, void 0);
|
|
363
|
+
break;
|
|
364
|
+
case "search":
|
|
365
|
+
let searchResultEvent = new require_EventResponse((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
366
|
+
this.eventEmitter.emit("search", message.args, searchResultEvent);
|
|
367
|
+
const searchResult = await this.waitForEventToRespond(searchResultEvent);
|
|
368
|
+
this.respondToMessage(message.id, searchResult.data, searchResultEvent);
|
|
369
|
+
break;
|
|
370
|
+
case "setup": {
|
|
371
|
+
let setupEvent = new require_EventResponse((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
372
|
+
this.eventEmitter.emit("setup", message.args, setupEvent);
|
|
373
|
+
const interval = setInterval(() => {
|
|
374
|
+
if (setupEvent.resolved) {
|
|
375
|
+
clearInterval(interval);
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
this.send("defer-update", {
|
|
379
|
+
logs: setupEvent.logs,
|
|
380
|
+
deferID: message.args.deferID,
|
|
381
|
+
progress: setupEvent.progress,
|
|
382
|
+
failed: setupEvent.failed
|
|
383
|
+
});
|
|
384
|
+
}, 100);
|
|
385
|
+
const setupResult = await this.waitForEventToRespond(setupEvent);
|
|
386
|
+
this.respondToMessage(message.id, setupResult.data, setupEvent);
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
389
|
+
case "library-search":
|
|
390
|
+
let librarySearchEvent = new require_EventResponse((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
391
|
+
this.eventEmitter.emit("library-search", message.args, librarySearchEvent);
|
|
392
|
+
const librarySearchResult = await this.waitForEventToRespond(librarySearchEvent);
|
|
393
|
+
this.respondToMessage(message.id, librarySearchResult.data, librarySearchEvent);
|
|
394
|
+
break;
|
|
395
|
+
case "game-details":
|
|
396
|
+
let gameDetailsEvent = new require_EventResponse((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
397
|
+
if (this.eventEmitter.listenerCount("game-details") === 0) {
|
|
398
|
+
this.respondToMessage(message.id, { error: "No event listener for game-details" }, gameDetailsEvent);
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
this.eventEmitter.emit("game-details", message.args, gameDetailsEvent);
|
|
402
|
+
const gameDetailsResult = await this.waitForEventToRespond(gameDetailsEvent);
|
|
403
|
+
this.respondToMessage(message.id, gameDetailsResult.data, gameDetailsEvent);
|
|
404
|
+
break;
|
|
405
|
+
case "check-for-updates":
|
|
406
|
+
let checkForUpdatesEvent = new require_EventResponse((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
407
|
+
this.eventEmitter.emit("check-for-updates", message.args, checkForUpdatesEvent);
|
|
408
|
+
const checkForUpdatesResult = await this.waitForEventToRespond(checkForUpdatesEvent);
|
|
409
|
+
this.respondToMessage(message.id, checkForUpdatesResult.data, checkForUpdatesEvent);
|
|
410
|
+
break;
|
|
411
|
+
case "request-dl":
|
|
412
|
+
let requestDLEvent = new require_EventResponse((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
413
|
+
if (this.eventEmitter.listenerCount("request-dl") === 0) {
|
|
414
|
+
this.respondToMessage(message.id, { error: "No event listener for request-dl" }, requestDLEvent);
|
|
415
|
+
break;
|
|
416
|
+
}
|
|
417
|
+
this.eventEmitter.emit("request-dl", message.args.appID, message.args.info, requestDLEvent);
|
|
418
|
+
const requestDLResult = await this.waitForEventToRespond(requestDLEvent);
|
|
419
|
+
if (requestDLEvent.failed) {
|
|
420
|
+
this.respondToMessage(message.id, void 0, requestDLEvent);
|
|
421
|
+
break;
|
|
422
|
+
}
|
|
423
|
+
if (requestDLEvent.data === void 0 || requestDLEvent.data?.downloadType === "request") throw new Error("Request DL event did not return a valid result. Please ensure that the event does not resolve with another `request` download type.");
|
|
424
|
+
this.respondToMessage(message.id, requestDLResult.data, requestDLEvent);
|
|
425
|
+
break;
|
|
426
|
+
case "catalog":
|
|
427
|
+
let catalogEvent = new require_EventResponse();
|
|
428
|
+
this.eventEmitter.emit("catalog", catalogEvent);
|
|
429
|
+
const catalogResult = await this.waitForEventToRespond(catalogEvent);
|
|
430
|
+
this.respondToMessage(message.id, catalogResult.data, catalogEvent);
|
|
431
|
+
break;
|
|
432
|
+
case "task-run": {
|
|
433
|
+
let taskRunEvent = new require_EventResponse((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
434
|
+
this.eventEmitter.emit("task-run", message.args, taskRunEvent);
|
|
435
|
+
const interval = setInterval(() => {
|
|
436
|
+
if (taskRunEvent.resolved) {
|
|
437
|
+
clearInterval(interval);
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
this.send("defer-update", {
|
|
441
|
+
logs: taskRunEvent.logs,
|
|
442
|
+
deferID: message.args.deferID,
|
|
443
|
+
progress: taskRunEvent.progress,
|
|
444
|
+
failed: taskRunEvent.failed
|
|
445
|
+
});
|
|
446
|
+
}, 100);
|
|
447
|
+
const taskRunResult = await this.waitForEventToRespond(taskRunEvent);
|
|
448
|
+
this.respondToMessage(message.id, taskRunResult.data, taskRunEvent);
|
|
449
|
+
break;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
waitForEventToRespond(event) {
|
|
455
|
+
return new Promise((resolve, reject) => {
|
|
456
|
+
const dataGet = setInterval(() => {
|
|
457
|
+
if (event.resolved) {
|
|
458
|
+
resolve(event);
|
|
459
|
+
clearTimeout(timeout);
|
|
460
|
+
}
|
|
461
|
+
}, 5);
|
|
462
|
+
const timeout = setTimeout(() => {
|
|
463
|
+
if (event.deffered) {
|
|
464
|
+
clearInterval(dataGet);
|
|
465
|
+
const interval = setInterval(() => {
|
|
466
|
+
if (event.resolved) {
|
|
467
|
+
clearInterval(interval);
|
|
468
|
+
resolve(event);
|
|
469
|
+
}
|
|
470
|
+
}, 100);
|
|
471
|
+
} else reject("Event did not respond in time");
|
|
472
|
+
}, 5e3);
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
respondToMessage(messageID, response, originalEvent) {
|
|
476
|
+
this.socket.send(JSON.stringify({
|
|
477
|
+
event: "response",
|
|
478
|
+
id: messageID,
|
|
479
|
+
args: response,
|
|
480
|
+
statusError: originalEvent ? originalEvent.failed : void 0
|
|
481
|
+
}));
|
|
482
|
+
console.log("dispatched response to " + messageID);
|
|
483
|
+
}
|
|
484
|
+
waitForResponseFromServer(messageID) {
|
|
485
|
+
return new Promise((resolve) => {
|
|
486
|
+
const waiter = (data) => {
|
|
487
|
+
const message = JSON.parse(data);
|
|
488
|
+
if (message.event !== "response") {
|
|
489
|
+
this.socket.once("message", waiter);
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
console.log("received response from " + messageID);
|
|
493
|
+
if (message.id === messageID) resolve(message.args);
|
|
494
|
+
else this.socket.once("message", waiter);
|
|
495
|
+
};
|
|
496
|
+
this.socket.once("message", waiter);
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
send(event, args) {
|
|
500
|
+
const id = Math.random().toString(36).substring(7);
|
|
501
|
+
this.socket.send(JSON.stringify({
|
|
502
|
+
event,
|
|
503
|
+
args,
|
|
504
|
+
id
|
|
505
|
+
}));
|
|
506
|
+
return id;
|
|
507
|
+
}
|
|
508
|
+
close() {
|
|
509
|
+
this.socket.close();
|
|
510
|
+
}
|
|
1075
511
|
};
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
512
|
+
|
|
513
|
+
//#endregion
|
|
514
|
+
exports.Configuration = require_config_Configuration.Configuration;
|
|
515
|
+
exports.ConfigurationBuilder = require_ConfigurationBuilder.ConfigurationBuilder;
|
|
516
|
+
exports.CustomTask = CustomTask;
|
|
517
|
+
exports.EventResponse = require_EventResponse;
|
|
518
|
+
exports.SearchTool = SearchTool;
|
|
519
|
+
exports.VERSION = VERSION;
|
|
520
|
+
exports.ZodLibraryInfo = ZodLibraryInfo;
|
|
521
|
+
exports.default = OGIAddon;
|
|
1086
522
|
//# sourceMappingURL=main.cjs.map
|