Completed
Push — master ( 2fd774...8b549b )
by Roy
02:57
created

OSPaths_   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 12
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 17
eloc 9
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
// # spell-checker:ignore AllUsersProfile HomeDrive HomePath LocalAppData UserProfile WinDir falsey
2
3
import { Platform } from '../platform-adapters/_base.js';
4
5
/** `OSPaths` (API) Determine common OS/platform paths (home, temp, ...) */
6
// eslint-disable-next-line functional/prefer-type-literal
7
interface OSPaths {
8
	/** Create an `OSPaths` object (`new` is optional). */
9
	// eslint-disable-next-line @typescript-eslint/no-misused-new
10
	new (): OSPaths;
11
	/** Create an `OSPaths` object (`new` is optional). */
12
	(): OSPaths;
13
	/* eslint-disable functional/no-method-signature */
14
	/** Returns the path string of the user's home directory (or `undefined` if the user's home directory is not resolvable). */
15
	home(): string | undefined;
16
	/** Returns the path string of the system's default directory for temporary files. */
17
	temp(): string;
18
	/* eslint-enable functional/no-method-signature */
19
}
20
21
function isEmpty(s: string | null | undefined): boolean {
22
	return !s; // reminder: JS "falsey" == [undefined, null, NaN, 0, '', false]
23
}
24
25
function Adapt(adapter_: Platform.Adapter): { readonly OSPaths: OSPaths } {
26
	const { env, os, path } = adapter_;
27
28
	const isWinOS = /^win/i.test(adapter_.process.platform);
29
30
	function normalizePath(path_: string | undefined): string | undefined {
31
		return path_ ? adapter_.path.normalize(adapter_.path.join(path_, '.')) : void 0;
32
	}
33
34
	function home() {
35
		const posix = () =>
36
			normalizePath((typeof os.homedir === 'function' ? os.homedir() : void 0) || env.get('HOME'));
37
38
		const windows = () => {
39
			const priorityList = [
40
				typeof os.homedir === 'function' ? os.homedir() : void 0,
41
				env.get('USERPROFILE'),
42
				env.get('HOME'),
43
				env.get('HOMEDRIVE') || env.get('HOMEPATH')
44
					? path.join(env.get('HOMEDRIVE') || '', env.get('HOMEPATH') || '')
45
					: void 0,
46
			];
47
			return normalizePath(priorityList.find((v) => !isEmpty(v)));
48
		};
49
50
		return isWinOS ? windows() : posix();
51
	}
52
53
	function temp() {
54
		function joinPathToBase(base: string | undefined, segments: readonly string[]) {
55
			return base ? path.join(base, ...segments) : void 0;
56
		}
57
58
		function posix() {
59
			const fallback = '/tmp';
60
			const priorityList = [
61
				typeof os.tmpdir === 'function' ? os.tmpdir() : void 0,
62
				env.get('TMPDIR'),
63
				env.get('TEMP'),
64
				env.get('TMP'),
65
			];
66
			return normalizePath(priorityList.find((v) => !isEmpty(v))) || fallback;
67
		}
68
69
		function windows() {
70
			const fallback = 'C:\\Temp';
71
			const priorityListLazy = [
72
				os.tmpdir,
73
				() => env.get('TEMP'),
74
				() => env.get('TMP'),
75
				() => joinPathToBase(env.get('LOCALAPPDATA'), ['Temp']),
76
				() => joinPathToBase(home(), ['AppData', 'Local', 'Temp']),
77
				() => joinPathToBase(env.get('ALLUSERSPROFILE'), ['Temp']),
78
				() => joinPathToBase(env.get('SystemRoot'), ['Temp']),
79
				() => joinPathToBase(env.get('windir'), ['Temp']),
80
				() => joinPathToBase(env.get('SystemDrive'), ['\\', 'Temp']),
81
			];
82
			const v = priorityListLazy.find((v) => v && !isEmpty(v()));
83
			return (v && normalizePath(v())) || fallback;
84
		}
85
86
		return isWinOS ? windows() : posix();
87
	}
88
89
	// eslint-disable-next-line functional/no-class
90
	class OSPaths_ {
91
		constructor() {
92
			function OSPaths(): OSPaths {
93
				return new OSPaths_() as OSPaths;
94
			}
95
96
			OSPaths.home = home;
97
			OSPaths.temp = temp;
98
99
			return OSPaths;
100
		}
101
	}
102
103
	return { OSPaths: new OSPaths_() as OSPaths };
104
}
105
106
export type { OSPaths };
107
export { Adapt };
108