@simeonradivoev/gameflow-sdk 1.5.1 → 1.5.2
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/README.md +15 -0
- package/build.ts +27 -0
- package/hooks/app.ts +12 -0
- package/hooks/auth.ts +9 -0
- package/hooks/emulators.ts +39 -0
- package/hooks/games.ts +174 -0
- package/hooks/store.ts +10 -0
- package/index.ts +91 -0
- package/package.json +49 -52
- package/sdk.tsconfig.json +22 -0
- package/shared.ts +623 -0
- package/task-queue.ts +307 -0
- package/index.d.ts +0 -1219
package/shared.ts
ADDED
|
@@ -0,0 +1,623 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
|
|
3
|
+
export const settingRegistry = z.registry<{
|
|
4
|
+
dev?: boolean;
|
|
5
|
+
}>();
|
|
6
|
+
|
|
7
|
+
export const SettingsSchema = z.object({
|
|
8
|
+
rommAddress: z.url().optional(),
|
|
9
|
+
rommUser: z.string().default('admin').optional(),
|
|
10
|
+
windowSize: z.object({ width: z.number(), height: z.number() }).optional(),
|
|
11
|
+
windowPosition: z.object({ x: z.number(), y: z.number() }).optional(),
|
|
12
|
+
downloadPath: z.string(),
|
|
13
|
+
launchInFullscreen: z.boolean().default(true),
|
|
14
|
+
disabledPlugins: z.array(z.string()).default([]),
|
|
15
|
+
emulatorResolution: z.enum(['720p', '1080p', '1440p', '4k']).default('720p'),
|
|
16
|
+
emulatorWidescreen: z.boolean().default(true)
|
|
17
|
+
}); export const LocalSettingsSchema = z.object({
|
|
18
|
+
backgroundBlur: z.boolean().default(true).meta({ title: "Background Blur" }),
|
|
19
|
+
backgroundAnimation: z.boolean().default(true).meta({ title: "Background Animation" }),
|
|
20
|
+
theme: z.enum(['dark', 'light', 'auto']).default('auto').meta({ title: "Theme" }),
|
|
21
|
+
soundEffects: z.boolean().default(true).meta({ title: "Sounds" }),
|
|
22
|
+
soundEffectsVolume: z.number().min(0).max(100).default(50).meta({ title: "Sound Volume" }),
|
|
23
|
+
hapticsEffects: z.boolean().default(true).meta({ title: "Haptics" }),
|
|
24
|
+
showRouterDevOptions: z.boolean().default(false).meta({ title: "Show Router Options" }).register(settingRegistry, { dev: true }),
|
|
25
|
+
showQueryDevOptions: z.boolean().default(false).meta({ title: "Show Query Options" }).register(settingRegistry, { dev: true }),
|
|
26
|
+
useGameflowKeyboard: z.boolean().default(true).describe("Show the gameflow on screen keyboard when using a controller").meta({ title: "Use Gameflow Keyboard" }),
|
|
27
|
+
autoKeybaord: z.boolean().default(true).describe("Open on screen keybaord automatically").meta({ title: "Auto Keyboard" })
|
|
28
|
+
});
|
|
29
|
+
export const GameListFilterSchema = z.object({
|
|
30
|
+
platform_source: z.string().optional(),
|
|
31
|
+
platform_slug: z.string().optional(),
|
|
32
|
+
platform_id: z.coerce.number().optional(),
|
|
33
|
+
collection_id: z.coerce.number().optional(),
|
|
34
|
+
collection_source: z.string().optional(),
|
|
35
|
+
limit: z.coerce.number().optional(),
|
|
36
|
+
search: z.string().optional(),
|
|
37
|
+
offset: z.coerce.number().optional(),
|
|
38
|
+
source: z.string().optional(),
|
|
39
|
+
localOnly: z.coerce.boolean().optional(),
|
|
40
|
+
orderBy: z.literal(['added', 'activity', 'name', 'release']).optional(),
|
|
41
|
+
age_ratings: z.union([z.string().array(), z.string().transform(v => [v])]).optional(),
|
|
42
|
+
genres: z.union([z.string().array(), z.string().transform(v => [v])]).optional(),
|
|
43
|
+
keywords: z.union([z.string().array(), z.string().transform(v => [v])]).optional(),
|
|
44
|
+
});
|
|
45
|
+
export const DownloadSourceSchema = z.object({
|
|
46
|
+
id: z.string(),
|
|
47
|
+
name: z.string()
|
|
48
|
+
});
|
|
49
|
+
export const RommLoginDataSchema = z.object({ hostname: z.url(), username: z.string(), password: z.string() });
|
|
50
|
+
export type GameListFilterType = z.infer<typeof GameListFilterSchema>;
|
|
51
|
+
export const DirSchema = z.object({ name: z.string(), parentPath: z.string(), isDirectory: z.boolean() });
|
|
52
|
+
export type DirType = z.infer<typeof DirSchema>;
|
|
53
|
+
export const CustomEmulatorSchema = z.record(z.string(), z.string());
|
|
54
|
+
export const GithubManifestSchema = z.object({
|
|
55
|
+
sha: z.hash('sha1'),
|
|
56
|
+
url: z.url(),
|
|
57
|
+
tree: z.array(z.object({
|
|
58
|
+
path: z.string(),
|
|
59
|
+
mode: z.string(),
|
|
60
|
+
type: z.enum(['blob', 'tree']),
|
|
61
|
+
sha: z.hash('sha1'),
|
|
62
|
+
url: z.url()
|
|
63
|
+
}))
|
|
64
|
+
});
|
|
65
|
+
export const StoreGameSaveSchema = z.object({
|
|
66
|
+
cwd: z.string(),
|
|
67
|
+
globs: z.string().array()
|
|
68
|
+
});
|
|
69
|
+
export const StoreDownloadSchema = z.discriminatedUnion('type', [
|
|
70
|
+
z.object({
|
|
71
|
+
type: z.literal('direct'),
|
|
72
|
+
url: z.url(),
|
|
73
|
+
name: z.string().optional(),
|
|
74
|
+
system: z.string(),
|
|
75
|
+
main: z.string().optional(),
|
|
76
|
+
saves: z.record(z.string(), StoreGameSaveSchema).optional()
|
|
77
|
+
}),
|
|
78
|
+
z.object({
|
|
79
|
+
type: z.literal("itch"),
|
|
80
|
+
path: z.string(),
|
|
81
|
+
name: z.string().optional(),
|
|
82
|
+
system: z.string(),
|
|
83
|
+
saves: z.record(z.string(), StoreGameSaveSchema).optional()
|
|
84
|
+
})
|
|
85
|
+
]);
|
|
86
|
+
export const NewGameSchema = z.object({
|
|
87
|
+
name: z.string(),
|
|
88
|
+
summary: z.string(),
|
|
89
|
+
genres: z.string().regex(/^$|^(\s*\S[^,]*)(\s*,\s*\S[^,]*)*\s*$/, {
|
|
90
|
+
message: "Must be a comma-separated list",
|
|
91
|
+
})
|
|
92
|
+
});
|
|
93
|
+
export const StoreGameSchema = z.object({
|
|
94
|
+
name: z.string(),
|
|
95
|
+
description: z.string(),
|
|
96
|
+
version: z.string(),
|
|
97
|
+
homepage: z.string().optional(),
|
|
98
|
+
keywords: z.string().array().optional(),
|
|
99
|
+
genres: z.string().array().optional(),
|
|
100
|
+
companies: z.string().array().optional(),
|
|
101
|
+
screenshots: z.string().array().optional(),
|
|
102
|
+
covers: z.string().array().optional(),
|
|
103
|
+
igdb_id: z.number().optional(),
|
|
104
|
+
ra_id: z.number().optional(),
|
|
105
|
+
sgdb_id: z.number().optional(),
|
|
106
|
+
first_release_date: z.union([z.number(), z.date()]).optional(),
|
|
107
|
+
player_count: z.string().optional(),
|
|
108
|
+
saves: z.record(z.string(), z.record(z.string(), StoreGameSaveSchema)).optional(),
|
|
109
|
+
downloads: z.record(z.string(), StoreDownloadSchema)
|
|
110
|
+
});
|
|
111
|
+
export const EmulatorPackageSchema = z.object({
|
|
112
|
+
name: z.string(),
|
|
113
|
+
description: z.string(),
|
|
114
|
+
homepage: z.url(),
|
|
115
|
+
logo: z.url(),
|
|
116
|
+
type: z.enum(['emulator']),
|
|
117
|
+
os: z.array(z.enum(['darwin', 'linux', 'win32', 'android'])),
|
|
118
|
+
keywords: z.array(z.string()).optional(),
|
|
119
|
+
downloads: z.record(z.string(), z.array(z.discriminatedUnion('type', [
|
|
120
|
+
z.object({
|
|
121
|
+
type: z.literal(['github', 'gitlab']),
|
|
122
|
+
pattern: z.string(),
|
|
123
|
+
path: z.string(),
|
|
124
|
+
bin: z.string().optional()
|
|
125
|
+
}),
|
|
126
|
+
z.object({
|
|
127
|
+
type: z.literal('direct'),
|
|
128
|
+
url: z.url(),
|
|
129
|
+
bin: z.string().optional()
|
|
130
|
+
}),
|
|
131
|
+
z.object({
|
|
132
|
+
type: z.literal('scoop'),
|
|
133
|
+
url: z.url(),
|
|
134
|
+
bin: z.string().optional()
|
|
135
|
+
})
|
|
136
|
+
]))).optional(),
|
|
137
|
+
systems: z.array(z.string()),
|
|
138
|
+
bios: z.literal(["required", "optional"]).optional()
|
|
139
|
+
});
|
|
140
|
+
export const ScoopPackageSchema = z.object({
|
|
141
|
+
version: z.string(),
|
|
142
|
+
url: z.url().optional(),
|
|
143
|
+
description: z.string(),
|
|
144
|
+
bin: z.string().optional(),
|
|
145
|
+
architecture: z.record(z.string(), z.object({
|
|
146
|
+
url: z.url(),
|
|
147
|
+
hash: z.string().optional(),
|
|
148
|
+
extract_dir: z.string().optional()
|
|
149
|
+
})).optional()
|
|
150
|
+
});
|
|
151
|
+
export const SystemInfoSchema = z.object({
|
|
152
|
+
battery: z.object({
|
|
153
|
+
percent: z.number(),
|
|
154
|
+
isCharging: z.boolean(),
|
|
155
|
+
acConnected: z.boolean(),
|
|
156
|
+
hasBattery: z.boolean()
|
|
157
|
+
}),
|
|
158
|
+
wifiConnections: z.array(z.object({ signalLevel: z.number() })),
|
|
159
|
+
bluetoothDevices: z.array(z.object({ connected: z.boolean() }))
|
|
160
|
+
});
|
|
161
|
+
export const GithubReleaseSchema = z.object({
|
|
162
|
+
id: z.number(),
|
|
163
|
+
tag_name: z.string().optional(),
|
|
164
|
+
url: z.url(),
|
|
165
|
+
body: z.string(),
|
|
166
|
+
assets: z.array(z.object({
|
|
167
|
+
name: z.string(),
|
|
168
|
+
browser_download_url: z.url(),
|
|
169
|
+
content_type: z.string().optional()
|
|
170
|
+
}))
|
|
171
|
+
});
|
|
172
|
+
export const EmulatorDownloadInfoSchema = z.object({
|
|
173
|
+
id: z.string(),
|
|
174
|
+
version: z.string().optional(),
|
|
175
|
+
url: z.url().optional(),
|
|
176
|
+
description: z.string().optional(),
|
|
177
|
+
downloadDate: z.coerce.date(),
|
|
178
|
+
type: z.string()
|
|
179
|
+
});
|
|
180
|
+
export const PluginEntrySchema = z.object({
|
|
181
|
+
downloads: z.object({
|
|
182
|
+
monthly: z.number(),
|
|
183
|
+
weekly: z.number()
|
|
184
|
+
}),
|
|
185
|
+
searchScore: z.number(),
|
|
186
|
+
installed: z.boolean(),
|
|
187
|
+
package: z.object({
|
|
188
|
+
name: z.string(),
|
|
189
|
+
keywords: z.string().array(),
|
|
190
|
+
version: z.string(),
|
|
191
|
+
description: z.string().optional(),
|
|
192
|
+
sanitized_name: z.string(),
|
|
193
|
+
license: z.string().optional(),
|
|
194
|
+
publisher: z.object({
|
|
195
|
+
email: z.string(),
|
|
196
|
+
username: z.string(),
|
|
197
|
+
trustedPublisher: z.object({
|
|
198
|
+
id: z.string(),
|
|
199
|
+
oidcConfigId: z.string()
|
|
200
|
+
}).optional()
|
|
201
|
+
}),
|
|
202
|
+
date: z.coerce.date(),
|
|
203
|
+
links: z.object({
|
|
204
|
+
homepage: z.string().optional(),
|
|
205
|
+
repository: z.string().optional(),
|
|
206
|
+
bugs: z.string().optional(),
|
|
207
|
+
npm: z.url()
|
|
208
|
+
})
|
|
209
|
+
})
|
|
210
|
+
});
|
|
211
|
+
export const PluginBunDetailsSchema = z.object({
|
|
212
|
+
name: z.string(),
|
|
213
|
+
keywords: z.string().array(),
|
|
214
|
+
version: z.string(),
|
|
215
|
+
author: z.object({ name: z.string().optional() }).optional(),
|
|
216
|
+
license: z.string().optional(),
|
|
217
|
+
devDependencies: z.record(z.string(), z.string()).optional(),
|
|
218
|
+
dependencies: z.record(z.string(), z.string()).optional(),
|
|
219
|
+
maintainers: z.object({ name: z.string() }).array().optional(),
|
|
220
|
+
dist: z.object({ unpackedSize: z.number() }),
|
|
221
|
+
description: z.string().optional(),
|
|
222
|
+
_npmUser: z.object({ name: z.string() }).optional()
|
|
223
|
+
});
|
|
224
|
+
export type EmulatorPackageType = z.infer<typeof EmulatorPackageSchema>;
|
|
225
|
+
export type StoreGameType = z.infer<typeof StoreGameSchema>;
|
|
226
|
+
export type StoreDownloadType = z.infer<typeof StoreDownloadSchema>;
|
|
227
|
+
export type SettingsType = z.infer<typeof SettingsSchema>;
|
|
228
|
+
export type LocalSettingsType = z.infer<typeof LocalSettingsSchema>;
|
|
229
|
+
export const PlatformSchema = z.object({ slug: z.string() });
|
|
230
|
+
export type SystemInfoType = z.infer<typeof SystemInfoSchema>;
|
|
231
|
+
export type EmulatorDownloadInfoType = z.infer<typeof EmulatorDownloadInfoSchema>;
|
|
232
|
+
export type DownloadSourceType = z.infer<typeof DownloadSourceSchema>;
|
|
233
|
+
export type PluginEntryType = z.infer<typeof PluginEntrySchema>;
|
|
234
|
+
export type PluginBunDetailsType = z.infer<typeof PluginBunDetailsSchema>;
|
|
235
|
+
|
|
236
|
+
export interface SaveFileChange
|
|
237
|
+
{
|
|
238
|
+
subPath: string | string[];
|
|
239
|
+
isGlob?: true;
|
|
240
|
+
cwd: string;
|
|
241
|
+
shared: boolean;
|
|
242
|
+
fixedSize?: boolean;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export type EmulatorSourceType = 'custom' | 'store' | 'registry' | 'system' | 'static' | 'embedded';
|
|
246
|
+
|
|
247
|
+
export interface EmulatorSourceEntryType
|
|
248
|
+
{
|
|
249
|
+
binPath: string;
|
|
250
|
+
rootPath?: string;
|
|
251
|
+
type: EmulatorSourceType;
|
|
252
|
+
exists: boolean;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export interface FrontEndEmulator
|
|
256
|
+
{
|
|
257
|
+
name: string;
|
|
258
|
+
source: string;
|
|
259
|
+
logo: string;
|
|
260
|
+
systems: EmulatorSystem[];
|
|
261
|
+
description?: string;
|
|
262
|
+
gameCount: number;
|
|
263
|
+
validSources: EmulatorSourceEntryType[];
|
|
264
|
+
integrations: EmulatorSupport[];
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export interface EmulatorSystem { id: string, romm_slug?: string, name: string, iconUrl: string; }
|
|
268
|
+
|
|
269
|
+
export interface FrontEndEmulatorDetailedDownload
|
|
270
|
+
{
|
|
271
|
+
name: string;
|
|
272
|
+
type: string | undefined;
|
|
273
|
+
version?: string;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export interface FrontEndEmulatorDetailed extends FrontEndEmulator
|
|
277
|
+
{
|
|
278
|
+
homepage: string;
|
|
279
|
+
description: string;
|
|
280
|
+
downloads: FrontEndEmulatorDetailedDownload[];
|
|
281
|
+
keywords?: string[];
|
|
282
|
+
screenshots: string[];
|
|
283
|
+
biosRequirement?: "required" | "optional";
|
|
284
|
+
bios?: string[];
|
|
285
|
+
storeDownloadInfo?: { hasUpdate: boolean; version?: string, type: string; description?: string; };
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export interface FrontEndGameTypeDetailedAchievement
|
|
289
|
+
{
|
|
290
|
+
id: string;
|
|
291
|
+
title: string;
|
|
292
|
+
description?: string;
|
|
293
|
+
date?: Date;
|
|
294
|
+
date_hardcode?: Date;
|
|
295
|
+
badge_url?: string;
|
|
296
|
+
display_order: number;
|
|
297
|
+
type?: string;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export interface FrontEndGameTypeDetailedEmulator extends FrontEndEmulator
|
|
301
|
+
{
|
|
302
|
+
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
export interface FrontEndGameTypeDetailed extends Exclude<FrontEndGameTypeWithIds, "metadata">
|
|
306
|
+
{
|
|
307
|
+
summary: string | null;
|
|
308
|
+
fs_size_bytes: number | null;
|
|
309
|
+
missing: boolean;
|
|
310
|
+
local: boolean;
|
|
311
|
+
version?: string | null;
|
|
312
|
+
version_system?: string | null;
|
|
313
|
+
version_source?: string | null;
|
|
314
|
+
metadata: FrontEndGameMetadataDetailed,
|
|
315
|
+
emulators?: FrontEndGameTypeDetailedEmulator[],
|
|
316
|
+
achievements?: {
|
|
317
|
+
unlocked: number;
|
|
318
|
+
total: number;
|
|
319
|
+
entires: FrontEndGameTypeDetailedAchievement[];
|
|
320
|
+
};
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
export interface Drive
|
|
324
|
+
{
|
|
325
|
+
parent: string | null;
|
|
326
|
+
device: string;
|
|
327
|
+
label: string;
|
|
328
|
+
mountPoint: string | null;
|
|
329
|
+
type: string;
|
|
330
|
+
size: number;
|
|
331
|
+
used: number;
|
|
332
|
+
isRemovable: boolean;
|
|
333
|
+
interfaceType: string | null;
|
|
334
|
+
hasWriteAccess: boolean;
|
|
335
|
+
hasReadAccess: boolean;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
export interface DownloadsDrive
|
|
339
|
+
{
|
|
340
|
+
device: string;
|
|
341
|
+
label: string;
|
|
342
|
+
mountPoint: string | null;
|
|
343
|
+
isRemovable: boolean;
|
|
344
|
+
size: number;
|
|
345
|
+
used: number;
|
|
346
|
+
isCurrentlyUsed: boolean;
|
|
347
|
+
unusableReason: 'not_enough_space' | 'already_used' | null;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export interface FrontendNotification
|
|
351
|
+
{
|
|
352
|
+
title?: string;
|
|
353
|
+
message: string;
|
|
354
|
+
type: 'success' | 'error' | 'info' | 'custom';
|
|
355
|
+
icon?: "save" | "upload" | "clock";
|
|
356
|
+
duration?: number;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export interface CommandEntry
|
|
360
|
+
{
|
|
361
|
+
/** The ID of the command. Could be just an index or a string */
|
|
362
|
+
id: string | number;
|
|
363
|
+
/** The front end label for the command. Mainly gotten from ES-DE list */
|
|
364
|
+
label?: string;
|
|
365
|
+
/** Compiled command to be executed */
|
|
366
|
+
command: string | string[];
|
|
367
|
+
/** Environment variables */
|
|
368
|
+
env?: Record<string, string>,
|
|
369
|
+
/** The path the spawned process will start at */
|
|
370
|
+
startDir?: string;
|
|
371
|
+
/** Is the command valid, for example does the executable exists */
|
|
372
|
+
valid: boolean;
|
|
373
|
+
/** Run the command as shell. Defaults is true */
|
|
374
|
+
shell?: boolean;
|
|
375
|
+
/** For what emulator is the command */
|
|
376
|
+
emulator?: string;
|
|
377
|
+
/** Where the emulator came from */
|
|
378
|
+
emulatorSource?: EmulatorSourceType;
|
|
379
|
+
/** Metadata for the command */
|
|
380
|
+
metadata: {
|
|
381
|
+
romPath?: string;
|
|
382
|
+
emulatorBin?: string;
|
|
383
|
+
/** The root directory of the emulator */
|
|
384
|
+
emulatorDir?: string;
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
export interface FrontEndId
|
|
389
|
+
{
|
|
390
|
+
id: string;
|
|
391
|
+
source: string;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Stuff stored in the local sqlite metadata field
|
|
395
|
+
export interface LocalGameMetadata
|
|
396
|
+
{
|
|
397
|
+
genres?: string[],
|
|
398
|
+
companies?: string[],
|
|
399
|
+
game_modes?: string[],
|
|
400
|
+
age_ratings?: string[];
|
|
401
|
+
player_count?: string;
|
|
402
|
+
first_release_date?: number;
|
|
403
|
+
average_rating?: number;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
export interface FrontEndPlatformType
|
|
407
|
+
{
|
|
408
|
+
id: FrontEndId;
|
|
409
|
+
slug: string;
|
|
410
|
+
name: string;
|
|
411
|
+
family_name?: string | null;
|
|
412
|
+
path_cover: string | null;
|
|
413
|
+
game_count: number;
|
|
414
|
+
updated_at: Date;
|
|
415
|
+
hasLocal: boolean;
|
|
416
|
+
paths_screenshots: string[];
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export interface FrontEndGameTypeWithIds extends FrontEndGameType
|
|
420
|
+
{
|
|
421
|
+
igdb_id: number | null;
|
|
422
|
+
ra_id: number | null;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
export interface FrontEndFilterSets
|
|
426
|
+
{
|
|
427
|
+
age_ratings: Set<string>,
|
|
428
|
+
player_counts: Set<string>,
|
|
429
|
+
languages: Set<string>,
|
|
430
|
+
companies: Set<string>,
|
|
431
|
+
genres: Set<string>;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
export interface FrontEndFilterLists
|
|
435
|
+
{
|
|
436
|
+
age_ratings: string[],
|
|
437
|
+
player_counts: string[],
|
|
438
|
+
languages: string[],
|
|
439
|
+
companies: string[],
|
|
440
|
+
genres: string[];
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
export interface FrontEndGameMetadata
|
|
444
|
+
{
|
|
445
|
+
first_release_date: Date | null;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
export interface FrontEndGameMetadataDetailed extends FrontEndGameMetadata
|
|
449
|
+
{
|
|
450
|
+
genres: string[],
|
|
451
|
+
companies: string[],
|
|
452
|
+
game_modes: string[],
|
|
453
|
+
age_ratings: string[];
|
|
454
|
+
player_count: string | null;
|
|
455
|
+
average_rating: number | null;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
export interface FrontEndGameType
|
|
459
|
+
{
|
|
460
|
+
platform_display_name: string | null,
|
|
461
|
+
path_platform_cover: string | null;
|
|
462
|
+
id: FrontEndId,
|
|
463
|
+
source: string | null,
|
|
464
|
+
source_id: string | null,
|
|
465
|
+
path_fs: string | null,
|
|
466
|
+
path_covers: string[],
|
|
467
|
+
last_played: Date | null,
|
|
468
|
+
updated_at: Date,
|
|
469
|
+
metadata: FrontEndGameMetadata,
|
|
470
|
+
slug: string | null,
|
|
471
|
+
name: string | null,
|
|
472
|
+
platform_id: number | null,
|
|
473
|
+
platform_slug: string | null,
|
|
474
|
+
paths_screenshots: string[];
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
export type GameStatusType = 'installed' | 'missing-emulator' | 'error' | 'install' | 'download' | 'extract' | 'playing' | 'queued';
|
|
478
|
+
|
|
479
|
+
export interface GameInstallProgress
|
|
480
|
+
{
|
|
481
|
+
progress?: number;
|
|
482
|
+
status?: GameStatusType;
|
|
483
|
+
details?: string;
|
|
484
|
+
commands?: CommandEntry[];
|
|
485
|
+
error?: any;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
export type JobStatus = 'completed' | 'error' | 'running' | 'queued' | 'aborted';
|
|
489
|
+
export type GameInstallProgressEvent = 'refresh';
|
|
490
|
+
|
|
491
|
+
export interface FrontendPlugin
|
|
492
|
+
{
|
|
493
|
+
name: string;
|
|
494
|
+
displayName?: string;
|
|
495
|
+
description?: string;
|
|
496
|
+
category: string;
|
|
497
|
+
enabled: boolean;
|
|
498
|
+
canDisable: boolean;
|
|
499
|
+
canUninstall: boolean;
|
|
500
|
+
source: PluginSourceType;
|
|
501
|
+
hasSettings: boolean;
|
|
502
|
+
version: string;
|
|
503
|
+
icon?: string;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
export type PluginSourceType = "builtin" | "store";
|
|
507
|
+
|
|
508
|
+
export type KeysWithValueAssignableTo<T, Value> = {
|
|
509
|
+
[K in keyof T]: Exclude<T[K], undefined> extends Value ? K : never;
|
|
510
|
+
}[keyof T];
|
|
511
|
+
|
|
512
|
+
export interface DownloadInfo
|
|
513
|
+
{
|
|
514
|
+
id: string;
|
|
515
|
+
screenshotUrls: string[];
|
|
516
|
+
coverUrl: string;
|
|
517
|
+
platform?: DownloadPlatform;
|
|
518
|
+
slug?: string;
|
|
519
|
+
path_fs?: string;
|
|
520
|
+
main_glob?: string;
|
|
521
|
+
summary?: string;
|
|
522
|
+
name: string;
|
|
523
|
+
last_played?: Date;
|
|
524
|
+
igdb_id?: number;
|
|
525
|
+
ra_id?: number;
|
|
526
|
+
source_id: string;
|
|
527
|
+
system_slug: string;
|
|
528
|
+
extract_path?: string;
|
|
529
|
+
metadata?: any;
|
|
530
|
+
files: DownloadFileEntry[];
|
|
531
|
+
auth?: string;
|
|
532
|
+
version?: string;
|
|
533
|
+
version_source?: string;
|
|
534
|
+
version_system?: string;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
export interface DownloadPlatform
|
|
538
|
+
{
|
|
539
|
+
id: string;
|
|
540
|
+
source: string;
|
|
541
|
+
igdb_id?: number;
|
|
542
|
+
igdb_slug?: string;
|
|
543
|
+
ra_id?: number;
|
|
544
|
+
moby_id?: number;
|
|
545
|
+
slug: string;
|
|
546
|
+
name: string;
|
|
547
|
+
/** Like Sony or Nintendo */
|
|
548
|
+
family_name?: string;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
export interface DownloadFileEntry
|
|
552
|
+
{
|
|
553
|
+
url: URL;
|
|
554
|
+
/** The path of the file, excluding the name */
|
|
555
|
+
file_path: string;
|
|
556
|
+
/** Just the name of the file including the extension */
|
|
557
|
+
file_name: string;
|
|
558
|
+
/** Checksum of the file */
|
|
559
|
+
sha1?: string;
|
|
560
|
+
/** Size in bytes */
|
|
561
|
+
size?: number;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
export interface LocalDownloadFileEntry extends DownloadFileEntry
|
|
565
|
+
{
|
|
566
|
+
/** Exists on the file system */
|
|
567
|
+
exists: boolean;
|
|
568
|
+
/** Matches the checksum */
|
|
569
|
+
matches: boolean;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
export interface FrontEndCollection
|
|
573
|
+
{
|
|
574
|
+
id: FrontEndId;
|
|
575
|
+
name: string;
|
|
576
|
+
description: string;
|
|
577
|
+
path_platform_cover: string | null;
|
|
578
|
+
game_count: number;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
export type EmulatorCapabilities = "saves" | "fullscreen" | "resolution" | "batch" | "states" | "config";
|
|
582
|
+
|
|
583
|
+
export interface EmulatorSupport
|
|
584
|
+
{
|
|
585
|
+
id: string;
|
|
586
|
+
source?: EmulatorSourceEntryType;
|
|
587
|
+
supportLevel?: "partial" | "full";
|
|
588
|
+
capabilities?: EmulatorCapabilities[];
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
export interface GameLookup
|
|
592
|
+
{
|
|
593
|
+
source: string;
|
|
594
|
+
id: string;
|
|
595
|
+
coverUrl: string | null | undefined;
|
|
596
|
+
slug: string | null | undefined;
|
|
597
|
+
screenshotUrls: string[];
|
|
598
|
+
name: string;
|
|
599
|
+
summary: string | null | undefined;
|
|
600
|
+
genres: string[];
|
|
601
|
+
companies: string[];
|
|
602
|
+
game_modes: string[];
|
|
603
|
+
age_ratings: string[];
|
|
604
|
+
player_count: string | undefined;
|
|
605
|
+
first_release_date: number | undefined;
|
|
606
|
+
average_rating: number | undefined;
|
|
607
|
+
keywords: string[];
|
|
608
|
+
igdb_id: number | undefined;
|
|
609
|
+
platforms: {
|
|
610
|
+
id: number;
|
|
611
|
+
name?: string | null;
|
|
612
|
+
displayName: string;
|
|
613
|
+
slug: string;
|
|
614
|
+
}[];
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
export interface AutoSaveChange
|
|
618
|
+
{
|
|
619
|
+
subPath: string;
|
|
620
|
+
cwd: string;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
export type SaveSlots = Record<string, { cwd: string; }>;
|