Completed
Push — next ( 5faad2...98c60d )
by Roy
02:24 queued 50s
created

src/lib/OSPaths.ts   A

Complexity

Total Complexity 16
Complexity/F 2

Size

Lines of Code 112
Function Count 8

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 16
eloc 89
mnd 8
bc 8
fnc 8
dl 0
loc 112
rs 10
bpm 1
cpm 2
noi 0
c 0
b 0
f 0

6 Functions

Rating   Name   Duplication   Size   Complexity  
A OSPaths.ts ➔ isEmpty 0 3 1
B OSPaths.ts ➔ temp 0 39 5
A OSPaths.ts ➔ OSPathsAdaptionBuilder_ 0 13 2
B OSPaths.ts ➔ home 0 22 5
A OSPaths.ts ➔ normalizePath 0 4 2
A OSPaths.ts ➔ isWinOS 0 2 1
1
// # spell-checker:ignore AllUsersProfile HomeDrive HomePath LocalAppData UserProfile WinDir falsey
2
3
import { Platform } from '../platform-adapters/_base';
4
5
/** Determine common OS/platform paths (home, temp, ...) */
6
export 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
// eslint-disable-next-line @typescript-eslint/no-namespace
24
namespace Adapt {
25
	export function isWinOS(adapter_: Platform.Adapter) {
26
		return /^win/i.test(adapter_.process.platform);
27
	}
28
29
	export function normalizePath(adapter_: Platform.Adapter) {
30
		return (path_: string | undefined): string | undefined => {
31
			return path_ ? adapter_.path.normalize(adapter_.path.join(path_, '.')) : void 0;
32
		};
33
	}
34
35
	export function home(adapter_: Platform.Adapter) {
36
		const { env, os, path } = adapter_;
37
38
		const normalizePath = Adapt.normalizePath(adapter_);
39
40
		const posix = () =>
41
			normalizePath((typeof os.homedir === 'function' ? os.homedir() : void 0) || env.get('HOME'));
42
43
		const windows = () => {
44
			const priorityList = [
45
				typeof os.homedir === 'function' ? os.homedir() : void 0,
46
				env.get('USERPROFILE'),
47
				env.get('HOME'),
48
				env.get('HOMEDRIVE') || env.get('HOMEPATH')
49
					? path.join(env.get('HOMEDRIVE') || '', env.get('HOMEPATH') || '')
50
					: void 0,
51
			];
52
			return normalizePath(priorityList.find((v) => !isEmpty(v)));
53
		};
54
55
		return Adapt.isWinOS(adapter_) ? windows : posix;
56
	}
57
58
	export function temp(adapter_: Platform.Adapter) {
59
		const { env, os, path } = adapter_;
60
61
		const normalizePath = Adapt.normalizePath(adapter_);
62
63
		function joinPathToBase(base: string | undefined, segments: readonly string[]) {
64
			return base ? path.join(base, ...segments) : void 0;
65
		}
66
67
		const posix = () => {
68
			const fallback = '/tmp';
69
			const priorityList = [
70
				typeof os.tmpdir === 'function' ? os.tmpdir() : void 0,
71
				env.get('TMPDIR'),
72
				env.get('TEMP'),
73
				env.get('TMP'),
74
			];
75
			return normalizePath(priorityList.find((v) => !isEmpty(v))) || fallback;
76
		};
77
78
		const windows = () => {
79
			const fallback = 'C:\\Temp';
80
			const priorityListLazy = [
81
				os.tmpdir,
82
				() => env.get('TEMP'),
83
				() => env.get('TMP'),
84
				() => joinPathToBase(env.get('LOCALAPPDATA'), ['Temp']),
85
				() => joinPathToBase(Adapt.home(adapter_)(), ['AppData', 'Local', 'Temp']),
86
				() => joinPathToBase(env.get('ALLUSERSPROFILE'), ['Temp']),
87
				() => joinPathToBase(env.get('SystemRoot'), ['Temp']),
88
				() => joinPathToBase(env.get('windir'), ['Temp']),
89
				() => joinPathToBase(env.get('SystemDrive'), ['\\', 'Temp']),
90
			];
91
			const v = priorityListLazy.find((v) => v && !isEmpty(v()));
92
			return (v && normalizePath(v())) || fallback;
93
		};
94
95
		return Adapt.isWinOS(adapter_) ? windows : posix;
96
	}
97
}
98
99
export function OSPathsAdaptionBuilder_(adapter_: Platform.Adapter): OSPaths {
100
	function OSPaths(): OSPaths {
101
		return obj as OSPaths;
102
	}
103
	const home = Adapt.home(adapter_);
104
	const temp = Adapt.temp(adapter_);
105
106
	const obj = Object.assign(OSPaths, {
107
		home,
108
		temp,
109
	}) as OSPaths;
110
	return obj as OSPaths;
111
}
112