Passed
Push — qa ( 47af86...332b24 )
by Roy
01:27
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

2 Functions

Rating   Name   Duplication   Size   Complexity  
A OSPaths.ts ➔ isEmpty 0 3 1
A OSPaths.ts ➔ normalizePath 0 3 2
1
/* eslint complexity: ['error', { max: 10 }] */ // set maximum cyclomatic complexity to 10; ref: <https://eslint.org/docs/rules/complexity>
2
// # spell-checker:ignore AllUsersProfile HomeDrive HomePath LocalAppData UserProfile WinDir cyclomatic falsey
3
4
import * as os from 'os';
5
import * as path from 'path';
6
7
export type OSPaths = {
8
	new (): OSPaths;
9
	(): OSPaths;
10
	readonly home: () => string | undefined;
11
	readonly temp: () => string;
12
};
13
14
const { env } = process;
15
16
const isWinOS = /^win/i.test(process.platform);
17
18
function isEmpty(s: string | null | undefined): boolean {
19
	return !s; // reminder: JS "falsey" == [undefined, null, NaN, 0, '', false]
20
}
21
22
function normalizePath(path_: string | undefined): string | undefined {
23
	return path_ ? path.normalize(path.join(path_, '.')) : void 0;
24
}
25
26
const base = () => {
27
	const home = () =>
28
		normalizePath((typeof os.homedir === 'function' ? os.homedir() : void 0) || env.HOME);
29
30
	const temp = () => {
31
		const fallback = '/tmp';
32
		const priorityList = [
33
			typeof os.tmpdir === 'function' ? os.tmpdir() : void 0,
34
			env.TMPDIR,
35
			env.TEMP,
36
			env.TMP,
37
		];
38
		return normalizePath(priorityList.find((v) => !isEmpty(v))) || fallback;
39
	};
40
41
	return { home, temp };
42
};
43
44
const windows = () => {
45
	const home = () => {
46
		const priorityList = [
47
			typeof os.homedir === 'function' ? os.homedir() : void 0,
48
			env.USERPROFILE,
49
			env.HOME,
50
			env.HOMEDRIVE || env.HOMEPATH ? path.join(env.HOMEDRIVE || '', env.HOMEPATH || '') : void 0,
51
		];
52
		return normalizePath(priorityList.find((v) => !isEmpty(v)));
53
	};
54
55
	const temp = () => {
56
		const fallback = 'C:\\Temp';
57
		const priorityList = [
58
			typeof os.tmpdir === 'function' ? os.tmpdir() : void 0,
59
			env.TEMP,
60
			env.TMP,
61
			env.LOCALAPPDATA ? path.join(env.LOCALAPPDATA, 'Temp') : void 0,
62
			(function (s) {
63
				return s ? path.join(s, 'AppData', 'Local', 'Temp') : void 0;
64
			})(home()),
65
			env.ALLUSERSPROFILE ? path.join(env.ALLUSERSPROFILE, 'Temp') : void 0,
66
			env.SystemRoot ? path.join(env.SystemRoot, 'Temp') : void 0,
67
			env.windir ? path.join(env.windir, 'Temp') : void 0,
68
			env.SystemDrive ? path.join(env.SystemDrive + '\\', 'Temp') : void 0,
69
		];
70
		return normalizePath(priorityList.find((v) => !isEmpty(v))) || fallback;
71
	};
72
73
	return { home, temp };
74
};
75
76
// eslint-disable-next-line functional/no-class
77
class _OSPaths {
78
	constructor() {
79
		const OSPaths = function () {
80
			return new _OSPaths();
81
		};
82
83
		// Connect to platform-specific API functions by extension
84
		const extension = isWinOS ? windows() : base();
85
		OSPaths.home = extension.home;
86
		OSPaths.temp = extension.temp;
87
88
		return OSPaths;
89
	}
90
}
91
92
const default_ = new _OSPaths() as OSPaths;
93
export default default_;
94