Passed
Push — master ( d1b4cc...c11d29 )
by Roy
01:29
created

src/lib/OSPaths.ts   A

Complexity

Total Complexity 17
Complexity/F 1.89

Size

Lines of Code 106
Function Count 9

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 17
eloc 82
mnd 8
bc 8
fnc 9
dl 0
loc 106
rs 10
bpm 0.8888
cpm 1.8888
noi 0
c 0
b 0
f 0

2 Functions

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