electrobun 1.5.0-beta.1 → 1.6.0-beta.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.
@@ -1,4 +1,8 @@
1
1
  import { ffi, native } from "../proc/native";
2
+ import { homedir, tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { readFileSync } from "node:fs";
5
+ import { OS } from "../../shared/platform";
2
6
 
3
7
  // TODO: move this to a more appropriate namespace
4
8
  export const moveToTrash = (path: string) => {
@@ -267,3 +271,163 @@ export const clipboardClear = (): void => {
267
271
  export const clipboardAvailableFormats = (): string[] => {
268
272
  return ffi.request.clipboardAvailableFormats();
269
273
  };
274
+
275
+ // ============================================================================
276
+ // Paths API — cross-platform OS directories and app-scoped directories
277
+ // ============================================================================
278
+
279
+ const home = homedir();
280
+
281
+ function getLinuxXdgUserDirs(): Record<string, string> {
282
+ try {
283
+ const content = readFileSync(join(home, ".config", "user-dirs.dirs"), "utf-8");
284
+ const dirs: Record<string, string> = {};
285
+ for (const line of content.split("\n")) {
286
+ const trimmed = line.trim();
287
+ if (trimmed.startsWith("#") || !trimmed.includes("=")) continue;
288
+ const eqIdx = trimmed.indexOf("=");
289
+ const key = trimmed.slice(0, eqIdx);
290
+ let value = trimmed.slice(eqIdx + 1);
291
+ // Strip surrounding quotes
292
+ if (value.startsWith('"') && value.endsWith('"')) {
293
+ value = value.slice(1, -1);
294
+ }
295
+ // Substitute $HOME
296
+ value = value.replace(/\$HOME/g, home);
297
+ dirs[key] = value;
298
+ }
299
+ return dirs;
300
+ } catch {
301
+ return {};
302
+ }
303
+ }
304
+
305
+ let _xdgUserDirs: Record<string, string> | undefined;
306
+ function xdgUserDir(key: string, fallbackName: string): string {
307
+ if (OS !== "linux") return "";
308
+ if (!_xdgUserDirs) _xdgUserDirs = getLinuxXdgUserDirs();
309
+ return _xdgUserDirs[key] || join(home, fallbackName);
310
+ }
311
+
312
+ let _versionInfo: { identifier: string; channel: string } | undefined;
313
+ function getVersionInfo(): { identifier: string; channel: string } {
314
+ if (_versionInfo) return _versionInfo;
315
+ try {
316
+ const resourcesDir = "Resources";
317
+ const raw = readFileSync(join("..", resourcesDir, "version.json"), "utf-8");
318
+ const parsed = JSON.parse(raw);
319
+ _versionInfo = { identifier: parsed.identifier, channel: parsed.channel };
320
+ return _versionInfo;
321
+ } catch (error) {
322
+ console.error("Failed to read version.json", error);
323
+ throw error;
324
+ }
325
+ }
326
+
327
+ function getAppDataDir(): string {
328
+ switch (OS) {
329
+ case "macos":
330
+ return join(home, "Library", "Application Support");
331
+ case "win":
332
+ return process.env["LOCALAPPDATA"] || join(home, "AppData", "Local");
333
+ case "linux":
334
+ return process.env["XDG_DATA_HOME"] || join(home, ".local", "share");
335
+ }
336
+ }
337
+
338
+ function getCacheDir(): string {
339
+ switch (OS) {
340
+ case "macos":
341
+ return join(home, "Library", "Caches");
342
+ case "win":
343
+ return process.env["LOCALAPPDATA"] || join(home, "AppData", "Local");
344
+ case "linux":
345
+ return process.env["XDG_CACHE_HOME"] || join(home, ".cache");
346
+ }
347
+ }
348
+
349
+ function getLogsDir(): string {
350
+ switch (OS) {
351
+ case "macos":
352
+ return join(home, "Library", "Logs");
353
+ case "win":
354
+ return process.env["LOCALAPPDATA"] || join(home, "AppData", "Local");
355
+ case "linux":
356
+ return process.env["XDG_STATE_HOME"] || join(home, ".local", "state");
357
+ }
358
+ }
359
+
360
+ function getConfigDir(): string {
361
+ switch (OS) {
362
+ case "macos":
363
+ return join(home, "Library", "Application Support");
364
+ case "win":
365
+ return process.env["APPDATA"] || join(home, "AppData", "Roaming");
366
+ case "linux":
367
+ return process.env["XDG_CONFIG_HOME"] || join(home, ".config");
368
+ }
369
+ }
370
+
371
+ function getUserDir(macName: string, winName: string, xdgKey: string, fallbackName: string): string {
372
+ switch (OS) {
373
+ case "macos":
374
+ return join(home, macName);
375
+ case "win": {
376
+ const userProfile = process.env["USERPROFILE"] || home;
377
+ return join(userProfile, winName);
378
+ }
379
+ case "linux":
380
+ return xdgUserDir(xdgKey, fallbackName);
381
+ }
382
+ }
383
+
384
+ export const paths = {
385
+ get home(): string {
386
+ return home;
387
+ },
388
+ get appData(): string {
389
+ return getAppDataDir();
390
+ },
391
+ get config(): string {
392
+ return getConfigDir();
393
+ },
394
+ get cache(): string {
395
+ return getCacheDir();
396
+ },
397
+ get temp(): string {
398
+ return tmpdir();
399
+ },
400
+ get logs(): string {
401
+ return getLogsDir();
402
+ },
403
+ get documents(): string {
404
+ return getUserDir("Documents", "Documents", "XDG_DOCUMENTS_DIR", "Documents");
405
+ },
406
+ get downloads(): string {
407
+ return getUserDir("Downloads", "Downloads", "XDG_DOWNLOAD_DIR", "Downloads");
408
+ },
409
+ get desktop(): string {
410
+ return getUserDir("Desktop", "Desktop", "XDG_DESKTOP_DIR", "Desktop");
411
+ },
412
+ get pictures(): string {
413
+ return getUserDir("Pictures", "Pictures", "XDG_PICTURES_DIR", "Pictures");
414
+ },
415
+ get music(): string {
416
+ return getUserDir("Music", "Music", "XDG_MUSIC_DIR", "Music");
417
+ },
418
+ get videos(): string {
419
+ return getUserDir("Movies", "Videos", "XDG_VIDEOS_DIR", "Videos");
420
+ },
421
+ get userData(): string {
422
+ const { identifier, channel } = getVersionInfo();
423
+ return join(getAppDataDir(), identifier, channel);
424
+ },
425
+ get userCache(): string {
426
+ const { identifier, channel } = getVersionInfo();
427
+ return join(getCacheDir(), identifier, channel);
428
+ },
429
+ get userLogs(): string {
430
+ const { identifier, channel } = getVersionInfo();
431
+ return join(getLogsDir(), identifier, channel);
432
+ },
433
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "electrobun",
3
- "version": "1.5.0-beta.1",
3
+ "version": "1.6.0-beta.0",
4
4
  "description": "Build ultra fast, tiny, and cross-platform desktop apps with Typescript.",
5
5
  "license": "MIT",
6
6
  "author": "Blackboard Technologies Inc.",