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/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": "3.0.0",
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"
@@ -1,34 +1 @@
1
- type BaseRequiredFields = {
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 = this.storedConfigTemplate[key].validate(
69
- this.definiteConfig[key]
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, ConfigurationOptionType };
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 interface ConfigurationFile {
4
- [key: string]: ConfigurationOption<string>;
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<N extends string = string>(
14
- option: ConfigurationOption<N>
15
- ): option is StringOption<N> {
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<N extends string = string>(
20
- option: ConfigurationOption<N>
21
- ): option is NumberOption<N> {
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<N extends string = string>(
26
- option: ConfigurationOption<N>
27
- ): option is BooleanOption<N> {
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<N extends string = string>(
32
- option: ConfigurationOption<N>
33
- ): option is ActionOption<N> {
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<N extends string = string> extends ConfigurationOption<N> {
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<N extends string = string> extends ConfigurationOption<N> {
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<N extends string = string> extends ConfigurationOption<N> {
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<N extends string = string> extends ConfigurationOption<N> {
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
+ }