Passed
Push — next ( ff7ad3...4d61eb )
by Roy
02:15
created

src/lib/OSPaths.ts   A

Complexity

Total Complexity 11
Complexity/F 3.67

Size

Lines of Code 109
Function Count 3

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 11
eloc 87
mnd 8
bc 8
fnc 3
dl 0
loc 109
rs 10
bpm 2.6666
cpm 3.6666
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
// eslint-disable-next-line @typescript-eslint/no-namespace
17
namespace Adapt {
18
	export const isWinOS = (adapter_: Platform.Adapter) => /^win/i.test(adapter_.process.platform);
19
20
	export const joinPathToBase = (adapter_: Platform.Adapter) => {
21
		return (base: string | undefined, segments: readonly string[]) => {
22
			return base ? adapter_.path.join(base, ...segments) : void 0;
23
		};
24
	};
25
26
	export const normalizePath = (adapter_: Platform.Adapter) => {
27
		return (path_: string | undefined): string | undefined => {
28
			return path_ ? adapter_.path.normalize(adapter_.path.join(path_, '.')) : void 0;
29
		};
30
	};
31
32
	export const home = (adapter_: Platform.Adapter) => {
33
		const { env, os, path } = adapter_;
34
35
		const isWinOS = Adapt.isWinOS(adapter_);
36
		const normalizePath = Adapt.normalizePath(adapter_);
37
38
		const posix = () =>
39
			normalizePath((typeof os.homedir === 'function' ? os.homedir() : void 0) || env.get('HOME'));
40
41
		const windows = () => {
42
			const priorityList = [
43
				typeof os.homedir === 'function' ? os.homedir() : void 0,
44
				env.get('USERPROFILE'),
45
				env.get('HOME'),
46
				env.get('HOMEDRIVE') || env.get('HOMEPATH')
47
					? path.join(env.get('HOMEDRIVE') || '', env.get('HOMEPATH') || '')
48
					: void 0,
49
			];
50
			return normalizePath(priorityList.find((v) => !isEmpty(v)));
51
		};
52
53
		return isWinOS ? windows : posix;
54
	};
55
56
	export const temp = (adapter_: Platform.Adapter) => {
57
		const { env, os } = adapter_;
58
59
		const isWinOS = Adapt.isWinOS(adapter_);
60
		const joinPathToBase = Adapt.joinPathToBase(adapter_);
61
		const normalizePath = Adapt.normalizePath(adapter_);
62
63
		const posix = () => {
64
			const fallback = '/tmp';
65
			const priorityList = [
66
				typeof os.tmpdir === 'function' ? os.tmpdir() : void 0,
67
				env.get('TMPDIR'),
68
				env.get('TEMP'),
69
				env.get('TMP'),
70
			];
71
			return normalizePath(priorityList.find((v) => !isEmpty(v))) || fallback;
72
		};
73
74
		const windows = () => {
75
			const fallback = 'C:\\Temp';
76
			const priorityListLazy = [
77
				os.tmpdir,
78
				() => env.get('TEMP'),
79
				() => env.get('TMP'),
80
				() => joinPathToBase(env.get('LOCALAPPDATA'), ['Temp']),
81
				() => joinPathToBase(Adapt.home(adapter_)(), ['AppData', 'Local', 'Temp']),
82
				() => joinPathToBase(env.get('ALLUSERSPROFILE'), ['Temp']),
83
				() => joinPathToBase(env.get('SystemRoot'), ['Temp']),
84
				() => joinPathToBase(env.get('windir'), ['Temp']),
85
				() => joinPathToBase(env.get('SystemDrive'), ['\\', 'Temp']),
86
			];
87
			const v = priorityListLazy.find((v) => v && !isEmpty(v()));
88
			return (v && normalizePath(v())) || fallback;
89
		};
90
91
		return isWinOS ? windows : posix;
92
	};
93
}
94
95
export function OSPathsAdaptionBuilder_(adapter_: Platform.Adapter): OSPaths {
96
	// eslint-disable-next-line functional/no-class
97
	class OSPaths_ {
98
		constructor() {
99
			const OSPaths = function () {
100
				return new OSPaths_() as OSPaths;
101
			};
102
103
			OSPaths.home = Adapt.home(adapter_);
104
			OSPaths.temp = Adapt.temp(adapter_);
105
106
			return OSPaths;
107
		}
108
	}
109
110
	return new OSPaths_() as OSPaths;
111
}
112