Skip to content

Commit 664b678

Browse files
committed
feat: add AppData path variables and harden resolveModTypePath
- Replace unused userDataPath/documentsPath with three specific AppData variables: appDataLocal, appDataLocalLow, appDataRoaming (Windows only for now) - Wrap resolveModTypePath in try/catch so getPath calls before discovery don't crash on unbound context variables
1 parent bb625fc commit 664b678

2 files changed

Lines changed: 38 additions & 12 deletions

File tree

src/runtime/context-resolver.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ export interface DiscoveryFacts {
1616
arch: 'x64' | 'arm64';
1717
installPath: string;
1818
executablePath: string;
19-
userDataPath?: string;
20-
documentsPath?: string;
19+
appDataLocal?: string; // Windows: %LOCALAPPDATA%
20+
appDataLocalLow?: string; // Windows: %LOCALAPPDATA%/../LocalLow
21+
appDataRoaming?: string; // Windows: %APPDATA%
2122
version?: string;
2223
}
2324

src/runtime/vortex-shim.ts

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -244,16 +244,21 @@ export class GdlRuntime {
244244
}
245245

246246
private resolveModTypePath(mt: ModTypeDecl, ctx: ResolvedContext = this.resolvedCtx ?? {}): string {
247-
if (mt.path.kind === 'literal') return String(mt.path.raw);
248-
if (mt.path.kind === 'interpolated') {
249-
return interpolate(mt.path.template, ctx);
247+
try {
248+
if (mt.path.kind === 'literal') return String(mt.path.raw);
249+
if (mt.path.kind === 'interpolated') {
250+
return interpolate(mt.path.template, ctx);
251+
}
252+
// Branch value: dispatch then recursively resolve the chosen arm against ctx.
253+
const arm = resolveBranch(mt.path, ctx as Record<string, string>) as ResolvableValue;
254+
if (arm.kind === 'literal') return String(arm.raw);
255+
if (arm.kind === 'interpolated') return interpolate(arm.template, ctx);
256+
// Nested branches are uncommon for modType paths but supported for symmetry.
257+
return String(resolveBranch(arm, ctx as Record<string, string>));
258+
} catch {
259+
// Context not yet resolved (getPath called before discovery); return empty.
260+
return '';
250261
}
251-
// Branch value: dispatch then recursively resolve the chosen arm against ctx.
252-
const arm = resolveBranch(mt.path, ctx as Record<string, string>) as ResolvableValue;
253-
if (arm.kind === 'literal') return String(arm.raw);
254-
if (arm.kind === 'interpolated') return interpolate(arm.template, ctx);
255-
// Nested branches are uncommon for modType paths but supported for symmetry.
256-
return String(resolveBranch(arm, ctx as Record<string, string>));
257262
}
258263

259264
private async discover(stores: StoreDecl[]): Promise<DiscoveryFacts | null> {
@@ -264,12 +269,32 @@ export class GdlRuntime {
264269
const found = await util.GameStoreHelper.findByAppId(appIds);
265270
if (!found) return null;
266271
this.discoveredStore = found.gameStoreId;
272+
const os = process.platform === 'win32' ? 'windows' as const
273+
: process.platform === 'darwin' ? 'macos' as const
274+
: 'linux' as const;
275+
276+
// Compute platform-specific AppData paths (Windows only for now).
277+
let appDataLocal: string | undefined;
278+
let appDataLocalLow: string | undefined;
279+
let appDataRoaming: string | undefined;
280+
if (os === 'windows') {
281+
const { homedir } = await import('node:os');
282+
const { join, resolve } = await import('node:path');
283+
const home = homedir();
284+
appDataLocal = process.env.LOCALAPPDATA || join(home, 'AppData', 'Local');
285+
appDataLocalLow = resolve(appDataLocal, '..', 'LocalLow');
286+
appDataRoaming = process.env.APPDATA || join(home, 'AppData', 'Roaming');
287+
}
288+
267289
return {
268290
store: found.gameStoreId,
269-
os: process.platform === 'win32' ? 'windows' : process.platform === 'darwin' ? 'macos' : 'linux',
291+
os,
270292
arch: process.arch === 'arm64' ? 'arm64' : 'x64',
271293
installPath: found.gamePath,
272294
executablePath: found.gamePath, // refined by Vortex later via game.executable()
295+
...(appDataLocal !== undefined && { appDataLocal }),
296+
...(appDataLocalLow !== undefined && { appDataLocalLow }),
297+
...(appDataRoaming !== undefined && { appDataRoaming }),
273298
};
274299
} catch {
275300
return null;

0 commit comments

Comments
 (0)