ogi-addon 3.0.0 → 4.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.d.cts +2 -31
- package/build/SearchEngine.d.mts +2 -31
- package/build/config/Configuration.cjs.map +1 -1
- package/build/config/Configuration.d.cts +5 -4
- package/build/config/Configuration.d.mts +5 -4
- package/build/config/Configuration.mjs.map +1 -1
- package/build/config/ConfigurationBuilder.cjs +2 -2
- package/build/config/ConfigurationBuilder.cjs.map +1 -1
- package/build/config/ConfigurationBuilder.d.cts +13 -15
- package/build/config/ConfigurationBuilder.d.mts +13 -15
- package/build/config/ConfigurationBuilder.mjs +2 -2
- package/build/config/ConfigurationBuilder.mjs.map +1 -1
- package/build/extraction.cjs +80 -0
- package/build/extraction.cjs.map +1 -0
- package/build/extraction.d.cts +5 -0
- package/build/extraction.d.mts +5 -0
- package/build/extraction.mjs +78 -0
- package/build/extraction.mjs.map +1 -0
- package/build/main.cjs +91 -169
- package/build/main.cjs.map +1 -1
- package/build/main.d.cts +27 -409
- package/build/main.d.mts +27 -409
- package/build/main.mjs +91 -168
- package/build/main.mjs.map +1 -1
- package/package.json +4 -4
- package/src/SearchEngine.ts +1 -34
- package/src/config/Configuration.ts +6 -8
- package/src/config/ConfigurationBuilder.ts +47 -30
- package/src/extraction.ts +87 -0
- package/src/main.ts +358 -765
- package/tsconfig.json +1 -1
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"module": "./build/main.mjs",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./build/main.cjs",
|
|
6
|
-
"version": "
|
|
6
|
+
"version": "4.0.0",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": {
|
|
9
9
|
"import": {
|
|
@@ -38,21 +38,21 @@
|
|
|
38
38
|
"directory": "packages/ogi-addon"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
+
"@ogi-sdk/connect": "workspace:*",
|
|
41
42
|
"fuse.js": "^7.1.0",
|
|
42
|
-
"ws": "^8.4.0",
|
|
43
43
|
"zod": "^3.23.8"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"auto-build": "tsc -w",
|
|
47
|
-
"build": "tsdown --config tsdown.config.js",
|
|
47
|
+
"build": "tsdown --config tsdown.config.js && bun run --filter '../../packages/addon-server' generate:event-proxy",
|
|
48
48
|
"typecheck": "tsc --noEmit",
|
|
49
49
|
"release": "bun run build && npm publish",
|
|
50
|
+
"format": "prettier --write \"src/**/*.{ts,svelte,json}\"",
|
|
50
51
|
"release-beta": "bun run build && npm publish --tag future"
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|
|
53
54
|
"@types/minimatch": "^6.0.0",
|
|
54
55
|
"@types/node": "^20.14.12",
|
|
55
|
-
"@types/ws": "^8.4.0",
|
|
56
56
|
"prettier": "^3.6.0",
|
|
57
57
|
"tsdown": "^0.20.0-beta.4",
|
|
58
58
|
"typescript": "^5.0.0"
|
package/src/SearchEngine.ts
CHANGED
|
@@ -1,34 +1 @@
|
|
|
1
|
-
type
|
|
2
|
-
name: string;
|
|
3
|
-
manifest?: Record<string, any>;
|
|
4
|
-
/**
|
|
5
|
-
* Update-only hint for OGI's setup stage.
|
|
6
|
-
* When false, OGI keeps existing files in place instead of moving them to `old_files`
|
|
7
|
-
* before running update setup. Defaults to true/undefined behavior.
|
|
8
|
-
*/
|
|
9
|
-
clearOldFilesBeforeUpdate?: boolean;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export type SearchResult = BaseRequiredFields &
|
|
13
|
-
(
|
|
14
|
-
| {
|
|
15
|
-
downloadType: 'torrent' | 'magnet';
|
|
16
|
-
filename: string;
|
|
17
|
-
downloadURL: string;
|
|
18
|
-
}
|
|
19
|
-
| {
|
|
20
|
-
downloadType: 'direct';
|
|
21
|
-
files: {
|
|
22
|
-
name: string;
|
|
23
|
-
downloadURL: string;
|
|
24
|
-
headers?: Record<string, string>;
|
|
25
|
-
}[];
|
|
26
|
-
}
|
|
27
|
-
| {
|
|
28
|
-
downloadType: 'task';
|
|
29
|
-
taskName: string;
|
|
30
|
-
}
|
|
31
|
-
| {
|
|
32
|
-
downloadType: 'request' | 'empty';
|
|
33
|
-
}
|
|
34
|
-
);
|
|
1
|
+
export type { SearchResult } from '@ogi-sdk/connect';
|
|
@@ -10,10 +10,7 @@ import {
|
|
|
10
10
|
isStringOption,
|
|
11
11
|
isActionOption,
|
|
12
12
|
} from './ConfigurationBuilder';
|
|
13
|
-
import type {
|
|
14
|
-
ConfigurationFile,
|
|
15
|
-
ConfigurationOptionType,
|
|
16
|
-
} from './ConfigurationBuilder';
|
|
13
|
+
import type { ConfigurationFile } from './ConfigurationBuilder';
|
|
17
14
|
|
|
18
15
|
interface DefiniteConfig {
|
|
19
16
|
[key: string]: string | number | boolean;
|
|
@@ -65,9 +62,9 @@ export class Configuration {
|
|
|
65
62
|
continue;
|
|
66
63
|
}
|
|
67
64
|
|
|
68
|
-
const result =
|
|
69
|
-
this.
|
|
70
|
-
);
|
|
65
|
+
const result = (
|
|
66
|
+
this.storedConfigTemplate[key] as unknown as ConfigurationOption<string>
|
|
67
|
+
).validate(this.definiteConfig[key]);
|
|
71
68
|
if (!result[0]) {
|
|
72
69
|
erroredKeys.set(key, result[1]);
|
|
73
70
|
}
|
|
@@ -145,4 +142,5 @@ export {
|
|
|
145
142
|
isActionOption,
|
|
146
143
|
};
|
|
147
144
|
|
|
148
|
-
export type { ConfigurationFile,
|
|
145
|
+
export type { ConfigurationFile, ConfigurationOptionWire } from '@ogi-sdk/connect';
|
|
146
|
+
export type { DefiniteConfig };
|
|
@@ -1,8 +1,23 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ActionConfigurationOption,
|
|
3
|
+
BooleanConfigurationOption,
|
|
4
|
+
ConfigurationFile,
|
|
5
|
+
ConfigurationOptionType,
|
|
6
|
+
ConfigurationOptionWire,
|
|
7
|
+
NumberConfigurationOption,
|
|
8
|
+
StringConfigurationOption,
|
|
9
|
+
} from '@ogi-sdk/connect';
|
|
1
10
|
import z, { ZodError } from 'zod';
|
|
2
11
|
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
12
|
+
export type {
|
|
13
|
+
ActionConfigurationOption,
|
|
14
|
+
BooleanConfigurationOption,
|
|
15
|
+
ConfigurationFile,
|
|
16
|
+
ConfigurationOptionType,
|
|
17
|
+
ConfigurationOptionWire,
|
|
18
|
+
NumberConfigurationOption,
|
|
19
|
+
StringConfigurationOption,
|
|
20
|
+
} from '@ogi-sdk/connect';
|
|
6
21
|
|
|
7
22
|
const configValidation = z.object({
|
|
8
23
|
name: z.string().min(1),
|
|
@@ -10,27 +25,27 @@ const configValidation = z.object({
|
|
|
10
25
|
description: z.string().min(1),
|
|
11
26
|
});
|
|
12
27
|
|
|
13
|
-
export function isStringOption
|
|
14
|
-
option:
|
|
15
|
-
): option is
|
|
28
|
+
export function isStringOption(
|
|
29
|
+
option: ConfigurationOptionWire
|
|
30
|
+
): option is StringConfigurationOption {
|
|
16
31
|
return option.type === 'string';
|
|
17
32
|
}
|
|
18
33
|
|
|
19
|
-
export function isNumberOption
|
|
20
|
-
option:
|
|
21
|
-
): option is
|
|
34
|
+
export function isNumberOption(
|
|
35
|
+
option: ConfigurationOptionWire
|
|
36
|
+
): option is NumberConfigurationOption {
|
|
22
37
|
return option.type === 'number';
|
|
23
38
|
}
|
|
24
39
|
|
|
25
|
-
export function isBooleanOption
|
|
26
|
-
option:
|
|
27
|
-
): option is
|
|
40
|
+
export function isBooleanOption(
|
|
41
|
+
option: ConfigurationOptionWire
|
|
42
|
+
): option is BooleanConfigurationOption {
|
|
28
43
|
return option.type === 'boolean';
|
|
29
44
|
}
|
|
30
45
|
|
|
31
|
-
export function isActionOption
|
|
32
|
-
option:
|
|
33
|
-
): option is
|
|
46
|
+
export function isActionOption(
|
|
47
|
+
option: ConfigurationOptionWire
|
|
48
|
+
): option is ActionConfigurationOption {
|
|
34
49
|
return option.type === 'action';
|
|
35
50
|
}
|
|
36
51
|
|
|
@@ -38,11 +53,11 @@ export function isActionOption<N extends string = string>(
|
|
|
38
53
|
* A builder for creating configuration screens. The generic type T accumulates
|
|
39
54
|
* the types of all options added to the builder, enabling type-safe access to
|
|
40
55
|
* the configuration values.
|
|
41
|
-
*
|
|
56
|
+
*
|
|
42
57
|
* @template T - The accumulated type of all configuration options
|
|
43
58
|
*/
|
|
44
59
|
export class ConfigurationBuilder<
|
|
45
|
-
T extends Record<string, string | number | boolean> = {}
|
|
60
|
+
T extends Record<string, string | number | boolean> = {},
|
|
46
61
|
> {
|
|
47
62
|
private options: ConfigurationOption<string>[] = [];
|
|
48
63
|
|
|
@@ -89,7 +104,7 @@ export class ConfigurationBuilder<
|
|
|
89
104
|
}
|
|
90
105
|
|
|
91
106
|
/**
|
|
92
|
-
* Add an action option to the configuration builder and return the builder for chaining.
|
|
107
|
+
* Add an action option to the configuration builder and return the builder for chaining.
|
|
93
108
|
* Action options contribute a boolean to the return type (true if clicked, false if not).
|
|
94
109
|
* You must provide a name, display name, and description for the option.
|
|
95
110
|
* @param option { (option: ActionOption) => ActionOption<K> }
|
|
@@ -115,21 +130,15 @@ export class ConfigurationBuilder<
|
|
|
115
130
|
throw new ZodError(optionData.error.errors);
|
|
116
131
|
}
|
|
117
132
|
|
|
118
|
-
config[option.name] = option;
|
|
133
|
+
config[option.name] = option as unknown as ConfigurationFile[string];
|
|
119
134
|
} else {
|
|
120
|
-
config[option.name] = option;
|
|
135
|
+
config[option.name] = option as unknown as ConfigurationFile[string];
|
|
121
136
|
}
|
|
122
137
|
});
|
|
123
138
|
return config;
|
|
124
139
|
}
|
|
125
140
|
}
|
|
126
141
|
|
|
127
|
-
export type ConfigurationOptionType =
|
|
128
|
-
| 'string'
|
|
129
|
-
| 'number'
|
|
130
|
-
| 'boolean'
|
|
131
|
-
| 'action'
|
|
132
|
-
| 'unset';
|
|
133
142
|
export class ConfigurationOption<N extends string = string> {
|
|
134
143
|
public name: N = '' as N;
|
|
135
144
|
public defaultValue: unknown = '';
|
|
@@ -175,7 +184,9 @@ export class ConfigurationOption<N extends string = string> {
|
|
|
175
184
|
}
|
|
176
185
|
}
|
|
177
186
|
|
|
178
|
-
export class StringOption<
|
|
187
|
+
export class StringOption<
|
|
188
|
+
N extends string = string,
|
|
189
|
+
> extends ConfigurationOption<N> {
|
|
179
190
|
public allowedValues: string[] = [];
|
|
180
191
|
public minTextLength: number = 0;
|
|
181
192
|
public maxTextLength: number = Number.MAX_SAFE_INTEGER;
|
|
@@ -266,7 +277,9 @@ export class StringOption<N extends string = string> extends ConfigurationOption
|
|
|
266
277
|
}
|
|
267
278
|
}
|
|
268
279
|
|
|
269
|
-
export class NumberOption<
|
|
280
|
+
export class NumberOption<
|
|
281
|
+
N extends string = string,
|
|
282
|
+
> extends ConfigurationOption<N> {
|
|
270
283
|
public min: number = 0;
|
|
271
284
|
public max: number = Number.MAX_SAFE_INTEGER;
|
|
272
285
|
public defaultValue: number = 0;
|
|
@@ -332,7 +345,9 @@ export class NumberOption<N extends string = string> extends ConfigurationOption
|
|
|
332
345
|
}
|
|
333
346
|
}
|
|
334
347
|
|
|
335
|
-
export class BooleanOption<
|
|
348
|
+
export class BooleanOption<
|
|
349
|
+
N extends string = string,
|
|
350
|
+
> extends ConfigurationOption<N> {
|
|
336
351
|
public type: ConfigurationOptionType = 'boolean';
|
|
337
352
|
public defaultValue: boolean = false;
|
|
338
353
|
|
|
@@ -362,7 +377,9 @@ export class BooleanOption<N extends string = string> extends ConfigurationOptio
|
|
|
362
377
|
}
|
|
363
378
|
}
|
|
364
379
|
|
|
365
|
-
export class ActionOption<
|
|
380
|
+
export class ActionOption<
|
|
381
|
+
N extends string = string,
|
|
382
|
+
> extends ConfigurationOption<N> {
|
|
366
383
|
public type: ConfigurationOptionType = 'action';
|
|
367
384
|
public manifest: Record<string, unknown> = {};
|
|
368
385
|
public buttonText: string = 'Run';
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
|
|
3
|
+
const s7ZipPath = 'C:\\Program Files\\7-Zip\\7z.exe';
|
|
4
|
+
|
|
5
|
+
function waitForChildProcess(
|
|
6
|
+
childProcess: ReturnType<typeof spawn>,
|
|
7
|
+
errorMessage: string
|
|
8
|
+
): Promise<void> {
|
|
9
|
+
return new Promise<void>((resolve, reject) => {
|
|
10
|
+
childProcess.once('error', reject);
|
|
11
|
+
childProcess.once('close', (code) => {
|
|
12
|
+
if (code !== 0) {
|
|
13
|
+
reject(new Error(errorMessage));
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
resolve();
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function detectUnrarType(): Promise<
|
|
23
|
+
'unrar-free' | 'unrar-nonfree' | 'unknown'
|
|
24
|
+
> {
|
|
25
|
+
const childProcess = spawn('unrar');
|
|
26
|
+
|
|
27
|
+
return await new Promise((resolve, reject) => {
|
|
28
|
+
let output = '';
|
|
29
|
+
|
|
30
|
+
const collectOutput = (data: Buffer) => {
|
|
31
|
+
output += data.toString();
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
childProcess.stdout.on('data', collectOutput);
|
|
35
|
+
childProcess.stderr.on('data', collectOutput);
|
|
36
|
+
childProcess.once('error', reject);
|
|
37
|
+
childProcess.once('close', () => {
|
|
38
|
+
if (output.includes('unrar-free')) {
|
|
39
|
+
resolve('unrar-free');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (output.includes('unrar-nonfree')) {
|
|
44
|
+
resolve('unrar-nonfree');
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
resolve('unknown');
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function extraction(filePath: string, outputDir: string) {
|
|
54
|
+
const lowerCaseFilePath = filePath.toLowerCase();
|
|
55
|
+
|
|
56
|
+
if (process.platform === 'win32') {
|
|
57
|
+
// expect 7zip to be installed, and use 7zip to unrar
|
|
58
|
+
const childProcess = spawn(s7ZipPath, ['x', filePath, '-o', outputDir]);
|
|
59
|
+
return await waitForChildProcess(childProcess, 'Failed to extract file');
|
|
60
|
+
} else if (process.platform === 'linux' || process.platform === 'darwin') {
|
|
61
|
+
if (lowerCaseFilePath.endsWith('.zip')) {
|
|
62
|
+
// expect unzip to be installed, and use unzip to unzip
|
|
63
|
+
const childProcess = spawn('unzip', ['-o', filePath, '-d', outputDir]);
|
|
64
|
+
return await waitForChildProcess(childProcess, 'Failed to unzip file');
|
|
65
|
+
} else if (lowerCaseFilePath.endsWith('.rar')) {
|
|
66
|
+
// check if unrar-nonfree is installed or unrar is installed
|
|
67
|
+
const unrarType = await detectUnrarType();
|
|
68
|
+
|
|
69
|
+
// now use the according unrar version to unrar
|
|
70
|
+
if (unrarType === 'unrar-free') {
|
|
71
|
+
// use unrar-free to unrar
|
|
72
|
+
const childProcess = spawn('unrar', ['-f', '-x', filePath, outputDir]);
|
|
73
|
+
return await waitForChildProcess(childProcess, 'Failed to unrar file');
|
|
74
|
+
} else if (unrarType === 'unrar-nonfree') {
|
|
75
|
+
// use unrar-nonfree to unrar
|
|
76
|
+
const childProcess = spawn('unrar', ['-o', filePath, '-d', outputDir]);
|
|
77
|
+
return await waitForChildProcess(childProcess, 'Failed to unrar file');
|
|
78
|
+
} else {
|
|
79
|
+
throw new Error('Unknown unrar type');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
throw new Error(`Unsupported archive type: ${filePath}`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
throw new Error(`Unsupported platform: ${process.platform}`);
|
|
87
|
+
}
|