Passed
Push — next ( f5c835...060fe5 )
by Roy
02:01
created

src/lib/OSPaths.ts   A

Complexity

Total Complexity 15
Complexity/F 7.5

Size

Lines of Code 94
Function Count 2

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 15
eloc 74
mnd 13
bc 13
fnc 2
dl 0
loc 94
rs 10
bpm 6.5
cpm 7.5
noi 0
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';
4
5
export type OSPaths = {
6
	new (): OSPaths;
7
	(): OSPaths;
8
	readonly home: () => string | undefined;
9
	readonly temp: () => string;
10
};
11
12
function isEmpty(s: string | null | undefined): boolean {
13
	return !s; // reminder: JS "falsey" == [undefined, null, NaN, 0, '', false]
14
}
15
16
export function OSPathsAdaptionBuilder_(adapter_: Platform.Adapter): OSPaths {
17
	const { env, os, path, process } = adapter_;
18
19
	const isWinOS = /^win/i.test(process.platform);
20
21
	function normalizePath(path_: string | undefined): string | undefined {
22
		return path_ ? path.normalize(path.join(path_, '.')) : void 0;
23
	}
24
25
	const posix = () => {
26
		const home = () =>
27
			normalizePath((typeof os.homedir === 'function' ? os.homedir() : void 0) || env.get('HOME'));
28
29
		const temp = () => {
30
			const fallback = '/tmp';
31
			const priorityList = [
32
				typeof os.tmpdir === 'function' ? os.tmpdir() : void 0,
33
				env.get('TMPDIR'),
34
				env.get('TEMP'),
35
				env.get('TMP'),
36
			];
37
			return normalizePath(priorityList.find((v) => !isEmpty(v))) || fallback;
38
		};
39
40
		return { home, temp };
41
	};
42
43
	const windows = () => {
44
		const home = () => {
45
			const priorityList = [
46
				typeof os.homedir === 'function' ? os.homedir() : void 0,
47
				env.get('USERPROFILE'),
48
				env.get('HOME'),
49
				env.get('HOMEDRIVE') || env.get('HOMEPATH')
50
					? path.join(env.get('HOMEDRIVE') || '', env.get('HOMEPATH') || '')
51
					: void 0,
52
			];
53
			return normalizePath(priorityList.find((v) => !isEmpty(v)));
54
		};
55
56
		function joinPathToBase(base: string | undefined, segments: ReadonlyArray<string>) {
57
			return base ? path.join(base, ...segments) : void 0;
58
		}
59
60
		const temp = () => {
61
			const fallback = 'C:\\Temp';
62
			const priorityListLazy = [
63
				os.tmpdir,
64
				() => env.get('TEMP'),
65
				() => env.get('TMP'),
66
				() => joinPathToBase(env.get('LOCALAPPDATA'), ['Temp']),
67
				() => joinPathToBase(home(), ['AppData', 'Local', 'Temp']),
68
				() => joinPathToBase(env.get('ALLUSERSPROFILE'), ['Temp']),
69
				() => joinPathToBase(env.get('SystemRoot'), ['Temp']),
70
				() => joinPathToBase(env.get('windir'), ['Temp']),
71
				() => joinPathToBase(env.get('SystemDrive'), ['\\', 'Temp']),
72
			];
73
			const v = priorityListLazy.find((v) => v && !isEmpty(v()));
74
			return (v && normalizePath(v())) || fallback;
75
		};
76
77
		return { home, temp };
78
	};
79
80
	// eslint-disable-next-line functional/no-class
81
	class OSPaths_ {
82
		constructor() {
83
			const OSPaths = function () {
84
				return new OSPaths_() as OSPaths;
85
			};
86
87
			// Connect to platform-specific API functions by extension
88
			const platformOS = isWinOS ? windows() : posix();
89
			OSPaths.home = platformOS.home;
90
			OSPaths.temp = platformOS.temp;
91
92
			return OSPaths;
93
		}
94
	}
95
96
	return new OSPaths_() as OSPaths;
97
}
98