check-disk-space 3.4.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -32
- package/dist/check-disk-space.d.mts +58 -0
- package/dist/check-disk-space.mjs +170 -190
- package/package.json +43 -71
- package/dist/check-disk-space.cjs +0 -210
- package/dist/check-disk-space.d.ts +0 -53
package/README.md
CHANGED
|
@@ -1,53 +1,113 @@
|
|
|
1
|
-
|
|
1
|
+
<h1 align="center">Check disk space</h1>
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
<p align="center">
|
|
4
|
+
<a href="https://github.com/Alex-D/check-disk-space/actions/workflows/test.yml"><img src="https://img.shields.io/github/actions/workflow/status/Alex-D/check-disk-space/test.yml?style=for-the-badge" alt="Minimized & gzipped size ~1kb" /></a>
|
|
5
|
+
<a href="https://bundlejs.com/?q=check-disk-space"><img src="https://img.shields.io/bundlejs/size/check-disk-space.svg?style=for-the-badge" alt="Minimized & gzipped size ~1kb" /></a>
|
|
6
|
+
<a href="https://npmx.dev/package/check-disk-space"><img src="https://img.shields.io/npm/dm/check-disk-space.svg?color=blue&label=npm%20downloads&style=for-the-badge" alt="Downloads" /></a>
|
|
7
|
+
<a href="https://github.com/Alex-D/check-disk-space/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/check-disk-space.svg?color=blue&style=for-the-badge" alt="MIT Licence" /></a>
|
|
8
|
+
</p>
|
|
6
9
|
|
|
10
|
+
<h2 align="center">Supporting check-disk-space</h2>
|
|
11
|
+
|
|
12
|
+
`check-disk-space` is an MIT-licensed open source project and completely free to use.
|
|
13
|
+
You can support its ongoing development by being a backer or a sponsor:
|
|
14
|
+
|
|
15
|
+
- [Become a backer or sponsor on Patreon](https://www.patreon.com/alexandredemode)
|
|
16
|
+
- [One-time donation via PayPal](https://www.paypal.me/demodealexandre/20eur)
|
|
17
|
+
|
|
18
|
+
---
|
|
7
19
|
|
|
8
20
|
## Introduction
|
|
9
21
|
|
|
10
|
-
|
|
22
|
+
A light multi-platform disk space checker without any third party compatible with Node.js, Bun and Deno.
|
|
11
23
|
|
|
12
|
-
- Works on Linux
|
|
24
|
+
- Works on **Linux**, **macOS** and **Windows**
|
|
13
25
|
- Take care of mounting points on unix-like systems
|
|
14
|
-
-
|
|
26
|
+
- Zero dependencies
|
|
15
27
|
- TypeScript support
|
|
16
28
|
|
|
17
|
-
|
|
18
29
|
## Install
|
|
19
30
|
|
|
20
|
-
|
|
21
|
-
|
|
31
|
+
| Package manager | Command |
|
|
32
|
+
| --------------- | ------------------------------------- |
|
|
33
|
+
| Vite+ | `vp add check-disk-space` |
|
|
34
|
+
| pnpm | `pnpm add check-disk-space` |
|
|
35
|
+
| npm | `npm install check-disk-space --save` |
|
|
36
|
+
| yarn | `yarn add check-disk-space` |
|
|
37
|
+
| bun | `bun add check-disk-space` |
|
|
38
|
+
| deno | `deno add npm:check-disk-space` |
|
|
22
39
|
|
|
23
40
|
## Usage
|
|
24
41
|
|
|
25
42
|
```js
|
|
26
|
-
|
|
27
|
-
|
|
43
|
+
import { checkDiskSpace } from "check-disk-space";
|
|
44
|
+
// Or with require
|
|
45
|
+
const { checkDiskSpace } = require("check-disk-space");
|
|
28
46
|
|
|
29
|
-
|
|
30
|
-
const checkDiskSpace = require('check-disk-space').default
|
|
47
|
+
let yourPath = "";
|
|
31
48
|
|
|
32
49
|
// On Windows
|
|
33
|
-
|
|
34
|
-
console.log(diskSpace)
|
|
35
|
-
// {
|
|
36
|
-
// diskPath: 'C:',
|
|
37
|
-
// free: 12345678,
|
|
38
|
-
// size: 98756432
|
|
39
|
-
// }
|
|
40
|
-
// Note: `free` and `size` are in bytes
|
|
41
|
-
})
|
|
50
|
+
yourPath = "C:/your/path";
|
|
42
51
|
|
|
43
52
|
// On Linux or macOS
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
+
yourPath = "/mnt/mydisk";
|
|
54
|
+
|
|
55
|
+
checkDiskSpace(yourPath).then((diskSpace) => {
|
|
56
|
+
console.log(diskSpace);
|
|
57
|
+
// {
|
|
58
|
+
// diskPath: 'C:', (or '/' on Linux/macOS)
|
|
59
|
+
// free: 12345678,
|
|
60
|
+
// size: 98756432
|
|
61
|
+
// }
|
|
62
|
+
// Note: `free` and `size` are in bytes
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Input
|
|
67
|
+
|
|
68
|
+
- `directoryPath` (string)
|
|
69
|
+
- Must be a valid path depending on the OS
|
|
70
|
+
- Can be a non-existent directory: the lib will automatically search the first existing parent folder to find the right disk to check
|
|
71
|
+
|
|
72
|
+
### Output
|
|
73
|
+
|
|
74
|
+
- `diskPath` (string)
|
|
75
|
+
- on Windows, it's always the disk letter
|
|
76
|
+
- on UNIX like, it depends on the mount path of the disk, so it's not necessarily `'/'`
|
|
77
|
+
- `free` (number)
|
|
78
|
+
- in bytes
|
|
79
|
+
- available space on the disk on which the path to check is stored on
|
|
80
|
+
- `size` (number)
|
|
81
|
+
- in bytes
|
|
82
|
+
- total size of the disk on which the path to check is stored on
|
|
83
|
+
|
|
84
|
+
## Migrating from v3.x
|
|
85
|
+
|
|
86
|
+
Migrates to ESM and does not use `default` export anymore.
|
|
87
|
+
|
|
88
|
+
```diff
|
|
89
|
+
- import checkDiskSpace from "check-disk-space";
|
|
90
|
+
+ import { checkDiskSpace } from "check-disk-space";
|
|
53
91
|
```
|
|
92
|
+
|
|
93
|
+
```diff
|
|
94
|
+
- const checkDiskSpace = require("check-disk-space").default;
|
|
95
|
+
+ import { checkDiskSpace } from "check-disk-space";
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Compatibility
|
|
99
|
+
|
|
100
|
+
All of this is fully tested in the CI.
|
|
101
|
+
|
|
102
|
+
### Supported engines
|
|
103
|
+
|
|
104
|
+
- Node 18+
|
|
105
|
+
- Bun 1.3+
|
|
106
|
+
- Deno 2.5+ (needs `sys`, `read`, `env` and `run` access)
|
|
107
|
+
|
|
108
|
+
### Operating Systems
|
|
109
|
+
|
|
110
|
+
- UNIX like, based on the `df` output
|
|
111
|
+
- Linux
|
|
112
|
+
- macOS
|
|
113
|
+
- Windows 7+, based on PowerShell 3 or `wmic` depending on the version and user's rights
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { access } from "node:fs/promises";
|
|
2
|
+
import { normalize, sep } from "node:path";
|
|
3
|
+
//#region src/errors/invalidPathError.d.ts
|
|
4
|
+
declare class InvalidPathError extends Error {
|
|
5
|
+
name: string;
|
|
6
|
+
constructor(message?: string);
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/errors/noMatchError.d.ts
|
|
10
|
+
declare class NoMatchError extends Error {
|
|
11
|
+
name: string;
|
|
12
|
+
constructor(message?: string);
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/types/dependencies.d.ts
|
|
16
|
+
type Dependencies = {
|
|
17
|
+
platform: NodeJS.Platform;
|
|
18
|
+
release: string;
|
|
19
|
+
fsAccess: typeof access;
|
|
20
|
+
pathNormalize: typeof normalize;
|
|
21
|
+
pathSep: typeof sep;
|
|
22
|
+
cpExecFile: (file: string, args: ReadonlyArray<string> | undefined | null, options: {
|
|
23
|
+
windowsHide: true;
|
|
24
|
+
}) => Promise<{
|
|
25
|
+
stdout: string;
|
|
26
|
+
stderr: string;
|
|
27
|
+
}>;
|
|
28
|
+
};
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region src/functions/getFirstExistingParentPath.d.ts
|
|
31
|
+
/**
|
|
32
|
+
* Get the first existing parent path
|
|
33
|
+
*
|
|
34
|
+
* @param directoryPath - The file/folder path from where we want to know disk space
|
|
35
|
+
* @param dependencies - Dependencies container
|
|
36
|
+
*/
|
|
37
|
+
declare function getFirstExistingParentPath(directoryPath: string, dependencies: Dependencies): Promise<string>;
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region src/types/diskSpace.d.ts
|
|
40
|
+
/**
|
|
41
|
+
* `free` and `size` are in bytes
|
|
42
|
+
*/
|
|
43
|
+
type DiskSpace = {
|
|
44
|
+
diskPath: string;
|
|
45
|
+
free: number;
|
|
46
|
+
size: number;
|
|
47
|
+
};
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region src/index.d.ts
|
|
50
|
+
/**
|
|
51
|
+
* Check disk space
|
|
52
|
+
*
|
|
53
|
+
* @param directoryPath - The file/folder path from where we want to know disk space
|
|
54
|
+
* @param dependencies - Dependencies container
|
|
55
|
+
*/
|
|
56
|
+
declare function checkDiskSpace(directoryPath: string, dependencies?: Dependencies): Promise<DiskSpace>;
|
|
57
|
+
//#endregion
|
|
58
|
+
export { type Dependencies, type DiskSpace, InvalidPathError, NoMatchError, checkDiskSpace, getFirstExistingParentPath };
|
|
@@ -1,203 +1,183 @@
|
|
|
1
|
-
import { execFile } from
|
|
2
|
-
import { access } from
|
|
3
|
-
import { release } from
|
|
4
|
-
import { normalize, sep } from
|
|
5
|
-
import { platform } from
|
|
6
|
-
import { promisify } from
|
|
7
|
-
|
|
8
|
-
class InvalidPathError extends Error {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class NoMatchError extends Error {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { access } from "node:fs/promises";
|
|
3
|
+
import { release } from "node:os";
|
|
4
|
+
import { normalize, sep } from "node:path";
|
|
5
|
+
import { platform } from "node:process";
|
|
6
|
+
import { promisify } from "node:util";
|
|
7
|
+
//#region src/errors/invalidPathError.ts
|
|
8
|
+
var InvalidPathError = class InvalidPathError extends Error {
|
|
9
|
+
name = "InvalidPathError";
|
|
10
|
+
constructor(message) {
|
|
11
|
+
super(message);
|
|
12
|
+
Object.setPrototypeOf(this, InvalidPathError.prototype);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/errors/noMatchError.ts
|
|
17
|
+
var NoMatchError = class NoMatchError extends Error {
|
|
18
|
+
name = "NoMatchError";
|
|
19
|
+
constructor(message) {
|
|
20
|
+
super(message);
|
|
21
|
+
Object.setPrototypeOf(this, NoMatchError.prototype);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/functions/isDirectoryExisting.ts
|
|
26
26
|
/**
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
* Tells if directory exists
|
|
28
|
+
*
|
|
29
|
+
* @param directoryPath - The file/folder path
|
|
30
|
+
* @param dependencies - Dependencies container
|
|
31
|
+
*/
|
|
32
32
|
async function isDirectoryExisting(directoryPath, dependencies) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
33
|
+
try {
|
|
34
|
+
await dependencies.fsAccess(directoryPath);
|
|
35
|
+
return Promise.resolve(true);
|
|
36
|
+
} catch (_error) {
|
|
37
|
+
return Promise.resolve(false);
|
|
38
|
+
}
|
|
40
39
|
}
|
|
41
|
-
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/functions/getFirstExistingParentPath.ts
|
|
42
42
|
/**
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
* Get the first existing parent path
|
|
44
|
+
*
|
|
45
|
+
* @param directoryPath - The file/folder path from where we want to know disk space
|
|
46
|
+
* @param dependencies - Dependencies container
|
|
47
|
+
*/
|
|
48
48
|
async function getFirstExistingParentPath(directoryPath, dependencies) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
let parentDirectoryPath = directoryPath;
|
|
50
|
+
let parentDirectoryFound = await isDirectoryExisting(parentDirectoryPath, dependencies);
|
|
51
|
+
while (!parentDirectoryFound) {
|
|
52
|
+
const newParentDirectoryPath = dependencies.pathNormalize(parentDirectoryPath + "/..");
|
|
53
|
+
if (parentDirectoryPath === newParentDirectoryPath || newParentDirectoryPath === ".") return Promise.reject(new NoMatchError("Unable to find an existing parent path."));
|
|
54
|
+
parentDirectoryPath = newParentDirectoryPath;
|
|
55
|
+
parentDirectoryFound = await isDirectoryExisting(parentDirectoryPath, dependencies);
|
|
56
|
+
}
|
|
57
|
+
return parentDirectoryPath;
|
|
56
58
|
}
|
|
57
|
-
|
|
59
|
+
//#endregion
|
|
60
|
+
//#region src/functions/hasPowerShell3.ts
|
|
58
61
|
/**
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
* Tell if PowerShell 3 is available based on Windows version
|
|
63
|
+
*
|
|
64
|
+
* Note: 6.* is Windows 7
|
|
65
|
+
* Note: PowerShell 3 is natively available since Windows 8
|
|
66
|
+
*
|
|
67
|
+
* @param dependencies - Dependencies Injection Container
|
|
68
|
+
*/
|
|
66
69
|
async function hasPowerShell3(dependencies) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
catch (error) {
|
|
76
|
-
return false;
|
|
77
|
-
}
|
|
70
|
+
if (parseInt(dependencies.release.split(".")[0], 10) <= 6) return false;
|
|
71
|
+
try {
|
|
72
|
+
await dependencies.cpExecFile("where", ["powershell"], { windowsHide: true });
|
|
73
|
+
return true;
|
|
74
|
+
} catch (_error) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
78
77
|
}
|
|
79
|
-
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region src/index.ts
|
|
80
80
|
/**
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
* Check disk space
|
|
82
|
+
*
|
|
83
|
+
* @param directoryPath - The file/folder path from where we want to know disk space
|
|
84
|
+
* @param dependencies - Dependencies container
|
|
85
|
+
*/
|
|
86
86
|
function checkDiskSpace(directoryPath, dependencies = {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
platform,
|
|
88
|
+
release: release(),
|
|
89
|
+
fsAccess: access,
|
|
90
|
+
pathNormalize: normalize,
|
|
91
|
+
pathSep: sep,
|
|
92
|
+
cpExecFile: promisify(execFile)
|
|
93
93
|
}) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
return Promise.reject(new InvalidPathError(`The following path is invalid (should start by ${dependencies.pathSep}): ${directoryPath}`));
|
|
182
|
-
}
|
|
183
|
-
const pathToCheck = await getFirstExistingParentPath(directoryPath, dependencies);
|
|
184
|
-
return check([
|
|
185
|
-
'df',
|
|
186
|
-
'-Pk',
|
|
187
|
-
'--',
|
|
188
|
-
pathToCheck,
|
|
189
|
-
], () => true, // We should only get one line, so we did not need to filter
|
|
190
|
-
{
|
|
191
|
-
diskPath: 5,
|
|
192
|
-
free: 3,
|
|
193
|
-
size: 1,
|
|
194
|
-
}, 1024);
|
|
195
|
-
}
|
|
196
|
-
// Call the right check depending on the OS
|
|
197
|
-
if (dependencies.platform === 'win32') {
|
|
198
|
-
return checkWin32(directoryPath);
|
|
199
|
-
}
|
|
200
|
-
return checkUnix(directoryPath);
|
|
94
|
+
/**
|
|
95
|
+
* Maps command output to a normalized object {diskPath, free, size}
|
|
96
|
+
*
|
|
97
|
+
* @param stdout - The command output
|
|
98
|
+
* @param filter - To filter drives (only used for win32)
|
|
99
|
+
* @param mapping - Map between column index and normalized column name
|
|
100
|
+
* @param coefficient - The size coefficient to get bytes instead of kB
|
|
101
|
+
*/
|
|
102
|
+
function mapOutput(stdout, filter, mapping, coefficient) {
|
|
103
|
+
const parsed = stdout.split("\n").map((line) => line.trim()).filter((line) => line.length !== 0).slice(1).map((line) => line.split(/\s+(?=[\d/])/));
|
|
104
|
+
const filtered = parsed.filter(filter);
|
|
105
|
+
if (filtered.length === 0) {
|
|
106
|
+
let errorContext = "No disk matches the path.";
|
|
107
|
+
if (parsed.length === 0) errorContext = "Nothing was returned by the command.";
|
|
108
|
+
throw new NoMatchError(errorContext);
|
|
109
|
+
}
|
|
110
|
+
const columnsCount = parsed.reduce((maxColumnCount, currentLine) => {
|
|
111
|
+
return Math.max(currentLine.length, maxColumnCount);
|
|
112
|
+
}, 0);
|
|
113
|
+
const diskData = filtered[0];
|
|
114
|
+
const indexOffset = diskData.length - columnsCount;
|
|
115
|
+
return {
|
|
116
|
+
diskPath: diskData[mapping.diskPath + indexOffset],
|
|
117
|
+
free: parseInt(diskData[mapping.free + indexOffset], 10) * coefficient,
|
|
118
|
+
size: parseInt(diskData[mapping.size + indexOffset], 10) * coefficient
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Run the command and do common things between win32 and Unix
|
|
123
|
+
*
|
|
124
|
+
* @param cmd - The command to execute
|
|
125
|
+
* @param filter - To filter drives (only used for win32)
|
|
126
|
+
* @param mapping - Map between column index and normalized column name
|
|
127
|
+
* @param coefficient - The size coefficient to get bytes instead of kB
|
|
128
|
+
*/
|
|
129
|
+
async function check(cmd, filter, mapping, coefficient = 1) {
|
|
130
|
+
const [file, ...args] = cmd;
|
|
131
|
+
/* istanbul ignore if */
|
|
132
|
+
if (file === void 0) return Promise.reject(/* @__PURE__ */ new Error("cmd must contain at least one item"));
|
|
133
|
+
try {
|
|
134
|
+
const { stdout } = await dependencies.cpExecFile(file, args, { windowsHide: true });
|
|
135
|
+
return mapOutput(stdout, filter, mapping, coefficient);
|
|
136
|
+
} catch (error) {
|
|
137
|
+
return Promise.reject(error);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Build the check call for win32
|
|
142
|
+
*
|
|
143
|
+
* @param directoryPath - The file/folder path from where we want to know disk space
|
|
144
|
+
*/
|
|
145
|
+
async function checkWin32(directoryPath) {
|
|
146
|
+
if (directoryPath.charAt(1) !== ":") return Promise.reject(new InvalidPathError(`The following path is invalid (should be X:\\...): ${directoryPath}`));
|
|
147
|
+
return check(await hasPowerShell3(dependencies) ? ["powershell", "Get-CimInstance -ClassName Win32_LogicalDisk | Select-Object Caption, FreeSpace, Size"] : [
|
|
148
|
+
"wmic",
|
|
149
|
+
"logicaldisk",
|
|
150
|
+
"get",
|
|
151
|
+
"size,freespace,caption"
|
|
152
|
+
], (driveData) => {
|
|
153
|
+
const driveLetter = driveData[0];
|
|
154
|
+
return directoryPath.toUpperCase().startsWith(driveLetter.toUpperCase());
|
|
155
|
+
}, {
|
|
156
|
+
diskPath: 0,
|
|
157
|
+
free: 1,
|
|
158
|
+
size: 2
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Build the check call for Unix
|
|
163
|
+
*
|
|
164
|
+
* @param directoryPath - The file/folder path from where we want to know disk space
|
|
165
|
+
*/
|
|
166
|
+
async function checkUnix(directoryPath) {
|
|
167
|
+
if (!dependencies.pathNormalize(directoryPath).startsWith(dependencies.pathSep)) return Promise.reject(new InvalidPathError(`The following path is invalid (should start by ${dependencies.pathSep}): ${directoryPath}`));
|
|
168
|
+
return check([
|
|
169
|
+
"df",
|
|
170
|
+
"-Pk",
|
|
171
|
+
"--",
|
|
172
|
+
await getFirstExistingParentPath(directoryPath, dependencies)
|
|
173
|
+
], () => true, {
|
|
174
|
+
diskPath: 5,
|
|
175
|
+
free: 3,
|
|
176
|
+
size: 1
|
|
177
|
+
}, 1024);
|
|
178
|
+
}
|
|
179
|
+
if (dependencies.platform === "win32") return checkWin32(directoryPath);
|
|
180
|
+
return checkUnix(directoryPath);
|
|
201
181
|
}
|
|
202
|
-
|
|
203
|
-
export { InvalidPathError, NoMatchError, checkDiskSpace
|
|
182
|
+
//#endregion
|
|
183
|
+
export { InvalidPathError, NoMatchError, checkDiskSpace, getFirstExistingParentPath };
|
package/package.json
CHANGED
|
@@ -1,83 +1,55 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "check-disk-space",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Light multi-platform disk space checker without third party for Node.js",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"disk",
|
|
7
|
+
"free",
|
|
8
|
+
"hdd",
|
|
9
|
+
"space"
|
|
10
|
+
],
|
|
11
|
+
"homepage": "https://github.com/Alex-D/check-disk-space#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/Alex-D/check-disk-space/issues"
|
|
14
|
+
},
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"author": "Alex-D <contact@alex-d.fr> (https://alex-d.fr)",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/Alex-D/check-disk-space.git"
|
|
20
|
+
},
|
|
5
21
|
"files": [
|
|
6
22
|
"dist",
|
|
7
23
|
"README.md"
|
|
8
24
|
],
|
|
9
|
-
"
|
|
10
|
-
"module": "./dist/check-disk-space.mjs",
|
|
11
|
-
"types": "./dist/check-disk-space.d.ts",
|
|
25
|
+
"type": "module",
|
|
12
26
|
"exports": {
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"build:lib": "rollup --config",
|
|
19
|
-
"build:dts": "rollup --config rollup.dts.config.mjs",
|
|
20
|
-
"build": "npm-run-all build:lib build:dts",
|
|
21
|
-
"lint": "eslint . --cache",
|
|
22
|
-
"lint:fix": "eslint --fix .",
|
|
23
|
-
"typecheck": "tsc --noEmit",
|
|
24
|
-
"test": "npm-run-all test:coverage lint typecheck",
|
|
25
|
-
"test:unit": "NODE_ENV=test TS_NODE_PROJECT='tsconfig.test.json' ava",
|
|
26
|
-
"test:coverage": "nyc --reporter=lcov --reporter=text npm run test:unit --silent"
|
|
27
|
-
},
|
|
28
|
-
"ava": {
|
|
29
|
-
"files": [
|
|
30
|
-
"test/**",
|
|
31
|
-
"!test/__helpers__/**"
|
|
32
|
-
],
|
|
33
|
-
"extensions": [
|
|
34
|
-
"ts"
|
|
35
|
-
],
|
|
36
|
-
"require": [
|
|
37
|
-
"tsconfig-paths/register",
|
|
38
|
-
"ts-node/register",
|
|
39
|
-
"source-map-support/register"
|
|
40
|
-
]
|
|
41
|
-
},
|
|
42
|
-
"engines": {
|
|
43
|
-
"node": ">=16"
|
|
27
|
+
".": {
|
|
28
|
+
"import": "./dist/check-disk-space.mjs",
|
|
29
|
+
"types": "./dist/check-disk-space.d.mts"
|
|
30
|
+
},
|
|
31
|
+
"./package.json": "./package.json"
|
|
44
32
|
},
|
|
45
33
|
"devDependencies": {
|
|
46
|
-
"@
|
|
47
|
-
"@
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"ava": "5.2.0",
|
|
53
|
-
"eslint": "8.41.0",
|
|
54
|
-
"eslint-plugin-ava": "14.0.0",
|
|
55
|
-
"eslint-plugin-import": "2.27.5",
|
|
56
|
-
"eslint-plugin-simple-import-sort": "10.0.0",
|
|
57
|
-
"npm-run-all": "4.1.5",
|
|
58
|
-
"nyc": "15.1.0",
|
|
59
|
-
"rollup": "3.22.0",
|
|
60
|
-
"rollup-plugin-dts": "5.3.0",
|
|
61
|
-
"source-map-support": "0.5.21",
|
|
62
|
-
"ts-node": "10.9.1",
|
|
63
|
-
"tsconfig-paths": "4.2.0",
|
|
64
|
-
"tslib": "2.5.2",
|
|
65
|
-
"typescript": "5.0.4"
|
|
34
|
+
"@types/node": "^26.6.5",
|
|
35
|
+
"@vitest/coverage-istanbul": "^5.0.5",
|
|
36
|
+
"bumpp": "^12.3.0",
|
|
37
|
+
"typescript": "npm:typescript-native-bridge@^6.0.3-bridge.18.tsgo.7.0.2",
|
|
38
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@1.3.0",
|
|
39
|
+
"vite-plus": "1.3.0"
|
|
66
40
|
},
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
|
|
41
|
+
"devEngines": {
|
|
42
|
+
"packageManager": {
|
|
43
|
+
"name": "pnpm",
|
|
44
|
+
"version": "12.3.4",
|
|
45
|
+
"onFail": "download"
|
|
46
|
+
}
|
|
70
47
|
},
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
"bugs": {
|
|
80
|
-
"url": "https://github.com/Alex-D/check-disk-space/issues"
|
|
81
|
-
},
|
|
82
|
-
"homepage": "https://github.com/Alex-D/check-disk-space#readme"
|
|
83
|
-
}
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "vp pack",
|
|
50
|
+
"dev": "vp pack --watch",
|
|
51
|
+
"dev:all": "pnpm -r --include-workspace-root --parallel dev",
|
|
52
|
+
"test": "vp tests",
|
|
53
|
+
"check": "vp check"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
var node_child_process = require('node:child_process');
|
|
6
|
-
var promises = require('node:fs/promises');
|
|
7
|
-
var node_os = require('node:os');
|
|
8
|
-
var node_path = require('node:path');
|
|
9
|
-
var node_process = require('node:process');
|
|
10
|
-
var node_util = require('node:util');
|
|
11
|
-
|
|
12
|
-
class InvalidPathError extends Error {
|
|
13
|
-
constructor(message) {
|
|
14
|
-
super(message);
|
|
15
|
-
this.name = 'InvalidPathError';
|
|
16
|
-
// Set the prototype explicitly.
|
|
17
|
-
Object.setPrototypeOf(this, InvalidPathError.prototype);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
class NoMatchError extends Error {
|
|
22
|
-
constructor(message) {
|
|
23
|
-
super(message);
|
|
24
|
-
this.name = 'NoMatchError';
|
|
25
|
-
// Set the prototype explicitly.
|
|
26
|
-
Object.setPrototypeOf(this, NoMatchError.prototype);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Tells if directory exists
|
|
32
|
-
*
|
|
33
|
-
* @param directoryPath - The file/folder path
|
|
34
|
-
* @param dependencies - Dependencies container
|
|
35
|
-
*/
|
|
36
|
-
async function isDirectoryExisting(directoryPath, dependencies) {
|
|
37
|
-
try {
|
|
38
|
-
await dependencies.fsAccess(directoryPath);
|
|
39
|
-
return Promise.resolve(true);
|
|
40
|
-
}
|
|
41
|
-
catch (error) {
|
|
42
|
-
return Promise.resolve(false);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Get the first existing parent path
|
|
48
|
-
*
|
|
49
|
-
* @param directoryPath - The file/folder path from where we want to know disk space
|
|
50
|
-
* @param dependencies - Dependencies container
|
|
51
|
-
*/
|
|
52
|
-
async function getFirstExistingParentPath(directoryPath, dependencies) {
|
|
53
|
-
let parentDirectoryPath = directoryPath;
|
|
54
|
-
let parentDirectoryFound = await isDirectoryExisting(parentDirectoryPath, dependencies);
|
|
55
|
-
while (!parentDirectoryFound) {
|
|
56
|
-
parentDirectoryPath = dependencies.pathNormalize(parentDirectoryPath + '/..');
|
|
57
|
-
parentDirectoryFound = await isDirectoryExisting(parentDirectoryPath, dependencies);
|
|
58
|
-
}
|
|
59
|
-
return parentDirectoryPath;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Tell if PowerShell 3 is available based on Windows version
|
|
64
|
-
*
|
|
65
|
-
* Note: 6.* is Windows 7
|
|
66
|
-
* Note: PowerShell 3 is natively available since Windows 8
|
|
67
|
-
*
|
|
68
|
-
* @param dependencies - Dependencies Injection Container
|
|
69
|
-
*/
|
|
70
|
-
async function hasPowerShell3(dependencies) {
|
|
71
|
-
const major = parseInt(dependencies.release.split('.')[0], 10);
|
|
72
|
-
if (major <= 6) {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
try {
|
|
76
|
-
await dependencies.cpExecFile('where', ['powershell'], { windowsHide: true });
|
|
77
|
-
return true;
|
|
78
|
-
}
|
|
79
|
-
catch (error) {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Check disk space
|
|
86
|
-
*
|
|
87
|
-
* @param directoryPath - The file/folder path from where we want to know disk space
|
|
88
|
-
* @param dependencies - Dependencies container
|
|
89
|
-
*/
|
|
90
|
-
function checkDiskSpace(directoryPath, dependencies = {
|
|
91
|
-
platform: node_process.platform,
|
|
92
|
-
release: node_os.release(),
|
|
93
|
-
fsAccess: promises.access,
|
|
94
|
-
pathNormalize: node_path.normalize,
|
|
95
|
-
pathSep: node_path.sep,
|
|
96
|
-
cpExecFile: node_util.promisify(node_child_process.execFile),
|
|
97
|
-
}) {
|
|
98
|
-
// Note: This function contains other functions in order
|
|
99
|
-
// to wrap them in a common context and make unit tests easier
|
|
100
|
-
/**
|
|
101
|
-
* Maps command output to a normalized object {diskPath, free, size}
|
|
102
|
-
*
|
|
103
|
-
* @param stdout - The command output
|
|
104
|
-
* @param filter - To filter drives (only used for win32)
|
|
105
|
-
* @param mapping - Map between column index and normalized column name
|
|
106
|
-
* @param coefficient - The size coefficient to get bytes instead of kB
|
|
107
|
-
*/
|
|
108
|
-
function mapOutput(stdout, filter, mapping, coefficient) {
|
|
109
|
-
const parsed = stdout
|
|
110
|
-
.split('\n') // Split lines
|
|
111
|
-
.map(line => line.trim()) // Trim all lines
|
|
112
|
-
.filter(line => line.length !== 0) // Remove empty lines
|
|
113
|
-
.slice(1) // Remove header
|
|
114
|
-
.map(line => line.split(/\s+(?=[\d/])/)); // Split on spaces to get columns
|
|
115
|
-
const filtered = parsed.filter(filter);
|
|
116
|
-
if (filtered.length === 0) {
|
|
117
|
-
throw new NoMatchError();
|
|
118
|
-
}
|
|
119
|
-
const diskData = filtered[0];
|
|
120
|
-
return {
|
|
121
|
-
diskPath: diskData[mapping.diskPath],
|
|
122
|
-
free: parseInt(diskData[mapping.free], 10) * coefficient,
|
|
123
|
-
size: parseInt(diskData[mapping.size], 10) * coefficient,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Run the command and do common things between win32 and unix
|
|
128
|
-
*
|
|
129
|
-
* @param cmd - The command to execute
|
|
130
|
-
* @param filter - To filter drives (only used for win32)
|
|
131
|
-
* @param mapping - Map between column index and normalized column name
|
|
132
|
-
* @param coefficient - The size coefficient to get bytes instead of kB
|
|
133
|
-
*/
|
|
134
|
-
async function check(cmd, filter, mapping, coefficient = 1) {
|
|
135
|
-
const [file, ...args] = cmd;
|
|
136
|
-
/* istanbul ignore if */
|
|
137
|
-
if (file === undefined) {
|
|
138
|
-
return Promise.reject(new Error('cmd must contain at least one item'));
|
|
139
|
-
}
|
|
140
|
-
try {
|
|
141
|
-
const { stdout } = await dependencies.cpExecFile(file, args, { windowsHide: true });
|
|
142
|
-
return mapOutput(stdout, filter, mapping, coefficient);
|
|
143
|
-
}
|
|
144
|
-
catch (error) {
|
|
145
|
-
return Promise.reject(error);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Build the check call for win32
|
|
150
|
-
*
|
|
151
|
-
* @param directoryPath - The file/folder path from where we want to know disk space
|
|
152
|
-
*/
|
|
153
|
-
async function checkWin32(directoryPath) {
|
|
154
|
-
if (directoryPath.charAt(1) !== ':') {
|
|
155
|
-
return Promise.reject(new InvalidPathError(`The following path is invalid (should be X:\\...): ${directoryPath}`));
|
|
156
|
-
}
|
|
157
|
-
const powershellCmd = [
|
|
158
|
-
'powershell',
|
|
159
|
-
'Get-CimInstance -ClassName Win32_LogicalDisk | Select-Object Caption, FreeSpace, Size',
|
|
160
|
-
];
|
|
161
|
-
const wmicCmd = [
|
|
162
|
-
'wmic',
|
|
163
|
-
'logicaldisk',
|
|
164
|
-
'get',
|
|
165
|
-
'size,freespace,caption',
|
|
166
|
-
];
|
|
167
|
-
const cmd = await hasPowerShell3(dependencies) ? powershellCmd : wmicCmd;
|
|
168
|
-
return check(cmd, driveData => {
|
|
169
|
-
// Only get the drive which match the path
|
|
170
|
-
const driveLetter = driveData[0];
|
|
171
|
-
return directoryPath.toUpperCase().startsWith(driveLetter.toUpperCase());
|
|
172
|
-
}, {
|
|
173
|
-
diskPath: 0,
|
|
174
|
-
free: 1,
|
|
175
|
-
size: 2,
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Build the check call for unix
|
|
180
|
-
*
|
|
181
|
-
* @param directoryPath - The file/folder path from where we want to know disk space
|
|
182
|
-
*/
|
|
183
|
-
async function checkUnix(directoryPath) {
|
|
184
|
-
if (!dependencies.pathNormalize(directoryPath).startsWith(dependencies.pathSep)) {
|
|
185
|
-
return Promise.reject(new InvalidPathError(`The following path is invalid (should start by ${dependencies.pathSep}): ${directoryPath}`));
|
|
186
|
-
}
|
|
187
|
-
const pathToCheck = await getFirstExistingParentPath(directoryPath, dependencies);
|
|
188
|
-
return check([
|
|
189
|
-
'df',
|
|
190
|
-
'-Pk',
|
|
191
|
-
'--',
|
|
192
|
-
pathToCheck,
|
|
193
|
-
], () => true, // We should only get one line, so we did not need to filter
|
|
194
|
-
{
|
|
195
|
-
diskPath: 5,
|
|
196
|
-
free: 3,
|
|
197
|
-
size: 1,
|
|
198
|
-
}, 1024);
|
|
199
|
-
}
|
|
200
|
-
// Call the right check depending on the OS
|
|
201
|
-
if (dependencies.platform === 'win32') {
|
|
202
|
-
return checkWin32(directoryPath);
|
|
203
|
-
}
|
|
204
|
-
return checkUnix(directoryPath);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
exports.InvalidPathError = InvalidPathError;
|
|
208
|
-
exports.NoMatchError = NoMatchError;
|
|
209
|
-
exports.default = checkDiskSpace;
|
|
210
|
-
exports.getFirstExistingParentPath = getFirstExistingParentPath;
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { access } from 'node:fs/promises';
|
|
2
|
-
import { normalize, sep } from 'node:path';
|
|
3
|
-
|
|
4
|
-
declare class InvalidPathError extends Error {
|
|
5
|
-
name: string;
|
|
6
|
-
constructor(message?: string);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
declare class NoMatchError extends Error {
|
|
10
|
-
name: string;
|
|
11
|
-
constructor(message?: string);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
type Dependencies = {
|
|
15
|
-
platform: NodeJS.Platform;
|
|
16
|
-
release: string;
|
|
17
|
-
fsAccess: typeof access;
|
|
18
|
-
pathNormalize: typeof normalize;
|
|
19
|
-
pathSep: typeof sep;
|
|
20
|
-
cpExecFile: (file: string, args: ReadonlyArray<string> | undefined | null, options: {
|
|
21
|
-
windowsHide: true;
|
|
22
|
-
}) => Promise<{
|
|
23
|
-
stdout: string;
|
|
24
|
-
stderr: string;
|
|
25
|
-
}>;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Get the first existing parent path
|
|
30
|
-
*
|
|
31
|
-
* @param directoryPath - The file/folder path from where we want to know disk space
|
|
32
|
-
* @param dependencies - Dependencies container
|
|
33
|
-
*/
|
|
34
|
-
declare function getFirstExistingParentPath(directoryPath: string, dependencies: Dependencies): Promise<string>;
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* `free` and `size` are in bytes
|
|
38
|
-
*/
|
|
39
|
-
type DiskSpace = {
|
|
40
|
-
diskPath: string;
|
|
41
|
-
free: number;
|
|
42
|
-
size: number;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Check disk space
|
|
47
|
-
*
|
|
48
|
-
* @param directoryPath - The file/folder path from where we want to know disk space
|
|
49
|
-
* @param dependencies - Dependencies container
|
|
50
|
-
*/
|
|
51
|
-
declare function checkDiskSpace(directoryPath: string, dependencies?: Dependencies): Promise<DiskSpace>;
|
|
52
|
-
|
|
53
|
-
export { Dependencies, DiskSpace, InvalidPathError, NoMatchError, checkDiskSpace as default, getFirstExistingParentPath };
|