ogi-addon 0.3.1 → 1.0.0
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/SearchEngine.cjs.map +1 -1
- package/build/SearchEngine.d.cts +2 -1
- package/build/SearchEngine.d.ts +2 -1
- package/build/main.cjs +76 -4
- package/build/main.cjs.map +1 -1
- package/build/main.d.cts +31 -6
- package/build/main.d.ts +31 -6
- package/build/main.js +76 -4
- package/build/main.js.map +1 -1
- package/package.json +1 -1
- package/schema.json +31 -0
- package/src/SearchEngine.ts +2 -1
- package/src/main.ts +57 -9
- package/tsconfig.json +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/SearchEngine.ts"],"sourcesContent":["export type SearchResult = {\r\n name: string;\r\n description: string;\r\n coverURL: string;\r\n downloadType: 'torrent' | 'direct' | 'magnet';\r\n downloadSize: number;\r\n
|
|
1
|
+
{"version":3,"sources":["../src/SearchEngine.ts"],"sourcesContent":["export type SearchResult = {\r\n name: string;\r\n description: string;\r\n coverURL: string;\r\n downloadType: 'torrent' | 'direct' | 'magnet';\r\n downloadSize: number;\r\n appID: number;\r\n storefront: 'steam' | 'internal';\r\n filename?: string;\r\n downloadURL?: string;\r\n files?: {\r\n name: string;\r\n downloadURL: string;\r\n }[];\r\n}\r\n\r\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
package/build/SearchEngine.d.cts
CHANGED
package/build/SearchEngine.d.ts
CHANGED
package/build/main.cjs
CHANGED
|
@@ -293,9 +293,61 @@ var EventResponse = class {
|
|
|
293
293
|
}
|
|
294
294
|
};
|
|
295
295
|
|
|
296
|
+
// package.json
|
|
297
|
+
var package_default = {
|
|
298
|
+
name: "ogi-addon",
|
|
299
|
+
module: "./build/main.js",
|
|
300
|
+
type: "module",
|
|
301
|
+
main: "./build/main.cjs",
|
|
302
|
+
exports: {
|
|
303
|
+
".": {
|
|
304
|
+
import: {
|
|
305
|
+
default: "./build/main.js",
|
|
306
|
+
types: "./build/main.d.ts"
|
|
307
|
+
},
|
|
308
|
+
require: {
|
|
309
|
+
default: "./build/main.cjs",
|
|
310
|
+
types: "./build/main.d.cts"
|
|
311
|
+
}
|
|
312
|
+
},
|
|
313
|
+
"./config": {
|
|
314
|
+
import: {
|
|
315
|
+
default: "./build/config/Configuration.js",
|
|
316
|
+
types: "./build/config/Configuration.d.ts"
|
|
317
|
+
},
|
|
318
|
+
require: {
|
|
319
|
+
default: "./build/config/Configuration.cjs",
|
|
320
|
+
types: "./build/config/Configuration.d.cts"
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
typings: "./build/main.d.ts",
|
|
325
|
+
author: {
|
|
326
|
+
name: "Nat3z",
|
|
327
|
+
email: "me@nat3z.com",
|
|
328
|
+
url: "https://nat3z.com/"
|
|
329
|
+
},
|
|
330
|
+
version: "1.0.0",
|
|
331
|
+
dependencies: {
|
|
332
|
+
ws: "^8.4.0",
|
|
333
|
+
zod: "^3.23.8"
|
|
334
|
+
},
|
|
335
|
+
scripts: {
|
|
336
|
+
"auto-build": "tsc -w",
|
|
337
|
+
build: "tsup --config tsup.config.js",
|
|
338
|
+
release: "bun run build && npm publish"
|
|
339
|
+
},
|
|
340
|
+
devDependencies: {
|
|
341
|
+
"@types/node": "^20.14.12",
|
|
342
|
+
"@types/ws": "^8.4.0",
|
|
343
|
+
tsup: "^8.2.3",
|
|
344
|
+
typescript: "^5.0.0"
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
|
|
296
348
|
// src/main.ts
|
|
297
349
|
var defaultPort = 7654;
|
|
298
|
-
var version =
|
|
350
|
+
var version = package_default.version;
|
|
299
351
|
var OGIAddon = class {
|
|
300
352
|
eventEmitter = new import_node_events.default.EventEmitter();
|
|
301
353
|
addonWSListener;
|
|
@@ -359,7 +411,8 @@ var OGIAddonWSListener = class {
|
|
|
359
411
|
}
|
|
360
412
|
this.eventEmitter.emit("disconnect", reason);
|
|
361
413
|
console.log("Disconnected from OGI Addon Server");
|
|
362
|
-
console.
|
|
414
|
+
console.error(reason.toString());
|
|
415
|
+
this.eventEmitter.emit("exit");
|
|
363
416
|
this.socket.close();
|
|
364
417
|
});
|
|
365
418
|
this.registerMessageReceiver();
|
|
@@ -397,12 +450,11 @@ var OGIAddonWSListener = class {
|
|
|
397
450
|
let searchResultEvent = new EventResponse((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
398
451
|
this.eventEmitter.emit("search", message.args, searchResultEvent);
|
|
399
452
|
const searchResult = await this.waitForEventToRespond(searchResultEvent);
|
|
400
|
-
console.log(searchResult.data);
|
|
401
453
|
this.respondToMessage(message.id, searchResult.data);
|
|
402
454
|
break;
|
|
403
455
|
case "setup":
|
|
404
456
|
let setupEvent = new EventResponse((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
405
|
-
this.eventEmitter.emit("setup", { path: message.args.path,
|
|
457
|
+
this.eventEmitter.emit("setup", { path: message.args.path, appID: message.args.appID, storefront: message.args.storefront, type: message.args.type, name: message.args.name, usedRealDebrid: message.args.usedRealDebrid, multiPartFiles: message.args.multiPartFiles }, setupEvent);
|
|
406
458
|
const interval = setInterval(() => {
|
|
407
459
|
if (setupEvent.resolved) {
|
|
408
460
|
clearInterval(interval);
|
|
@@ -417,6 +469,26 @@ var OGIAddonWSListener = class {
|
|
|
417
469
|
const setupResult = await this.waitForEventToRespond(setupEvent);
|
|
418
470
|
this.respondToMessage(message.id, setupResult.data);
|
|
419
471
|
break;
|
|
472
|
+
case "library-search":
|
|
473
|
+
let librarySearchEvent = new EventResponse((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
474
|
+
if (this.eventEmitter.listenerCount("game-details") === 0) {
|
|
475
|
+
this.respondToMessage(message.id, []);
|
|
476
|
+
break;
|
|
477
|
+
}
|
|
478
|
+
this.eventEmitter.emit("library-search", message.args, librarySearchEvent);
|
|
479
|
+
const librarySearchResult = await this.waitForEventToRespond(librarySearchEvent);
|
|
480
|
+
this.respondToMessage(message.id, librarySearchResult.data);
|
|
481
|
+
break;
|
|
482
|
+
case "game-details":
|
|
483
|
+
let gameDetailsEvent = new EventResponse((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
484
|
+
if (this.eventEmitter.listenerCount("game-details") === 0) {
|
|
485
|
+
this.respondToMessage(message.id, { error: "No event listener for game-details" });
|
|
486
|
+
break;
|
|
487
|
+
}
|
|
488
|
+
this.eventEmitter.emit("game-details", message.args, gameDetailsEvent);
|
|
489
|
+
const gameDetailsResult = await this.waitForEventToRespond(gameDetailsEvent);
|
|
490
|
+
this.respondToMessage(message.id, gameDetailsResult.data);
|
|
491
|
+
break;
|
|
420
492
|
}
|
|
421
493
|
});
|
|
422
494
|
}
|
package/build/main.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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' | 'input-asked';\r\n\r\nexport type OGIAddonServerSentEvent = 'authenticate' | 'configure' | 'config-update' | 'search' | 'setup' | 'response';\r\nexport { ConfigurationBuilder, Configuration, EventResponse, SearchResult };\r\nconst defaultPort = 7654;\r\nconst version = process.env.npm_package_version;\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 'input-asked': ConfigurationBuilder;\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: { type: 'steamapp', text: string }, event: EventResponse<SearchResult[]>) => void;\r\n setup: (\r\n data: { \r\n path: string, \r\n type: 'direct' | 'torrent' | 'magnet',\r\n name: string,\r\n usedRealDebrid: boolean, \r\n multiPartFiles?: {\r\n name: string,\r\n downloadURL: string\r\n }[],\r\n steamAppID: number\r\n }, event: EventResponse<LibraryInfo>\r\n ) => 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\n\r\nexport interface LibraryInfo {\r\n name: string;\r\n version: string;\r\n cwd: string;\r\n steamAppID: number;\r\n launchExecutable: string;\r\n launchArguments?: string;\r\n capsuleImage: string;\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 console.log('OGI Addon Server Version:', version);\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 ogiVersion: version\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 console.log(reason.toString())\r\n this.socket.close();\r\n });\r\n\r\n this.registerMessageReceiver();\r\n }\r\n\r\n private async userInputAsked(configBuilt: ConfigurationBuilder, name: string, description: string, socket: WebSocket): Promise<{ [key: string]: number | boolean | string }> {\r\n const config = configBuilt.build(false);\r\n const id = Math.random().toString(36).substring(7);\r\n if (!socket) {\r\n return {};\r\n }\r\n socket.send(JSON.stringify({\r\n event: 'input-asked',\r\n args: {\r\n config,\r\n name,\r\n description\r\n },\r\n id: id\r\n }));\r\n return await this.waitForResponseFromServer(id);\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[]>((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));\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<LibraryInfo>((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));\r\n this.eventEmitter.emit('setup', { path: message.args.path, steamAppID: message.args.steamAppID, type: message.args.type, name: message.args.name, usedRealDebrid: message.args.usedRealDebrid, multiPartFiles: message.args.multiPartFiles }, 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 waitForResponseFromServer<T>(messageID: string): Promise<T> {\r\n return new Promise((resolve) => {\r\n const waiter = (data: string) => {\r\n const message: WebsocketMessageClient = JSON.parse(data);\r\n if (message.event !== 'response') {\r\n this.socket.once('message', waiter);\r\n return;\r\n }\r\n console.log(\"received response from \" + messageID)\r\n\r\n if (message.id === messageID) {\r\n resolve(message.args);\r\n }\r\n else {\r\n this.socket.once('message', waiter);\r\n }\r\n }\r\n this.socket.once('message', waiter);\r\n });\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 inputType: 'text' | 'file' | 'password' | 'folder' = 'text';\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 setInputType(inputType: 'text' | 'file' | 'password' | 'folder'): this {\r\n this.inputType = inputType;\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 };","import { ConfigurationBuilder } from \"./main\";\r\n\r\nexport 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 onInputAsked?: (screen: ConfigurationBuilder, name: string, description: string) => Promise<{ [key: string]: boolean | string | number }>;\r\n\r\n constructor(onInputAsked?: (screen: ConfigurationBuilder, name: string, description: string) => Promise<{ [key: string]: boolean | string | number }>) {\r\n this.onInputAsked = onInputAsked;\r\n }\r\n \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 public async askForInput(name: string, description: string, screen: ConfigurationBuilder) {\r\n if (!this.onInputAsked) {\r\n throw new Error('No input asked callback');\r\n }\r\n return await this.onInputAsked(screen, name, description);\r\n }\r\n\r\n \r\n}"],"mappings":"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","names":["z","events","ws"]}
|
|
1
|
+
{"version":3,"sources":["../src/main.ts","../src/config/ConfigurationBuilder.ts","../src/config/Configuration.ts","../src/EventResponse.ts","../package.json"],"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' | 'library-search' | 'game-details' | 'exit';\r\nexport type OGIAddonClientSentEvent = 'response' | 'authenticate' | 'configure' | 'defer-update' | 'notification' | 'input-asked';\r\n\r\nexport type OGIAddonServerSentEvent = 'authenticate' | 'configure' | 'config-update' | 'search' | 'setup' | 'response' | 'library-search' | 'game-details';\r\nexport { ConfigurationBuilder, Configuration, EventResponse, SearchResult };\r\nconst defaultPort = 7654;\r\nimport pjson from '../package.json';\r\nconst version = pjson.version;\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 'input-asked': ConfigurationBuilder;\r\n}\r\n\r\nexport type BasicLibraryInfo = {\r\n name: string;\r\n capsuleImage: string;\r\n appID: number;\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: { type: 'steamapp' | 'internal', text: string }, event: EventResponse<SearchResult[]>) => void;\r\n setup: (\r\n data: { \r\n path: string, \r\n type: 'direct' | 'torrent' | 'magnet',\r\n name: string,\r\n usedRealDebrid: boolean, \r\n multiPartFiles?: {\r\n name: string,\r\n downloadURL: string\r\n }[],\r\n appID: number,\r\n storefront: 'steam' | 'internal'\r\n }, event: EventResponse<LibraryInfo>\r\n ) => void;\r\n 'library-search': (query: string, event: EventResponse<BasicLibraryInfo[]>) => void;\r\n 'game-details': (appID: number, event: EventResponse<StoreData>) => void;\r\n exit: () => void;\r\n}\r\n\r\nexport interface StoreData {\r\n name: string;\r\n publishers: string[];\r\n developers: string[];\r\n appID: number;\r\n releaseDate: string;\r\n capsuleImage: string;\r\n coverImage: string;\r\n basicDescription: string;\r\n description: string;\r\n headerImage: string;\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\n\r\nexport interface LibraryInfo {\r\n name: string;\r\n version: string;\r\n cwd: string;\r\n appID: number;\r\n launchExecutable: string;\r\n launchArguments?: string;\r\n capsuleImage: string;\r\n storefront: 'steam' | 'internal';\r\n addonsource: string;\r\n coverImage: string;\r\n titleImage?: string;\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 console.log('OGI Addon Server Version:', version);\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 ogiVersion: version\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 console.error(reason.toString())\r\n this.eventEmitter.emit('exit');\r\n this.socket.close();\r\n });\r\n\r\n this.registerMessageReceiver();\r\n }\r\n\r\n private async userInputAsked(configBuilt: ConfigurationBuilder, name: string, description: string, socket: WebSocket): Promise<{ [key: string]: number | boolean | string }> {\r\n const config = configBuilt.build(false);\r\n const id = Math.random().toString(36).substring(7);\r\n if (!socket) {\r\n return {};\r\n }\r\n socket.send(JSON.stringify({\r\n event: 'input-asked',\r\n args: {\r\n config,\r\n name,\r\n description\r\n },\r\n id: id\r\n }));\r\n return await this.waitForResponseFromServer(id);\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[]>((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));\r\n this.eventEmitter.emit('search', message.args, searchResultEvent);\r\n const searchResult = await this.waitForEventToRespond(searchResultEvent); \r\n this.respondToMessage(message.id!!, searchResult.data);\r\n break\r\n case 'setup':\r\n let setupEvent = new EventResponse<LibraryInfo>((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));\r\n this.eventEmitter.emit('setup', { path: message.args.path, appID: message.args.appID, storefront: message.args.storefront, type: message.args.type, name: message.args.name, usedRealDebrid: message.args.usedRealDebrid, multiPartFiles: message.args.multiPartFiles }, 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 case 'library-search':\r\n let librarySearchEvent = new EventResponse<BasicLibraryInfo[]>((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));\r\n if (this.eventEmitter.listenerCount('game-details') === 0) {\r\n this.respondToMessage(message.id!!, []);\r\n break;\r\n }\r\n this.eventEmitter.emit('library-search', message.args, librarySearchEvent);\r\n const librarySearchResult = await this.waitForEventToRespond(librarySearchEvent);\r\n this.respondToMessage(message.id!!, librarySearchResult.data);\r\n break\r\n case 'game-details':\r\n let gameDetailsEvent = new EventResponse<StoreData>((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));\r\n if (this.eventEmitter.listenerCount('game-details') === 0) {\r\n this.respondToMessage(message.id!!, { error: 'No event listener for game-details' });\r\n break;\r\n }\r\n this.eventEmitter.emit('game-details', message.args, gameDetailsEvent);\r\n const gameDetailsResult = await this.waitForEventToRespond(gameDetailsEvent);\r\n this.respondToMessage(message.id!!, gameDetailsResult.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 // check the handlers to see if there even is any\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 waitForResponseFromServer<T>(messageID: string): Promise<T> {\r\n return new Promise((resolve) => {\r\n const waiter = (data: string) => {\r\n const message: WebsocketMessageClient = JSON.parse(data);\r\n if (message.event !== 'response') {\r\n this.socket.once('message', waiter);\r\n return;\r\n }\r\n console.log(\"received response from \" + messageID)\r\n\r\n if (message.id === messageID) {\r\n resolve(message.args);\r\n }\r\n else {\r\n this.socket.once('message', waiter);\r\n }\r\n }\r\n this.socket.once('message', waiter);\r\n });\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 inputType: 'text' | 'file' | 'password' | 'folder' = 'text';\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 setInputType(inputType: 'text' | 'file' | 'password' | 'folder'): this {\r\n this.inputType = inputType;\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 };","import { ConfigurationBuilder } from \"./main\";\r\n\r\nexport 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 onInputAsked?: (screen: ConfigurationBuilder, name: string, description: string) => Promise<{ [key: string]: boolean | string | number }>;\r\n\r\n constructor(onInputAsked?: (screen: ConfigurationBuilder, name: string, description: string) => Promise<{ [key: string]: boolean | string | number }>) {\r\n this.onInputAsked = onInputAsked;\r\n }\r\n \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 public async askForInput(name: string, description: string, screen: ConfigurationBuilder) {\r\n if (!this.onInputAsked) {\r\n throw new Error('No input asked callback');\r\n }\r\n return await this.onInputAsked(screen, name, description);\r\n }\r\n\r\n \r\n}","{\r\n \"name\": \"ogi-addon\",\r\n \"module\": \"./build/main.js\",\r\n \"type\": \"module\",\r\n \"main\": \"./build/main.cjs\",\r\n \"exports\": {\r\n \".\": {\r\n \"import\": {\r\n \"default\": \"./build/main.js\",\r\n \"types\": \"./build/main.d.ts\"\r\n },\r\n \"require\": {\r\n \"default\": \"./build/main.cjs\",\r\n \"types\": \"./build/main.d.cts\"\r\n }\r\n },\r\n \"./config\": {\r\n \"import\": {\r\n \"default\": \"./build/config/Configuration.js\",\r\n \"types\": \"./build/config/Configuration.d.ts\"\r\n },\r\n \"require\": {\r\n \"default\": \"./build/config/Configuration.cjs\",\r\n \"types\": \"./build/config/Configuration.d.cts\"\r\n }\r\n }\r\n },\r\n \"typings\": \"./build/main.d.ts\",\r\n \"author\": {\r\n \"name\": \"Nat3z\",\r\n \"email\": \"me@nat3z.com\",\r\n \"url\": \"https://nat3z.com/\"\r\n },\r\n \"version\": \"1.0.0\",\r\n \"dependencies\": {\r\n \"ws\": \"^8.4.0\",\r\n \"zod\": \"^3.23.8\"\r\n },\r\n \"scripts\": {\r\n \"auto-build\": \"tsc -w\",\r\n \"build\": \"tsup --config tsup.config.js\",\r\n \"release\": \"bun run build && npm publish\"\r\n },\r\n \"devDependencies\": {\r\n \"@types/node\": \"^20.14.12\",\r\n \"@types/ws\": \"^8.4.0\",\r\n \"tsup\": \"^8.2.3\",\r\n \"typescript\": \"^5.0.0\"\r\n }\r\n}"],"mappings":"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","names":["z","events","ws"]}
|
package/build/main.d.cts
CHANGED
|
@@ -5,9 +5,9 @@ import { Configuration } from './config/Configuration.cjs';
|
|
|
5
5
|
import EventResponse from './EventResponse.cjs';
|
|
6
6
|
import { SearchResult } from './SearchEngine.cjs';
|
|
7
7
|
|
|
8
|
-
type OGIAddonEvent = 'connect' | 'disconnect' | 'configure' | 'authenticate' | 'search' | 'setup';
|
|
8
|
+
type OGIAddonEvent = 'connect' | 'disconnect' | 'configure' | 'authenticate' | 'search' | 'setup' | 'library-search' | 'game-details' | 'exit';
|
|
9
9
|
type OGIAddonClientSentEvent = 'response' | 'authenticate' | 'configure' | 'defer-update' | 'notification' | 'input-asked';
|
|
10
|
-
type OGIAddonServerSentEvent = 'authenticate' | 'configure' | 'config-update' | 'search' | 'setup' | 'response';
|
|
10
|
+
type OGIAddonServerSentEvent = 'authenticate' | 'configure' | 'config-update' | 'search' | 'setup' | 'response' | 'library-search' | 'game-details';
|
|
11
11
|
|
|
12
12
|
interface ClientSentEventTypes {
|
|
13
13
|
response: any;
|
|
@@ -20,6 +20,11 @@ interface ClientSentEventTypes {
|
|
|
20
20
|
notification: Notification;
|
|
21
21
|
'input-asked': ConfigurationBuilder;
|
|
22
22
|
}
|
|
23
|
+
type BasicLibraryInfo = {
|
|
24
|
+
name: string;
|
|
25
|
+
capsuleImage: string;
|
|
26
|
+
appID: number;
|
|
27
|
+
};
|
|
23
28
|
interface EventListenerTypes {
|
|
24
29
|
connect: (socket: ws) => void;
|
|
25
30
|
disconnect: (reason: string) => void;
|
|
@@ -27,7 +32,7 @@ interface EventListenerTypes {
|
|
|
27
32
|
response: (response: any) => void;
|
|
28
33
|
authenticate: (config: any) => void;
|
|
29
34
|
search: (query: {
|
|
30
|
-
type: 'steamapp';
|
|
35
|
+
type: 'steamapp' | 'internal';
|
|
31
36
|
text: string;
|
|
32
37
|
}, event: EventResponse<SearchResult[]>) => void;
|
|
33
38
|
setup: (data: {
|
|
@@ -39,8 +44,24 @@ interface EventListenerTypes {
|
|
|
39
44
|
name: string;
|
|
40
45
|
downloadURL: string;
|
|
41
46
|
}[];
|
|
42
|
-
|
|
47
|
+
appID: number;
|
|
48
|
+
storefront: 'steam' | 'internal';
|
|
43
49
|
}, event: EventResponse<LibraryInfo>) => void;
|
|
50
|
+
'library-search': (query: string, event: EventResponse<BasicLibraryInfo[]>) => void;
|
|
51
|
+
'game-details': (appID: number, event: EventResponse<StoreData>) => void;
|
|
52
|
+
exit: () => void;
|
|
53
|
+
}
|
|
54
|
+
interface StoreData {
|
|
55
|
+
name: string;
|
|
56
|
+
publishers: string[];
|
|
57
|
+
developers: string[];
|
|
58
|
+
appID: number;
|
|
59
|
+
releaseDate: string;
|
|
60
|
+
capsuleImage: string;
|
|
61
|
+
coverImage: string;
|
|
62
|
+
basicDescription: string;
|
|
63
|
+
description: string;
|
|
64
|
+
headerImage: string;
|
|
44
65
|
}
|
|
45
66
|
interface WebsocketMessageClient {
|
|
46
67
|
event: OGIAddonClientSentEvent;
|
|
@@ -74,10 +95,14 @@ interface LibraryInfo {
|
|
|
74
95
|
name: string;
|
|
75
96
|
version: string;
|
|
76
97
|
cwd: string;
|
|
77
|
-
|
|
98
|
+
appID: number;
|
|
78
99
|
launchExecutable: string;
|
|
79
100
|
launchArguments?: string;
|
|
80
101
|
capsuleImage: string;
|
|
102
|
+
storefront: 'steam' | 'internal';
|
|
103
|
+
addonsource: string;
|
|
104
|
+
coverImage: string;
|
|
105
|
+
titleImage?: string;
|
|
81
106
|
}
|
|
82
107
|
interface Notification {
|
|
83
108
|
type: 'warning' | 'error' | 'info' | 'success';
|
|
@@ -98,4 +123,4 @@ declare class OGIAddonWSListener {
|
|
|
98
123
|
close(): void;
|
|
99
124
|
}
|
|
100
125
|
|
|
101
|
-
export { type ClientSentEventTypes, Configuration, ConfigurationBuilder, type EventListenerTypes, EventResponse, type LibraryInfo, type OGIAddonClientSentEvent, type OGIAddonConfiguration, type OGIAddonEvent, type OGIAddonServerSentEvent, SearchResult, type WebsocketMessageClient, type WebsocketMessageServer, OGIAddon as default };
|
|
126
|
+
export { type BasicLibraryInfo, type ClientSentEventTypes, Configuration, ConfigurationBuilder, type EventListenerTypes, EventResponse, type LibraryInfo, type OGIAddonClientSentEvent, type OGIAddonConfiguration, type OGIAddonEvent, type OGIAddonServerSentEvent, SearchResult, type StoreData, type WebsocketMessageClient, type WebsocketMessageServer, OGIAddon as default };
|
package/build/main.d.ts
CHANGED
|
@@ -5,9 +5,9 @@ import { Configuration } from './config/Configuration.js';
|
|
|
5
5
|
import EventResponse from './EventResponse.js';
|
|
6
6
|
import { SearchResult } from './SearchEngine.js';
|
|
7
7
|
|
|
8
|
-
type OGIAddonEvent = 'connect' | 'disconnect' | 'configure' | 'authenticate' | 'search' | 'setup';
|
|
8
|
+
type OGIAddonEvent = 'connect' | 'disconnect' | 'configure' | 'authenticate' | 'search' | 'setup' | 'library-search' | 'game-details' | 'exit';
|
|
9
9
|
type OGIAddonClientSentEvent = 'response' | 'authenticate' | 'configure' | 'defer-update' | 'notification' | 'input-asked';
|
|
10
|
-
type OGIAddonServerSentEvent = 'authenticate' | 'configure' | 'config-update' | 'search' | 'setup' | 'response';
|
|
10
|
+
type OGIAddonServerSentEvent = 'authenticate' | 'configure' | 'config-update' | 'search' | 'setup' | 'response' | 'library-search' | 'game-details';
|
|
11
11
|
|
|
12
12
|
interface ClientSentEventTypes {
|
|
13
13
|
response: any;
|
|
@@ -20,6 +20,11 @@ interface ClientSentEventTypes {
|
|
|
20
20
|
notification: Notification;
|
|
21
21
|
'input-asked': ConfigurationBuilder;
|
|
22
22
|
}
|
|
23
|
+
type BasicLibraryInfo = {
|
|
24
|
+
name: string;
|
|
25
|
+
capsuleImage: string;
|
|
26
|
+
appID: number;
|
|
27
|
+
};
|
|
23
28
|
interface EventListenerTypes {
|
|
24
29
|
connect: (socket: ws) => void;
|
|
25
30
|
disconnect: (reason: string) => void;
|
|
@@ -27,7 +32,7 @@ interface EventListenerTypes {
|
|
|
27
32
|
response: (response: any) => void;
|
|
28
33
|
authenticate: (config: any) => void;
|
|
29
34
|
search: (query: {
|
|
30
|
-
type: 'steamapp';
|
|
35
|
+
type: 'steamapp' | 'internal';
|
|
31
36
|
text: string;
|
|
32
37
|
}, event: EventResponse<SearchResult[]>) => void;
|
|
33
38
|
setup: (data: {
|
|
@@ -39,8 +44,24 @@ interface EventListenerTypes {
|
|
|
39
44
|
name: string;
|
|
40
45
|
downloadURL: string;
|
|
41
46
|
}[];
|
|
42
|
-
|
|
47
|
+
appID: number;
|
|
48
|
+
storefront: 'steam' | 'internal';
|
|
43
49
|
}, event: EventResponse<LibraryInfo>) => void;
|
|
50
|
+
'library-search': (query: string, event: EventResponse<BasicLibraryInfo[]>) => void;
|
|
51
|
+
'game-details': (appID: number, event: EventResponse<StoreData>) => void;
|
|
52
|
+
exit: () => void;
|
|
53
|
+
}
|
|
54
|
+
interface StoreData {
|
|
55
|
+
name: string;
|
|
56
|
+
publishers: string[];
|
|
57
|
+
developers: string[];
|
|
58
|
+
appID: number;
|
|
59
|
+
releaseDate: string;
|
|
60
|
+
capsuleImage: string;
|
|
61
|
+
coverImage: string;
|
|
62
|
+
basicDescription: string;
|
|
63
|
+
description: string;
|
|
64
|
+
headerImage: string;
|
|
44
65
|
}
|
|
45
66
|
interface WebsocketMessageClient {
|
|
46
67
|
event: OGIAddonClientSentEvent;
|
|
@@ -74,10 +95,14 @@ interface LibraryInfo {
|
|
|
74
95
|
name: string;
|
|
75
96
|
version: string;
|
|
76
97
|
cwd: string;
|
|
77
|
-
|
|
98
|
+
appID: number;
|
|
78
99
|
launchExecutable: string;
|
|
79
100
|
launchArguments?: string;
|
|
80
101
|
capsuleImage: string;
|
|
102
|
+
storefront: 'steam' | 'internal';
|
|
103
|
+
addonsource: string;
|
|
104
|
+
coverImage: string;
|
|
105
|
+
titleImage?: string;
|
|
81
106
|
}
|
|
82
107
|
interface Notification {
|
|
83
108
|
type: 'warning' | 'error' | 'info' | 'success';
|
|
@@ -98,4 +123,4 @@ declare class OGIAddonWSListener {
|
|
|
98
123
|
close(): void;
|
|
99
124
|
}
|
|
100
125
|
|
|
101
|
-
export { type ClientSentEventTypes, Configuration, ConfigurationBuilder, type EventListenerTypes, EventResponse, type LibraryInfo, type OGIAddonClientSentEvent, type OGIAddonConfiguration, type OGIAddonEvent, type OGIAddonServerSentEvent, SearchResult, type WebsocketMessageClient, type WebsocketMessageServer, OGIAddon as default };
|
|
126
|
+
export { type BasicLibraryInfo, type ClientSentEventTypes, Configuration, ConfigurationBuilder, type EventListenerTypes, EventResponse, type LibraryInfo, type OGIAddonClientSentEvent, type OGIAddonConfiguration, type OGIAddonEvent, type OGIAddonServerSentEvent, SearchResult, type StoreData, type WebsocketMessageClient, type WebsocketMessageServer, OGIAddon as default };
|
package/build/main.js
CHANGED
|
@@ -256,9 +256,61 @@ var EventResponse = class {
|
|
|
256
256
|
}
|
|
257
257
|
};
|
|
258
258
|
|
|
259
|
+
// package.json
|
|
260
|
+
var package_default = {
|
|
261
|
+
name: "ogi-addon",
|
|
262
|
+
module: "./build/main.js",
|
|
263
|
+
type: "module",
|
|
264
|
+
main: "./build/main.cjs",
|
|
265
|
+
exports: {
|
|
266
|
+
".": {
|
|
267
|
+
import: {
|
|
268
|
+
default: "./build/main.js",
|
|
269
|
+
types: "./build/main.d.ts"
|
|
270
|
+
},
|
|
271
|
+
require: {
|
|
272
|
+
default: "./build/main.cjs",
|
|
273
|
+
types: "./build/main.d.cts"
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
"./config": {
|
|
277
|
+
import: {
|
|
278
|
+
default: "./build/config/Configuration.js",
|
|
279
|
+
types: "./build/config/Configuration.d.ts"
|
|
280
|
+
},
|
|
281
|
+
require: {
|
|
282
|
+
default: "./build/config/Configuration.cjs",
|
|
283
|
+
types: "./build/config/Configuration.d.cts"
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
typings: "./build/main.d.ts",
|
|
288
|
+
author: {
|
|
289
|
+
name: "Nat3z",
|
|
290
|
+
email: "me@nat3z.com",
|
|
291
|
+
url: "https://nat3z.com/"
|
|
292
|
+
},
|
|
293
|
+
version: "1.0.0",
|
|
294
|
+
dependencies: {
|
|
295
|
+
ws: "^8.4.0",
|
|
296
|
+
zod: "^3.23.8"
|
|
297
|
+
},
|
|
298
|
+
scripts: {
|
|
299
|
+
"auto-build": "tsc -w",
|
|
300
|
+
build: "tsup --config tsup.config.js",
|
|
301
|
+
release: "bun run build && npm publish"
|
|
302
|
+
},
|
|
303
|
+
devDependencies: {
|
|
304
|
+
"@types/node": "^20.14.12",
|
|
305
|
+
"@types/ws": "^8.4.0",
|
|
306
|
+
tsup: "^8.2.3",
|
|
307
|
+
typescript: "^5.0.0"
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
|
|
259
311
|
// src/main.ts
|
|
260
312
|
var defaultPort = 7654;
|
|
261
|
-
var version =
|
|
313
|
+
var version = package_default.version;
|
|
262
314
|
var OGIAddon = class {
|
|
263
315
|
eventEmitter = new events.EventEmitter();
|
|
264
316
|
addonWSListener;
|
|
@@ -322,7 +374,8 @@ var OGIAddonWSListener = class {
|
|
|
322
374
|
}
|
|
323
375
|
this.eventEmitter.emit("disconnect", reason);
|
|
324
376
|
console.log("Disconnected from OGI Addon Server");
|
|
325
|
-
console.
|
|
377
|
+
console.error(reason.toString());
|
|
378
|
+
this.eventEmitter.emit("exit");
|
|
326
379
|
this.socket.close();
|
|
327
380
|
});
|
|
328
381
|
this.registerMessageReceiver();
|
|
@@ -360,12 +413,11 @@ var OGIAddonWSListener = class {
|
|
|
360
413
|
let searchResultEvent = new EventResponse((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
361
414
|
this.eventEmitter.emit("search", message.args, searchResultEvent);
|
|
362
415
|
const searchResult = await this.waitForEventToRespond(searchResultEvent);
|
|
363
|
-
console.log(searchResult.data);
|
|
364
416
|
this.respondToMessage(message.id, searchResult.data);
|
|
365
417
|
break;
|
|
366
418
|
case "setup":
|
|
367
419
|
let setupEvent = new EventResponse((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
368
|
-
this.eventEmitter.emit("setup", { path: message.args.path,
|
|
420
|
+
this.eventEmitter.emit("setup", { path: message.args.path, appID: message.args.appID, storefront: message.args.storefront, type: message.args.type, name: message.args.name, usedRealDebrid: message.args.usedRealDebrid, multiPartFiles: message.args.multiPartFiles }, setupEvent);
|
|
369
421
|
const interval = setInterval(() => {
|
|
370
422
|
if (setupEvent.resolved) {
|
|
371
423
|
clearInterval(interval);
|
|
@@ -380,6 +432,26 @@ var OGIAddonWSListener = class {
|
|
|
380
432
|
const setupResult = await this.waitForEventToRespond(setupEvent);
|
|
381
433
|
this.respondToMessage(message.id, setupResult.data);
|
|
382
434
|
break;
|
|
435
|
+
case "library-search":
|
|
436
|
+
let librarySearchEvent = new EventResponse((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
437
|
+
if (this.eventEmitter.listenerCount("game-details") === 0) {
|
|
438
|
+
this.respondToMessage(message.id, []);
|
|
439
|
+
break;
|
|
440
|
+
}
|
|
441
|
+
this.eventEmitter.emit("library-search", message.args, librarySearchEvent);
|
|
442
|
+
const librarySearchResult = await this.waitForEventToRespond(librarySearchEvent);
|
|
443
|
+
this.respondToMessage(message.id, librarySearchResult.data);
|
|
444
|
+
break;
|
|
445
|
+
case "game-details":
|
|
446
|
+
let gameDetailsEvent = new EventResponse((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
447
|
+
if (this.eventEmitter.listenerCount("game-details") === 0) {
|
|
448
|
+
this.respondToMessage(message.id, { error: "No event listener for game-details" });
|
|
449
|
+
break;
|
|
450
|
+
}
|
|
451
|
+
this.eventEmitter.emit("game-details", message.args, gameDetailsEvent);
|
|
452
|
+
const gameDetailsResult = await this.waitForEventToRespond(gameDetailsEvent);
|
|
453
|
+
this.respondToMessage(message.id, gameDetailsResult.data);
|
|
454
|
+
break;
|
|
383
455
|
}
|
|
384
456
|
});
|
|
385
457
|
}
|
package/build/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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' | 'input-asked';\r\n\r\nexport type OGIAddonServerSentEvent = 'authenticate' | 'configure' | 'config-update' | 'search' | 'setup' | 'response';\r\nexport { ConfigurationBuilder, Configuration, EventResponse, SearchResult };\r\nconst defaultPort = 7654;\r\nconst version = process.env.npm_package_version;\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 'input-asked': ConfigurationBuilder;\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: { type: 'steamapp', text: string }, event: EventResponse<SearchResult[]>) => void;\r\n setup: (\r\n data: { \r\n path: string, \r\n type: 'direct' | 'torrent' | 'magnet',\r\n name: string,\r\n usedRealDebrid: boolean, \r\n multiPartFiles?: {\r\n name: string,\r\n downloadURL: string\r\n }[],\r\n steamAppID: number\r\n }, event: EventResponse<LibraryInfo>\r\n ) => 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\n\r\nexport interface LibraryInfo {\r\n name: string;\r\n version: string;\r\n cwd: string;\r\n steamAppID: number;\r\n launchExecutable: string;\r\n launchArguments?: string;\r\n capsuleImage: string;\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 console.log('OGI Addon Server Version:', version);\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 ogiVersion: version\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 console.log(reason.toString())\r\n this.socket.close();\r\n });\r\n\r\n this.registerMessageReceiver();\r\n }\r\n\r\n private async userInputAsked(configBuilt: ConfigurationBuilder, name: string, description: string, socket: WebSocket): Promise<{ [key: string]: number | boolean | string }> {\r\n const config = configBuilt.build(false);\r\n const id = Math.random().toString(36).substring(7);\r\n if (!socket) {\r\n return {};\r\n }\r\n socket.send(JSON.stringify({\r\n event: 'input-asked',\r\n args: {\r\n config,\r\n name,\r\n description\r\n },\r\n id: id\r\n }));\r\n return await this.waitForResponseFromServer(id);\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[]>((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));\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<LibraryInfo>((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));\r\n this.eventEmitter.emit('setup', { path: message.args.path, steamAppID: message.args.steamAppID, type: message.args.type, name: message.args.name, usedRealDebrid: message.args.usedRealDebrid, multiPartFiles: message.args.multiPartFiles }, 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 waitForResponseFromServer<T>(messageID: string): Promise<T> {\r\n return new Promise((resolve) => {\r\n const waiter = (data: string) => {\r\n const message: WebsocketMessageClient = JSON.parse(data);\r\n if (message.event !== 'response') {\r\n this.socket.once('message', waiter);\r\n return;\r\n }\r\n console.log(\"received response from \" + messageID)\r\n\r\n if (message.id === messageID) {\r\n resolve(message.args);\r\n }\r\n else {\r\n this.socket.once('message', waiter);\r\n }\r\n }\r\n this.socket.once('message', waiter);\r\n });\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 inputType: 'text' | 'file' | 'password' | 'folder' = 'text';\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 setInputType(inputType: 'text' | 'file' | 'password' | 'folder'): this {\r\n this.inputType = inputType;\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 };","import { ConfigurationBuilder } from \"./main\";\r\n\r\nexport 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 onInputAsked?: (screen: ConfigurationBuilder, name: string, description: string) => Promise<{ [key: string]: boolean | string | number }>;\r\n\r\n constructor(onInputAsked?: (screen: ConfigurationBuilder, name: string, description: string) => Promise<{ [key: string]: boolean | string | number }>) {\r\n this.onInputAsked = onInputAsked;\r\n }\r\n \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 public async askForInput(name: string, description: string, screen: ConfigurationBuilder) {\r\n if (!this.onInputAsked) {\r\n throw new Error('No input asked callback');\r\n }\r\n return await this.onInputAsked(screen, name, description);\r\n }\r\n\r\n \r\n}"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/main.ts","../src/config/ConfigurationBuilder.ts","../src/config/Configuration.ts","../src/EventResponse.ts","../package.json"],"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' | 'library-search' | 'game-details' | 'exit';\r\nexport type OGIAddonClientSentEvent = 'response' | 'authenticate' | 'configure' | 'defer-update' | 'notification' | 'input-asked';\r\n\r\nexport type OGIAddonServerSentEvent = 'authenticate' | 'configure' | 'config-update' | 'search' | 'setup' | 'response' | 'library-search' | 'game-details';\r\nexport { ConfigurationBuilder, Configuration, EventResponse, SearchResult };\r\nconst defaultPort = 7654;\r\nimport pjson from '../package.json';\r\nconst version = pjson.version;\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 'input-asked': ConfigurationBuilder;\r\n}\r\n\r\nexport type BasicLibraryInfo = {\r\n name: string;\r\n capsuleImage: string;\r\n appID: number;\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: { type: 'steamapp' | 'internal', text: string }, event: EventResponse<SearchResult[]>) => void;\r\n setup: (\r\n data: { \r\n path: string, \r\n type: 'direct' | 'torrent' | 'magnet',\r\n name: string,\r\n usedRealDebrid: boolean, \r\n multiPartFiles?: {\r\n name: string,\r\n downloadURL: string\r\n }[],\r\n appID: number,\r\n storefront: 'steam' | 'internal'\r\n }, event: EventResponse<LibraryInfo>\r\n ) => void;\r\n 'library-search': (query: string, event: EventResponse<BasicLibraryInfo[]>) => void;\r\n 'game-details': (appID: number, event: EventResponse<StoreData>) => void;\r\n exit: () => void;\r\n}\r\n\r\nexport interface StoreData {\r\n name: string;\r\n publishers: string[];\r\n developers: string[];\r\n appID: number;\r\n releaseDate: string;\r\n capsuleImage: string;\r\n coverImage: string;\r\n basicDescription: string;\r\n description: string;\r\n headerImage: string;\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\n\r\nexport interface LibraryInfo {\r\n name: string;\r\n version: string;\r\n cwd: string;\r\n appID: number;\r\n launchExecutable: string;\r\n launchArguments?: string;\r\n capsuleImage: string;\r\n storefront: 'steam' | 'internal';\r\n addonsource: string;\r\n coverImage: string;\r\n titleImage?: string;\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 console.log('OGI Addon Server Version:', version);\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 ogiVersion: version\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 console.error(reason.toString())\r\n this.eventEmitter.emit('exit');\r\n this.socket.close();\r\n });\r\n\r\n this.registerMessageReceiver();\r\n }\r\n\r\n private async userInputAsked(configBuilt: ConfigurationBuilder, name: string, description: string, socket: WebSocket): Promise<{ [key: string]: number | boolean | string }> {\r\n const config = configBuilt.build(false);\r\n const id = Math.random().toString(36).substring(7);\r\n if (!socket) {\r\n return {};\r\n }\r\n socket.send(JSON.stringify({\r\n event: 'input-asked',\r\n args: {\r\n config,\r\n name,\r\n description\r\n },\r\n id: id\r\n }));\r\n return await this.waitForResponseFromServer(id);\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[]>((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));\r\n this.eventEmitter.emit('search', message.args, searchResultEvent);\r\n const searchResult = await this.waitForEventToRespond(searchResultEvent); \r\n this.respondToMessage(message.id!!, searchResult.data);\r\n break\r\n case 'setup':\r\n let setupEvent = new EventResponse<LibraryInfo>((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));\r\n this.eventEmitter.emit('setup', { path: message.args.path, appID: message.args.appID, storefront: message.args.storefront, type: message.args.type, name: message.args.name, usedRealDebrid: message.args.usedRealDebrid, multiPartFiles: message.args.multiPartFiles }, 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 case 'library-search':\r\n let librarySearchEvent = new EventResponse<BasicLibraryInfo[]>((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));\r\n if (this.eventEmitter.listenerCount('game-details') === 0) {\r\n this.respondToMessage(message.id!!, []);\r\n break;\r\n }\r\n this.eventEmitter.emit('library-search', message.args, librarySearchEvent);\r\n const librarySearchResult = await this.waitForEventToRespond(librarySearchEvent);\r\n this.respondToMessage(message.id!!, librarySearchResult.data);\r\n break\r\n case 'game-details':\r\n let gameDetailsEvent = new EventResponse<StoreData>((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));\r\n if (this.eventEmitter.listenerCount('game-details') === 0) {\r\n this.respondToMessage(message.id!!, { error: 'No event listener for game-details' });\r\n break;\r\n }\r\n this.eventEmitter.emit('game-details', message.args, gameDetailsEvent);\r\n const gameDetailsResult = await this.waitForEventToRespond(gameDetailsEvent);\r\n this.respondToMessage(message.id!!, gameDetailsResult.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 // check the handlers to see if there even is any\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 waitForResponseFromServer<T>(messageID: string): Promise<T> {\r\n return new Promise((resolve) => {\r\n const waiter = (data: string) => {\r\n const message: WebsocketMessageClient = JSON.parse(data);\r\n if (message.event !== 'response') {\r\n this.socket.once('message', waiter);\r\n return;\r\n }\r\n console.log(\"received response from \" + messageID)\r\n\r\n if (message.id === messageID) {\r\n resolve(message.args);\r\n }\r\n else {\r\n this.socket.once('message', waiter);\r\n }\r\n }\r\n this.socket.once('message', waiter);\r\n });\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 inputType: 'text' | 'file' | 'password' | 'folder' = 'text';\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 setInputType(inputType: 'text' | 'file' | 'password' | 'folder'): this {\r\n this.inputType = inputType;\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 };","import { ConfigurationBuilder } from \"./main\";\r\n\r\nexport 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 onInputAsked?: (screen: ConfigurationBuilder, name: string, description: string) => Promise<{ [key: string]: boolean | string | number }>;\r\n\r\n constructor(onInputAsked?: (screen: ConfigurationBuilder, name: string, description: string) => Promise<{ [key: string]: boolean | string | number }>) {\r\n this.onInputAsked = onInputAsked;\r\n }\r\n \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 public async askForInput(name: string, description: string, screen: ConfigurationBuilder) {\r\n if (!this.onInputAsked) {\r\n throw new Error('No input asked callback');\r\n }\r\n return await this.onInputAsked(screen, name, description);\r\n }\r\n\r\n \r\n}","{\r\n \"name\": \"ogi-addon\",\r\n \"module\": \"./build/main.js\",\r\n \"type\": \"module\",\r\n \"main\": \"./build/main.cjs\",\r\n \"exports\": {\r\n \".\": {\r\n \"import\": {\r\n \"default\": \"./build/main.js\",\r\n \"types\": \"./build/main.d.ts\"\r\n },\r\n \"require\": {\r\n \"default\": \"./build/main.cjs\",\r\n \"types\": \"./build/main.d.cts\"\r\n }\r\n },\r\n \"./config\": {\r\n \"import\": {\r\n \"default\": \"./build/config/Configuration.js\",\r\n \"types\": \"./build/config/Configuration.d.ts\"\r\n },\r\n \"require\": {\r\n \"default\": \"./build/config/Configuration.cjs\",\r\n \"types\": \"./build/config/Configuration.d.cts\"\r\n }\r\n }\r\n },\r\n \"typings\": \"./build/main.d.ts\",\r\n \"author\": {\r\n \"name\": \"Nat3z\",\r\n \"email\": \"me@nat3z.com\",\r\n \"url\": \"https://nat3z.com/\"\r\n },\r\n \"version\": \"1.0.0\",\r\n \"dependencies\": {\r\n \"ws\": \"^8.4.0\",\r\n \"zod\": \"^3.23.8\"\r\n },\r\n \"scripts\": {\r\n \"auto-build\": \"tsc -w\",\r\n \"build\": \"tsup --config tsup.config.js\",\r\n \"release\": \"bun run build && npm publish\"\r\n },\r\n \"devDependencies\": {\r\n \"@types/node\": \"^20.14.12\",\r\n \"@types/ws\": \"^8.4.0\",\r\n \"tsup\": \"^8.2.3\",\r\n \"typescript\": \"^5.0.0\"\r\n }\r\n}"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
package/schema.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "AddonFileConfigurationSchema",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"author": {
|
|
7
|
+
"type": "string"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"properties": {
|
|
12
|
+
"setup": {
|
|
13
|
+
"type": "string"
|
|
14
|
+
},
|
|
15
|
+
"run": {
|
|
16
|
+
"type": "string"
|
|
17
|
+
},
|
|
18
|
+
"preSetup": {
|
|
19
|
+
"type": "string"
|
|
20
|
+
},
|
|
21
|
+
"postSetup": {
|
|
22
|
+
"type": "string"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"required": ["run"],
|
|
26
|
+
"additionalProperties": false
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"required": ["author", "scripts"],
|
|
30
|
+
"additionalProperties": false
|
|
31
|
+
}
|
package/src/SearchEngine.ts
CHANGED
package/src/main.ts
CHANGED
|
@@ -5,13 +5,14 @@ import { Configuration } from './config/Configuration';
|
|
|
5
5
|
import EventResponse from './EventResponse';
|
|
6
6
|
import { SearchResult } from './SearchEngine';
|
|
7
7
|
|
|
8
|
-
export type OGIAddonEvent = 'connect' | 'disconnect' | 'configure' | 'authenticate' | 'search' | 'setup';
|
|
8
|
+
export type OGIAddonEvent = 'connect' | 'disconnect' | 'configure' | 'authenticate' | 'search' | 'setup' | 'library-search' | 'game-details' | 'exit';
|
|
9
9
|
export type OGIAddonClientSentEvent = 'response' | 'authenticate' | 'configure' | 'defer-update' | 'notification' | 'input-asked';
|
|
10
10
|
|
|
11
|
-
export type OGIAddonServerSentEvent = 'authenticate' | 'configure' | 'config-update' | 'search' | 'setup' | 'response';
|
|
11
|
+
export type OGIAddonServerSentEvent = 'authenticate' | 'configure' | 'config-update' | 'search' | 'setup' | 'response' | 'library-search' | 'game-details';
|
|
12
12
|
export { ConfigurationBuilder, Configuration, EventResponse, SearchResult };
|
|
13
13
|
const defaultPort = 7654;
|
|
14
|
-
|
|
14
|
+
import pjson from '../package.json';
|
|
15
|
+
const version = pjson.version;
|
|
15
16
|
|
|
16
17
|
export interface ClientSentEventTypes {
|
|
17
18
|
response: any;
|
|
@@ -25,13 +26,19 @@ export interface ClientSentEventTypes {
|
|
|
25
26
|
'input-asked': ConfigurationBuilder;
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
export type BasicLibraryInfo = {
|
|
30
|
+
name: string;
|
|
31
|
+
capsuleImage: string;
|
|
32
|
+
appID: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
28
35
|
export interface EventListenerTypes {
|
|
29
36
|
connect: (socket: ws) => void;
|
|
30
37
|
disconnect: (reason: string) => void;
|
|
31
38
|
configure: (config: ConfigurationBuilder) => ConfigurationBuilder;
|
|
32
39
|
response: (response: any) => void;
|
|
33
40
|
authenticate: (config: any) => void;
|
|
34
|
-
search: (query: { type: 'steamapp', text: string }, event: EventResponse<SearchResult[]>) => void;
|
|
41
|
+
search: (query: { type: 'steamapp' | 'internal', text: string }, event: EventResponse<SearchResult[]>) => void;
|
|
35
42
|
setup: (
|
|
36
43
|
data: {
|
|
37
44
|
path: string,
|
|
@@ -42,11 +49,27 @@ export interface EventListenerTypes {
|
|
|
42
49
|
name: string,
|
|
43
50
|
downloadURL: string
|
|
44
51
|
}[],
|
|
45
|
-
|
|
52
|
+
appID: number,
|
|
53
|
+
storefront: 'steam' | 'internal'
|
|
46
54
|
}, event: EventResponse<LibraryInfo>
|
|
47
55
|
) => void;
|
|
56
|
+
'library-search': (query: string, event: EventResponse<BasicLibraryInfo[]>) => void;
|
|
57
|
+
'game-details': (appID: number, event: EventResponse<StoreData>) => void;
|
|
58
|
+
exit: () => void;
|
|
48
59
|
}
|
|
49
60
|
|
|
61
|
+
export interface StoreData {
|
|
62
|
+
name: string;
|
|
63
|
+
publishers: string[];
|
|
64
|
+
developers: string[];
|
|
65
|
+
appID: number;
|
|
66
|
+
releaseDate: string;
|
|
67
|
+
capsuleImage: string;
|
|
68
|
+
coverImage: string;
|
|
69
|
+
basicDescription: string;
|
|
70
|
+
description: string;
|
|
71
|
+
headerImage: string;
|
|
72
|
+
}
|
|
50
73
|
export interface WebsocketMessageClient {
|
|
51
74
|
event: OGIAddonClientSentEvent;
|
|
52
75
|
id?: string;
|
|
@@ -94,10 +117,14 @@ export interface LibraryInfo {
|
|
|
94
117
|
name: string;
|
|
95
118
|
version: string;
|
|
96
119
|
cwd: string;
|
|
97
|
-
|
|
120
|
+
appID: number;
|
|
98
121
|
launchExecutable: string;
|
|
99
122
|
launchArguments?: string;
|
|
100
123
|
capsuleImage: string;
|
|
124
|
+
storefront: 'steam' | 'internal';
|
|
125
|
+
addonsource: string;
|
|
126
|
+
coverImage: string;
|
|
127
|
+
titleImage?: string;
|
|
101
128
|
}
|
|
102
129
|
interface Notification {
|
|
103
130
|
type: 'warning' | 'error' | 'info' | 'success';
|
|
@@ -157,7 +184,8 @@ class OGIAddonWSListener {
|
|
|
157
184
|
}
|
|
158
185
|
this.eventEmitter.emit('disconnect', reason);
|
|
159
186
|
console.log("Disconnected from OGI Addon Server")
|
|
160
|
-
console.
|
|
187
|
+
console.error(reason.toString())
|
|
188
|
+
this.eventEmitter.emit('exit');
|
|
161
189
|
this.socket.close();
|
|
162
190
|
});
|
|
163
191
|
|
|
@@ -199,12 +227,11 @@ class OGIAddonWSListener {
|
|
|
199
227
|
let searchResultEvent = new EventResponse<SearchResult[]>((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
200
228
|
this.eventEmitter.emit('search', message.args, searchResultEvent);
|
|
201
229
|
const searchResult = await this.waitForEventToRespond(searchResultEvent);
|
|
202
|
-
console.log(searchResult.data)
|
|
203
230
|
this.respondToMessage(message.id!!, searchResult.data);
|
|
204
231
|
break
|
|
205
232
|
case 'setup':
|
|
206
233
|
let setupEvent = new EventResponse<LibraryInfo>((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
207
|
-
this.eventEmitter.emit('setup', { path: message.args.path,
|
|
234
|
+
this.eventEmitter.emit('setup', { path: message.args.path, appID: message.args.appID, storefront: message.args.storefront, type: message.args.type, name: message.args.name, usedRealDebrid: message.args.usedRealDebrid, multiPartFiles: message.args.multiPartFiles }, setupEvent);
|
|
208
235
|
const interval = setInterval(() => {
|
|
209
236
|
if (setupEvent.resolved) {
|
|
210
237
|
clearInterval(interval);
|
|
@@ -219,11 +246,32 @@ class OGIAddonWSListener {
|
|
|
219
246
|
const setupResult = await this.waitForEventToRespond(setupEvent);
|
|
220
247
|
this.respondToMessage(message.id!!, setupResult.data);
|
|
221
248
|
break
|
|
249
|
+
case 'library-search':
|
|
250
|
+
let librarySearchEvent = new EventResponse<BasicLibraryInfo[]>((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
251
|
+
if (this.eventEmitter.listenerCount('game-details') === 0) {
|
|
252
|
+
this.respondToMessage(message.id!!, []);
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
this.eventEmitter.emit('library-search', message.args, librarySearchEvent);
|
|
256
|
+
const librarySearchResult = await this.waitForEventToRespond(librarySearchEvent);
|
|
257
|
+
this.respondToMessage(message.id!!, librarySearchResult.data);
|
|
258
|
+
break
|
|
259
|
+
case 'game-details':
|
|
260
|
+
let gameDetailsEvent = new EventResponse<StoreData>((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
261
|
+
if (this.eventEmitter.listenerCount('game-details') === 0) {
|
|
262
|
+
this.respondToMessage(message.id!!, { error: 'No event listener for game-details' });
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
this.eventEmitter.emit('game-details', message.args, gameDetailsEvent);
|
|
266
|
+
const gameDetailsResult = await this.waitForEventToRespond(gameDetailsEvent);
|
|
267
|
+
this.respondToMessage(message.id!!, gameDetailsResult.data);
|
|
268
|
+
break
|
|
222
269
|
}
|
|
223
270
|
});
|
|
224
271
|
}
|
|
225
272
|
|
|
226
273
|
private waitForEventToRespond<T>(event: EventResponse<T>): Promise<EventResponse<T>> {
|
|
274
|
+
// check the handlers to see if there even is any
|
|
227
275
|
return new Promise((resolve, reject) => {
|
|
228
276
|
const dataGet = setInterval(() => {
|
|
229
277
|
if (event.resolved) {
|
package/tsconfig.json
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"baseUrl": "./", // Lets you set a base directory to resolve non-absolute module names.
|
|
14
14
|
"esModuleInterop": true, // fixes some issues TS originally had with the ES6 spec where TypeScript treats CommonJS/AMD/UMD modules similar to ES6 module
|
|
15
15
|
"moduleResolution": "node", // Pretty much always node for modern JS. Other option is "classic"
|
|
16
|
+
"resolveJsonModule": true,
|
|
16
17
|
"paths": {}, // A series of entries which re-map imports to lookup locations relative to the baseUrl
|
|
17
18
|
|
|
18
19
|
// Source Map
|