check-disk-space 3.0.0 → 3.0.1

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 CHANGED
@@ -4,10 +4,22 @@
4
4
  [![check-disk-space on npm](https://img.shields.io/npm/v/check-disk-space?style=for-the-badge)](https://www.npmjs.com/package/check-disk-space)
5
5
  [![License MIT](https://img.shields.io/github/license/Alex-D/check-disk-space.svg?style=for-the-badge)](LICENSE)
6
6
 
7
+
8
+ ## Introduction
9
+
10
+ Light multi-platform disk space checker without third party for Node.js.
11
+
12
+ - Works on Linux, macOS and Windows
13
+ - Take care of mounting points on unix-like systems
14
+ - No dependencies
15
+ - TypeScript support
16
+
17
+
7
18
  ## Install
8
19
 
9
20
  `npm install check-disk-space`
10
21
 
22
+
11
23
  ## Usage
12
24
 
13
25
  ```js
@@ -25,6 +37,7 @@ checkDiskSpace('C:/blabla/bla').then((diskSpace) => {
25
37
  // free: 12345678,
26
38
  // size: 98756432
27
39
  // }
40
+ // Note: `free` and `size` are in bytes
28
41
  })
29
42
 
30
43
  // On Linux or macOS
@@ -35,5 +48,6 @@ checkDiskSpace('/mnt/mygames').then((diskSpace) => {
35
48
  // free: 12345678,
36
49
  // size: 98756432
37
50
  // }
51
+ // Note: `free` and `size` are in bytes
38
52
  })
39
53
  ```
@@ -0,0 +1,157 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var child_process = require('child_process');
6
+ var fs = require('fs');
7
+ var path = require('path');
8
+
9
+ class InvalidPathError extends Error {
10
+ constructor(message) {
11
+ super(message);
12
+ this.name = 'InvalidPathError';
13
+ // Set the prototype explicitly.
14
+ Object.setPrototypeOf(this, InvalidPathError.prototype);
15
+ }
16
+ }
17
+
18
+ class NoMatchError extends Error {
19
+ constructor(message) {
20
+ super(message);
21
+ this.name = 'NoMatchError';
22
+ // Set the prototype explicitly.
23
+ Object.setPrototypeOf(this, NoMatchError.prototype);
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Get the first existing parent path
29
+ *
30
+ * @param directoryPath - The file/folder path from where we want to know disk space
31
+ * @param dependencies - Dependencies container
32
+ */
33
+ function getFirstExistingParentPath(directoryPath, dependencies) {
34
+ let parentDirectoryPath = directoryPath;
35
+ let parentDirectoryFound = dependencies.fsExistsSync(parentDirectoryPath);
36
+ while (!parentDirectoryFound) {
37
+ parentDirectoryPath = dependencies.pathNormalize(parentDirectoryPath + '/..');
38
+ parentDirectoryFound = dependencies.fsExistsSync(parentDirectoryPath);
39
+ }
40
+ return parentDirectoryPath;
41
+ }
42
+
43
+ /**
44
+ * Check disk space
45
+ *
46
+ * @param directoryPath - The file/folder path from where we want to know disk space
47
+ * @param dependencies - Dependencies container
48
+ */
49
+ function checkDiskSpace(directoryPath, dependencies = {
50
+ platform: process.platform,
51
+ fsExistsSync: fs.existsSync,
52
+ pathNormalize: path.normalize,
53
+ pathSep: path.sep,
54
+ cpExecFile: child_process.execFile,
55
+ }) {
56
+ /**
57
+ * Maps command output to a normalized object {diskPath, free, size}
58
+ *
59
+ * @param stdout - The command output
60
+ * @param filter - To filter drives (only used for win32)
61
+ * @param mapping - Map between column index and normalized column name
62
+ * @param coefficient - The size coefficient to get bytes instead of kB
63
+ */
64
+ function mapOutput(stdout, filter, mapping, coefficient) {
65
+ const parsed = stdout.trim().split('\n').slice(1).map(line => {
66
+ return line.trim().split(/\s+(?=[\d/])/);
67
+ });
68
+ const filtered = parsed.filter(filter);
69
+ if (filtered.length === 0) {
70
+ throw new NoMatchError();
71
+ }
72
+ const diskData = filtered[0];
73
+ return {
74
+ diskPath: diskData[mapping.diskPath],
75
+ free: parseInt(diskData[mapping.free], 10) * coefficient,
76
+ size: parseInt(diskData[mapping.size], 10) * coefficient,
77
+ };
78
+ }
79
+ /**
80
+ * Run the command and do common things between win32 and unix
81
+ *
82
+ * @param cmd - The command to execute
83
+ * @param filter - To filter drives (only used for win32)
84
+ * @param mapping - Map between column index and normalized column name
85
+ * @param coefficient - The size coefficient to get bytes instead of kB
86
+ */
87
+ function check(cmd, filter, mapping, coefficient = 1) {
88
+ return new Promise((resolve, reject) => {
89
+ const [file, ...args] = cmd;
90
+ /* istanbul ignore if */
91
+ if (file === undefined) {
92
+ return Promise.reject('cmd must contain at least one item');
93
+ }
94
+ dependencies.cpExecFile(file, args, (error, stdout) => {
95
+ if (error) {
96
+ reject(error);
97
+ }
98
+ try {
99
+ resolve(mapOutput(stdout, filter, mapping, coefficient));
100
+ }
101
+ catch (error2) {
102
+ reject(error2);
103
+ }
104
+ });
105
+ });
106
+ }
107
+ /**
108
+ * Build the check call for win32
109
+ *
110
+ * @param directoryPath - The file/folder path from where we want to know disk space
111
+ */
112
+ function checkWin32(directoryPath) {
113
+ if (directoryPath.charAt(1) !== ':') {
114
+ return new Promise((resolve, reject) => {
115
+ reject(new InvalidPathError(`The following path is invalid (should be X:\\...): ${directoryPath}`));
116
+ });
117
+ }
118
+ return check(['wmic', 'logicaldisk', 'get', 'size,freespace,caption'], driveData => {
119
+ // Only get the drive which match the path
120
+ const driveLetter = driveData[0];
121
+ return directoryPath.toUpperCase().startsWith(driveLetter.toUpperCase());
122
+ }, {
123
+ diskPath: 0,
124
+ free: 1,
125
+ size: 2,
126
+ });
127
+ }
128
+ /**
129
+ * Build the check call for unix
130
+ *
131
+ * @param directoryPath - The file/folder path from where we want to know disk space
132
+ */
133
+ function checkUnix(directoryPath) {
134
+ if (!dependencies.pathNormalize(directoryPath).startsWith(dependencies.pathSep)) {
135
+ return new Promise((resolve, reject) => {
136
+ reject(new InvalidPathError(`The following path is invalid (should start by ${dependencies.pathSep}): ${directoryPath}`));
137
+ });
138
+ }
139
+ const pathToCheck = getFirstExistingParentPath(directoryPath, dependencies);
140
+ return check(['df', '-Pk', '--', pathToCheck], () => true, // We should only get one line, so we did not need to filter
141
+ {
142
+ diskPath: 5,
143
+ free: 3,
144
+ size: 1,
145
+ }, 1024);
146
+ }
147
+ // Call the right check depending on the OS
148
+ if (dependencies.platform === 'win32') {
149
+ return checkWin32(directoryPath);
150
+ }
151
+ return checkUnix(directoryPath);
152
+ }
153
+
154
+ exports.InvalidPathError = InvalidPathError;
155
+ exports.NoMatchError = NoMatchError;
156
+ exports.default = checkDiskSpace;
157
+ exports.getFirstExistingParentPath = getFirstExistingParentPath;
@@ -0,0 +1,49 @@
1
+ import { ExecFileException, ChildProcess } from 'child_process';
2
+ import { existsSync } from 'fs';
3
+ import { normalize, sep } from 'path';
4
+
5
+ declare class InvalidPathError extends Error {
6
+ name: string;
7
+ constructor(message?: string);
8
+ }
9
+
10
+ declare class NoMatchError extends Error {
11
+ name: string;
12
+ constructor(message?: string);
13
+ }
14
+
15
+ declare type Dependencies = {
16
+ platform: NodeJS.Platform;
17
+ fsExistsSync: typeof existsSync;
18
+ pathNormalize: typeof normalize;
19
+ pathSep: typeof sep;
20
+ cpExecFile: (file: string, args: ReadonlyArray<string> | undefined | null, callback: (error: ExecFileException | null, stdout: string, stderr: string) => void) => ChildProcess;
21
+ };
22
+
23
+ /**
24
+ * Get the first existing parent path
25
+ *
26
+ * @param directoryPath - The file/folder path from where we want to know disk space
27
+ * @param dependencies - Dependencies container
28
+ */
29
+ declare function getFirstExistingParentPath(directoryPath: string, dependencies: Dependencies): string;
30
+
31
+ /**
32
+ * `free` and `size` are in bytes
33
+ */
34
+ declare type DiskSpace = {
35
+ diskPath: string;
36
+ free: number;
37
+ size: number;
38
+ };
39
+
40
+ /**
41
+ * Check disk space
42
+ *
43
+ * @param directoryPath - The file/folder path from where we want to know disk space
44
+ * @param dependencies - Dependencies container
45
+ */
46
+ declare function checkDiskSpace(directoryPath: string, dependencies?: Dependencies): Promise<DiskSpace>;
47
+
48
+ export default checkDiskSpace;
49
+ export { Dependencies, DiskSpace, InvalidPathError, NoMatchError, getFirstExistingParentPath };
@@ -0,0 +1,151 @@
1
+ import { execFile } from 'child_process';
2
+ import { existsSync } from 'fs';
3
+ import { normalize, sep } from 'path';
4
+
5
+ class InvalidPathError extends Error {
6
+ constructor(message) {
7
+ super(message);
8
+ this.name = 'InvalidPathError';
9
+ // Set the prototype explicitly.
10
+ Object.setPrototypeOf(this, InvalidPathError.prototype);
11
+ }
12
+ }
13
+
14
+ class NoMatchError extends Error {
15
+ constructor(message) {
16
+ super(message);
17
+ this.name = 'NoMatchError';
18
+ // Set the prototype explicitly.
19
+ Object.setPrototypeOf(this, NoMatchError.prototype);
20
+ }
21
+ }
22
+
23
+ /**
24
+ * Get the first existing parent path
25
+ *
26
+ * @param directoryPath - The file/folder path from where we want to know disk space
27
+ * @param dependencies - Dependencies container
28
+ */
29
+ function getFirstExistingParentPath(directoryPath, dependencies) {
30
+ let parentDirectoryPath = directoryPath;
31
+ let parentDirectoryFound = dependencies.fsExistsSync(parentDirectoryPath);
32
+ while (!parentDirectoryFound) {
33
+ parentDirectoryPath = dependencies.pathNormalize(parentDirectoryPath + '/..');
34
+ parentDirectoryFound = dependencies.fsExistsSync(parentDirectoryPath);
35
+ }
36
+ return parentDirectoryPath;
37
+ }
38
+
39
+ /**
40
+ * Check disk space
41
+ *
42
+ * @param directoryPath - The file/folder path from where we want to know disk space
43
+ * @param dependencies - Dependencies container
44
+ */
45
+ function checkDiskSpace(directoryPath, dependencies = {
46
+ platform: process.platform,
47
+ fsExistsSync: existsSync,
48
+ pathNormalize: normalize,
49
+ pathSep: sep,
50
+ cpExecFile: execFile,
51
+ }) {
52
+ /**
53
+ * Maps command output to a normalized object {diskPath, free, size}
54
+ *
55
+ * @param stdout - The command output
56
+ * @param filter - To filter drives (only used for win32)
57
+ * @param mapping - Map between column index and normalized column name
58
+ * @param coefficient - The size coefficient to get bytes instead of kB
59
+ */
60
+ function mapOutput(stdout, filter, mapping, coefficient) {
61
+ const parsed = stdout.trim().split('\n').slice(1).map(line => {
62
+ return line.trim().split(/\s+(?=[\d/])/);
63
+ });
64
+ const filtered = parsed.filter(filter);
65
+ if (filtered.length === 0) {
66
+ throw new NoMatchError();
67
+ }
68
+ const diskData = filtered[0];
69
+ return {
70
+ diskPath: diskData[mapping.diskPath],
71
+ free: parseInt(diskData[mapping.free], 10) * coefficient,
72
+ size: parseInt(diskData[mapping.size], 10) * coefficient,
73
+ };
74
+ }
75
+ /**
76
+ * Run the command and do common things between win32 and unix
77
+ *
78
+ * @param cmd - The command to execute
79
+ * @param filter - To filter drives (only used for win32)
80
+ * @param mapping - Map between column index and normalized column name
81
+ * @param coefficient - The size coefficient to get bytes instead of kB
82
+ */
83
+ function check(cmd, filter, mapping, coefficient = 1) {
84
+ return new Promise((resolve, reject) => {
85
+ const [file, ...args] = cmd;
86
+ /* istanbul ignore if */
87
+ if (file === undefined) {
88
+ return Promise.reject('cmd must contain at least one item');
89
+ }
90
+ dependencies.cpExecFile(file, args, (error, stdout) => {
91
+ if (error) {
92
+ reject(error);
93
+ }
94
+ try {
95
+ resolve(mapOutput(stdout, filter, mapping, coefficient));
96
+ }
97
+ catch (error2) {
98
+ reject(error2);
99
+ }
100
+ });
101
+ });
102
+ }
103
+ /**
104
+ * Build the check call for win32
105
+ *
106
+ * @param directoryPath - The file/folder path from where we want to know disk space
107
+ */
108
+ function checkWin32(directoryPath) {
109
+ if (directoryPath.charAt(1) !== ':') {
110
+ return new Promise((resolve, reject) => {
111
+ reject(new InvalidPathError(`The following path is invalid (should be X:\\...): ${directoryPath}`));
112
+ });
113
+ }
114
+ return check(['wmic', 'logicaldisk', 'get', 'size,freespace,caption'], driveData => {
115
+ // Only get the drive which match the path
116
+ const driveLetter = driveData[0];
117
+ return directoryPath.toUpperCase().startsWith(driveLetter.toUpperCase());
118
+ }, {
119
+ diskPath: 0,
120
+ free: 1,
121
+ size: 2,
122
+ });
123
+ }
124
+ /**
125
+ * Build the check call for unix
126
+ *
127
+ * @param directoryPath - The file/folder path from where we want to know disk space
128
+ */
129
+ function checkUnix(directoryPath) {
130
+ if (!dependencies.pathNormalize(directoryPath).startsWith(dependencies.pathSep)) {
131
+ return new Promise((resolve, reject) => {
132
+ reject(new InvalidPathError(`The following path is invalid (should start by ${dependencies.pathSep}): ${directoryPath}`));
133
+ });
134
+ }
135
+ const pathToCheck = getFirstExistingParentPath(directoryPath, dependencies);
136
+ return check(['df', '-Pk', '--', pathToCheck], () => true, // We should only get one line, so we did not need to filter
137
+ {
138
+ diskPath: 5,
139
+ free: 3,
140
+ size: 1,
141
+ }, 1024);
142
+ }
143
+ // Call the right check depending on the OS
144
+ if (dependencies.platform === 'win32') {
145
+ return checkWin32(directoryPath);
146
+ }
147
+ return checkUnix(directoryPath);
148
+ }
149
+
150
+ export default checkDiskSpace;
151
+ export { InvalidPathError, NoMatchError, getFirstExistingParentPath };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "check-disk-space",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Light multi-platform disk space checker without third party for Node.js",
5
5
  "files": [
6
6
  "dist"
@@ -19,26 +19,26 @@
19
19
  "build:dts": "rollup --config rollup.dts.config.js",
20
20
  "build": "npm-run-all build:lib build:dts",
21
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"
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
+ ]
27
41
  },
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
42
  "engines": {
43
43
  "node": ">=12"
44
44
  },
@@ -61,6 +61,7 @@
61
61
  "source-map-support": "^0.5.19",
62
62
  "ts-node": "^10.0.0",
63
63
  "tsconfig-paths": "^3.9.0",
64
+ "tslib": "^2.3.0",
64
65
  "typescript": "4.3.2"
65
66
  },
66
67
  "repository": {