ogi-addon 0.2.1 → 0.3.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/EventResponse.cjs +10 -0
- package/build/EventResponse.cjs.map +1 -1
- package/build/EventResponse.d.cts +11 -0
- package/build/EventResponse.d.ts +11 -0
- package/build/EventResponse.js +10 -0
- package/build/EventResponse.js.map +1 -1
- package/build/config/Configuration.cjs +5 -0
- package/build/config/Configuration.cjs.map +1 -1
- package/build/config/Configuration.js +5 -0
- package/build/config/Configuration.js.map +1 -1
- package/build/config/ConfigurationBuilder.cjs +5 -0
- package/build/config/ConfigurationBuilder.cjs.map +1 -1
- package/build/config/ConfigurationBuilder.d.cts +2 -0
- package/build/config/ConfigurationBuilder.d.ts +2 -0
- package/build/config/ConfigurationBuilder.js +5 -0
- package/build/config/ConfigurationBuilder.js.map +1 -1
- package/build/main.cjs +58 -4
- package/build/main.cjs.map +1 -1
- package/build/main.d.cts +18 -5
- package/build/main.d.ts +18 -5
- package/build/main.js +58 -4
- package/build/main.js.map +1 -1
- package/package.json +49 -49
- package/src/EventResponse.ts +15 -0
- package/src/config/ConfigurationBuilder.ts +6 -0
- package/src/main.ts +63 -8
package/package.json
CHANGED
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "ogi-addon",
|
|
3
|
-
"module": "./build/main.js",
|
|
4
|
-
"type": "module",
|
|
5
|
-
"main": "./build/main.cjs",
|
|
6
|
-
"exports": {
|
|
7
|
-
".": {
|
|
8
|
-
"import": {
|
|
9
|
-
"default": "./build/main.js",
|
|
10
|
-
"types": "./build/main.d.ts"
|
|
11
|
-
},
|
|
12
|
-
"require": {
|
|
13
|
-
"default": "./build/main.cjs",
|
|
14
|
-
"types": "./build/main.d.cts"
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"./config": {
|
|
18
|
-
"import": {
|
|
19
|
-
"default": "./build/config/Configuration.js",
|
|
20
|
-
"types": "./build/config/Configuration.d.ts"
|
|
21
|
-
},
|
|
22
|
-
"require": {
|
|
23
|
-
"default": "./build/config/Configuration.cjs",
|
|
24
|
-
"types": "./build/config/Configuration.d.cts"
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
"typings": "./build/main.d.ts",
|
|
29
|
-
"author": {
|
|
30
|
-
"name": "Nat3z",
|
|
31
|
-
"email": "me@nat3z.com",
|
|
32
|
-
"url": "https://nat3z.com/"
|
|
33
|
-
},
|
|
34
|
-
"version": "0.
|
|
35
|
-
"dependencies": {
|
|
36
|
-
"ws": "^8.4.0",
|
|
37
|
-
"zod": "^3.23.8"
|
|
38
|
-
},
|
|
39
|
-
"scripts": {
|
|
40
|
-
"auto-build": "tsc -w",
|
|
41
|
-
"build": "tsup --config tsup.config.js",
|
|
42
|
-
"release": "bun run build && npm publish"
|
|
43
|
-
},
|
|
44
|
-
"devDependencies": {
|
|
45
|
-
"@types/node": "^20.14.12",
|
|
46
|
-
"@types/ws": "^8.4.0",
|
|
47
|
-
"tsup": "^8.2.3",
|
|
48
|
-
"typescript": "^5.0.0"
|
|
49
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "ogi-addon",
|
|
3
|
+
"module": "./build/main.js",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./build/main.cjs",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"import": {
|
|
9
|
+
"default": "./build/main.js",
|
|
10
|
+
"types": "./build/main.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"require": {
|
|
13
|
+
"default": "./build/main.cjs",
|
|
14
|
+
"types": "./build/main.d.cts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"./config": {
|
|
18
|
+
"import": {
|
|
19
|
+
"default": "./build/config/Configuration.js",
|
|
20
|
+
"types": "./build/config/Configuration.d.ts"
|
|
21
|
+
},
|
|
22
|
+
"require": {
|
|
23
|
+
"default": "./build/config/Configuration.cjs",
|
|
24
|
+
"types": "./build/config/Configuration.d.cts"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"typings": "./build/main.d.ts",
|
|
29
|
+
"author": {
|
|
30
|
+
"name": "Nat3z",
|
|
31
|
+
"email": "me@nat3z.com",
|
|
32
|
+
"url": "https://nat3z.com/"
|
|
33
|
+
},
|
|
34
|
+
"version": "0.3.0",
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"ws": "^8.4.0",
|
|
37
|
+
"zod": "^3.23.8"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"auto-build": "tsc -w",
|
|
41
|
+
"build": "tsup --config tsup.config.js",
|
|
42
|
+
"release": "bun run build && npm publish"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^20.14.12",
|
|
46
|
+
"@types/ws": "^8.4.0",
|
|
47
|
+
"tsup": "^8.2.3",
|
|
48
|
+
"typescript": "^5.0.0"
|
|
49
|
+
}
|
|
50
50
|
}
|
package/src/EventResponse.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
+
import { ConfigurationBuilder } from "./main";
|
|
2
|
+
|
|
1
3
|
export default class EventResponse<T> {
|
|
2
4
|
data: T | undefined = undefined;
|
|
3
5
|
deffered: boolean = false;
|
|
4
6
|
resolved: boolean = false;
|
|
5
7
|
progress: number = 0;
|
|
6
8
|
logs: string[] = [];
|
|
9
|
+
onInputAsked?: (screen: ConfigurationBuilder, name: string, description: string) => Promise<{ [key: string]: boolean | string | number }>;
|
|
10
|
+
|
|
11
|
+
constructor(onInputAsked?: (screen: ConfigurationBuilder, name: string, description: string) => Promise<{ [key: string]: boolean | string | number }>) {
|
|
12
|
+
this.onInputAsked = onInputAsked;
|
|
13
|
+
}
|
|
14
|
+
|
|
7
15
|
|
|
8
16
|
public defer() {
|
|
9
17
|
this.deffered = true;
|
|
@@ -22,5 +30,12 @@ export default class EventResponse<T> {
|
|
|
22
30
|
this.logs.push(message);
|
|
23
31
|
}
|
|
24
32
|
|
|
33
|
+
public async askForInput(name: string, description: string, screen: ConfigurationBuilder) {
|
|
34
|
+
if (!this.onInputAsked) {
|
|
35
|
+
throw new Error('No input asked callback');
|
|
36
|
+
}
|
|
37
|
+
return await this.onInputAsked(screen, name, description);
|
|
38
|
+
}
|
|
39
|
+
|
|
25
40
|
|
|
26
41
|
}
|
|
@@ -100,6 +100,7 @@ export class StringOption extends ConfigurationOption {
|
|
|
100
100
|
public minTextLength: number = 0;
|
|
101
101
|
public maxTextLength: number = Number.MAX_SAFE_INTEGER;
|
|
102
102
|
public defaultValue: string = '';
|
|
103
|
+
public inputType: 'text' | 'file' | 'password' | 'folder' = 'text';
|
|
103
104
|
public type: ConfigurationOptionType = 'string'
|
|
104
105
|
|
|
105
106
|
setAllowedValues(allowedValues: string[]): this {
|
|
@@ -122,6 +123,11 @@ export class StringOption extends ConfigurationOption {
|
|
|
122
123
|
return this;
|
|
123
124
|
}
|
|
124
125
|
|
|
126
|
+
setInputType(inputType: 'text' | 'file' | 'password' | 'folder'): this {
|
|
127
|
+
this.inputType = inputType;
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
130
|
+
|
|
125
131
|
override validate(input: unknown): [ boolean, string ] {
|
|
126
132
|
if (typeof input !== 'string') {
|
|
127
133
|
return [ false, 'Input is not a string' ];
|
package/src/main.ts
CHANGED
|
@@ -6,11 +6,12 @@ import EventResponse from './EventResponse';
|
|
|
6
6
|
import { SearchResult } from './SearchEngine';
|
|
7
7
|
|
|
8
8
|
export type OGIAddonEvent = 'connect' | 'disconnect' | 'configure' | 'authenticate' | 'search' | 'setup';
|
|
9
|
-
export type OGIAddonClientSentEvent = 'response' | 'authenticate' | 'configure' | 'defer-update' | 'notification';
|
|
9
|
+
export type OGIAddonClientSentEvent = 'response' | 'authenticate' | 'configure' | 'defer-update' | 'notification' | 'input-asked';
|
|
10
10
|
|
|
11
|
-
export type OGIAddonServerSentEvent = 'authenticate' | 'configure' | 'config-update' | 'search' | 'setup';
|
|
11
|
+
export type OGIAddonServerSentEvent = 'authenticate' | 'configure' | 'config-update' | 'search' | 'setup' | 'response';
|
|
12
12
|
export { ConfigurationBuilder, Configuration, EventResponse, SearchResult };
|
|
13
13
|
const defaultPort = 7654;
|
|
14
|
+
const version = process.env.npm_package_version;
|
|
14
15
|
|
|
15
16
|
export interface ClientSentEventTypes {
|
|
16
17
|
response: any;
|
|
@@ -21,6 +22,7 @@ export interface ClientSentEventTypes {
|
|
|
21
22
|
progress: number
|
|
22
23
|
};
|
|
23
24
|
notification: Notification;
|
|
25
|
+
'input-asked': ConfigurationBuilder;
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
export interface EventListenerTypes {
|
|
@@ -29,7 +31,7 @@ export interface EventListenerTypes {
|
|
|
29
31
|
configure: (config: ConfigurationBuilder) => ConfigurationBuilder;
|
|
30
32
|
response: (response: any) => void;
|
|
31
33
|
authenticate: (config: any) => void;
|
|
32
|
-
search: (query: { type: 'steamapp'
|
|
34
|
+
search: (query: { type: 'steamapp', text: string }, event: EventResponse<SearchResult[]>) => void;
|
|
33
35
|
setup: (
|
|
34
36
|
data: {
|
|
35
37
|
path: string,
|
|
@@ -40,7 +42,8 @@ export interface EventListenerTypes {
|
|
|
40
42
|
name: string,
|
|
41
43
|
downloadURL: string
|
|
42
44
|
}[],
|
|
43
|
-
|
|
45
|
+
steamAppID: number
|
|
46
|
+
}, event: EventResponse<LibraryInfo>
|
|
44
47
|
) => void;
|
|
45
48
|
}
|
|
46
49
|
|
|
@@ -86,6 +89,16 @@ export default class OGIAddon {
|
|
|
86
89
|
this.addonWSListener.send('notification', [ notification ]);
|
|
87
90
|
}
|
|
88
91
|
}
|
|
92
|
+
|
|
93
|
+
export interface LibraryInfo {
|
|
94
|
+
name: string;
|
|
95
|
+
version: string;
|
|
96
|
+
cwd: string;
|
|
97
|
+
steamAppID: number;
|
|
98
|
+
launchExecutable: string;
|
|
99
|
+
launchArguments?: string;
|
|
100
|
+
capsuleImage: string;
|
|
101
|
+
}
|
|
89
102
|
interface Notification {
|
|
90
103
|
type: 'warning' | 'error' | 'info' | 'success';
|
|
91
104
|
message: string;
|
|
@@ -105,13 +118,15 @@ class OGIAddonWSListener {
|
|
|
105
118
|
this.socket = new ws('ws://localhost:' + defaultPort);
|
|
106
119
|
this.socket.on('open', () => {
|
|
107
120
|
console.log('Connected to OGI Addon Server');
|
|
121
|
+
console.log('OGI Addon Server Version:', version);
|
|
108
122
|
|
|
109
123
|
// Authenticate with OGI Addon Server
|
|
110
124
|
this.socket.send(JSON.stringify({
|
|
111
125
|
event: 'authenticate',
|
|
112
126
|
args: {
|
|
113
127
|
...this.addon.addonInfo,
|
|
114
|
-
secret: process.argv[process.argv.length - 1].split('=')[1]
|
|
128
|
+
secret: process.argv[process.argv.length - 1].split('=')[1],
|
|
129
|
+
ogiVersion: version
|
|
115
130
|
}
|
|
116
131
|
}));
|
|
117
132
|
|
|
@@ -142,12 +157,31 @@ class OGIAddonWSListener {
|
|
|
142
157
|
}
|
|
143
158
|
this.eventEmitter.emit('disconnect', reason);
|
|
144
159
|
console.log("Disconnected from OGI Addon Server")
|
|
160
|
+
console.log(reason.toString())
|
|
145
161
|
this.socket.close();
|
|
146
162
|
});
|
|
147
163
|
|
|
148
164
|
this.registerMessageReceiver();
|
|
149
165
|
}
|
|
150
166
|
|
|
167
|
+
private async userInputAsked(configBuilt: ConfigurationBuilder, name: string, description: string, socket: WebSocket): Promise<{ [key: string]: number | boolean | string }> {
|
|
168
|
+
const config = configBuilt.build(false);
|
|
169
|
+
const id = Math.random().toString(36).substring(7);
|
|
170
|
+
if (!socket) {
|
|
171
|
+
return {};
|
|
172
|
+
}
|
|
173
|
+
socket.send(JSON.stringify({
|
|
174
|
+
event: 'input-asked',
|
|
175
|
+
args: {
|
|
176
|
+
config,
|
|
177
|
+
name,
|
|
178
|
+
description
|
|
179
|
+
},
|
|
180
|
+
id: id
|
|
181
|
+
}));
|
|
182
|
+
return await this.waitForResponseFromServer(id);
|
|
183
|
+
}
|
|
184
|
+
|
|
151
185
|
private registerMessageReceiver() {
|
|
152
186
|
this.socket.on('message', async (data: string) => {
|
|
153
187
|
const message: WebsocketMessageServer = JSON.parse(data);
|
|
@@ -162,15 +196,15 @@ class OGIAddonWSListener {
|
|
|
162
196
|
}
|
|
163
197
|
break
|
|
164
198
|
case 'search':
|
|
165
|
-
let searchResultEvent = new EventResponse<SearchResult[]>();
|
|
199
|
+
let searchResultEvent = new EventResponse<SearchResult[]>((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
166
200
|
this.eventEmitter.emit('search', message.args, searchResultEvent);
|
|
167
201
|
const searchResult = await this.waitForEventToRespond(searchResultEvent);
|
|
168
202
|
console.log(searchResult.data)
|
|
169
203
|
this.respondToMessage(message.id!!, searchResult.data);
|
|
170
204
|
break
|
|
171
205
|
case 'setup':
|
|
172
|
-
let setupEvent = new EventResponse<
|
|
173
|
-
this.eventEmitter.emit('setup', { path: message.args.path, type: message.args.type, name: message.args.name, usedRealDebrid: message.args.usedRealDebrid, multiPartFiles: message.args.multiPartFiles }, setupEvent);
|
|
206
|
+
let setupEvent = new EventResponse<LibraryInfo>((screen, name, description) => this.userInputAsked(screen, name, description, this.socket));
|
|
207
|
+
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);
|
|
174
208
|
const interval = setInterval(() => {
|
|
175
209
|
if (setupEvent.resolved) {
|
|
176
210
|
clearInterval(interval);
|
|
@@ -224,6 +258,27 @@ class OGIAddonWSListener {
|
|
|
224
258
|
console.log("dispatched response to " + messageID)
|
|
225
259
|
}
|
|
226
260
|
|
|
261
|
+
public waitForResponseFromServer<T>(messageID: string): Promise<T> {
|
|
262
|
+
return new Promise((resolve) => {
|
|
263
|
+
const waiter = (data: string) => {
|
|
264
|
+
const message: WebsocketMessageClient = JSON.parse(data);
|
|
265
|
+
if (message.event !== 'response') {
|
|
266
|
+
this.socket.once('message', waiter);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
console.log("received response from " + messageID)
|
|
270
|
+
|
|
271
|
+
if (message.id === messageID) {
|
|
272
|
+
resolve(message.args);
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
this.socket.once('message', waiter);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
this.socket.once('message', waiter);
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
227
282
|
public send(event: OGIAddonClientSentEvent, args: Parameters<ClientSentEventTypes[OGIAddonClientSentEvent]>) {
|
|
228
283
|
this.socket.send(JSON.stringify({
|
|
229
284
|
event,
|