@rocketmakers/shell-fs 0.1.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 ADDED
@@ -0,0 +1,3 @@
1
+ ## Overview
2
+
3
+ Contains helper functions for working with the file system.
package/lib/fs.d.ts ADDED
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Gets all sub-folders of a folder
3
+ * @param path The path of the folder to check
4
+ */
5
+ export declare function getFolders(path: string): {
6
+ name: string;
7
+ path: string;
8
+ }[];
9
+ /**
10
+ * Gets all files within a folder (excluding sub-folders)
11
+ * @param path The path of the folder to check
12
+ */
13
+ export declare function getFiles(path: string): {
14
+ name: string;
15
+ path: string;
16
+ }[];
17
+ /**
18
+ * Tests whether there is a directory at the given path
19
+ * @param path The path to check
20
+ */
21
+ export declare function isDirectory(path: string): boolean;
22
+ /**
23
+ * Get the directory path from the given file path.
24
+ *
25
+ * Neither the file nor the directory necessarily have to exist for this to work
26
+ * but if the path cannot represent a file (e.g. "/") then this will return undefined.
27
+ *
28
+ * @param filePath A string that could represent a file path
29
+ * @returns A string that represents the directory containing the given file,
30
+ * or undefined if the path could not have been a file
31
+ */
32
+ export declare function getDirectoryPathFromFilePath(filePath: string): string | undefined;
33
+ /**
34
+ * Tests whether the given path is an empty directory
35
+ * @param path The path to check
36
+ */
37
+ export declare function isEmptyDirectory(path: string): boolean;
package/lib/fs.js ADDED
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getFolders = getFolders;
4
+ exports.getFiles = getFiles;
5
+ exports.isDirectory = isDirectory;
6
+ exports.getDirectoryPathFromFilePath = getDirectoryPathFromFilePath;
7
+ exports.isEmptyDirectory = isEmptyDirectory;
8
+ const fs_1 = require("fs");
9
+ const path_1 = require("path");
10
+ /**
11
+ * Appends the given file names to the given path
12
+ * @param path The path to append to
13
+ * @param names The names to append to the path
14
+ */
15
+ function getInfo(path, names) {
16
+ return names.map(name => ({ name, path: (0, path_1.join)(path, name) }));
17
+ }
18
+ /**
19
+ * Gets all sub-folders of a folder
20
+ * @param path The path of the folder to check
21
+ */
22
+ function getFolders(path) {
23
+ return getInfo(path, (0, fs_1.readdirSync)(path).filter(name => (0, fs_1.lstatSync)((0, path_1.join)(path, name)).isDirectory()));
24
+ }
25
+ /**
26
+ * Gets all files within a folder (excluding sub-folders)
27
+ * @param path The path of the folder to check
28
+ */
29
+ function getFiles(path) {
30
+ return getInfo(path, (0, fs_1.readdirSync)(path).filter(name => (0, fs_1.lstatSync)((0, path_1.join)(path, name)).isFile()));
31
+ }
32
+ /**
33
+ * Tests whether there is a directory at the given path
34
+ * @param path The path to check
35
+ */
36
+ function isDirectory(path) {
37
+ if (!(0, fs_1.existsSync)(path)) {
38
+ return false;
39
+ }
40
+ return (0, fs_1.lstatSync)(path).isDirectory();
41
+ }
42
+ /**
43
+ * Get the directory path from the given file path.
44
+ *
45
+ * Neither the file nor the directory necessarily have to exist for this to work
46
+ * but if the path cannot represent a file (e.g. "/") then this will return undefined.
47
+ *
48
+ * @param filePath A string that could represent a file path
49
+ * @returns A string that represents the directory containing the given file,
50
+ * or undefined if the path could not have been a file
51
+ */
52
+ function getDirectoryPathFromFilePath(filePath) {
53
+ const parts = filePath.split(path_1.sep);
54
+ const fileName = parts.pop();
55
+ return fileName ? `${parts.join(path_1.sep)}${path_1.sep}` : undefined;
56
+ }
57
+ /**
58
+ * Tests whether the given path is an empty directory
59
+ * @param path The path to check
60
+ */
61
+ function isEmptyDirectory(path) {
62
+ if (!isDirectory(path)) {
63
+ throw new Error(`isEmptyDirectory function expects '${path}' to be a directory`);
64
+ }
65
+ const contentLength = getFiles(path).length + getFolders(path).length;
66
+ return contentLength === 0;
67
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Gets all sub-folders of a folder
3
+ * @param path The path of the folder to check
4
+ */
5
+ export declare function getFolders(path: string): {
6
+ name: string;
7
+ path: string;
8
+ }[];
9
+ /**
10
+ * Gets all files within a folder (excluding sub-folders)
11
+ * @param path The path of the folder to check
12
+ */
13
+ export declare function getFiles(path: string): {
14
+ name: string;
15
+ path: string;
16
+ }[];
17
+ /**
18
+ * Tests whether there is a directory at the given path
19
+ * @param path The path to check
20
+ */
21
+ export declare function isDirectory(path: string): boolean;
22
+ /**
23
+ * Get the directory path from the given file path.
24
+ *
25
+ * Neither the file nor the directory necessarily have to exist for this to work
26
+ * but if the path cannot represent a file (e.g. "/") then this will return undefined.
27
+ *
28
+ * @param filePath A string that could represent a file path
29
+ * @returns A string that represents the directory containing the given file,
30
+ * or undefined if the path could not have been a file
31
+ */
32
+ export declare function getDirectoryPathFromFilePath(filePath: string): string | undefined;
33
+ /**
34
+ * Tests whether the given path is an empty directory
35
+ * @param path The path to check
36
+ */
37
+ export declare function isEmptyDirectory(path: string): boolean;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getFolders = getFolders;
4
+ exports.getFiles = getFiles;
5
+ exports.isDirectory = isDirectory;
6
+ exports.getDirectoryPathFromFilePath = getDirectoryPathFromFilePath;
7
+ exports.isEmptyDirectory = isEmptyDirectory;
8
+ const fs_1 = require("fs");
9
+ const path_1 = require("path");
10
+ /**
11
+ * Appends the given file names to the given path
12
+ * @param path The path to append to
13
+ * @param names The names to append to the path
14
+ */
15
+ function getInfo(path, names) {
16
+ return names.map(name => ({ name, path: (0, path_1.join)(path, name) }));
17
+ }
18
+ /**
19
+ * Gets all sub-folders of a folder
20
+ * @param path The path of the folder to check
21
+ */
22
+ function getFolders(path) {
23
+ return getInfo(path, (0, fs_1.readdirSync)(path).filter(name => (0, fs_1.lstatSync)((0, path_1.join)(path, name)).isDirectory()));
24
+ }
25
+ /**
26
+ * Gets all files within a folder (excluding sub-folders)
27
+ * @param path The path of the folder to check
28
+ */
29
+ function getFiles(path) {
30
+ return getInfo(path, (0, fs_1.readdirSync)(path).filter(name => (0, fs_1.lstatSync)((0, path_1.join)(path, name)).isFile()));
31
+ }
32
+ /**
33
+ * Tests whether there is a directory at the given path
34
+ * @param path The path to check
35
+ */
36
+ function isDirectory(path) {
37
+ if (!(0, fs_1.existsSync)(path)) {
38
+ return false;
39
+ }
40
+ return (0, fs_1.lstatSync)(path).isDirectory();
41
+ }
42
+ /**
43
+ * Get the directory path from the given file path.
44
+ *
45
+ * Neither the file nor the directory necessarily have to exist for this to work
46
+ * but if the path cannot represent a file (e.g. "/") then this will return undefined.
47
+ *
48
+ * @param filePath A string that could represent a file path
49
+ * @returns A string that represents the directory containing the given file,
50
+ * or undefined if the path could not have been a file
51
+ */
52
+ function getDirectoryPathFromFilePath(filePath) {
53
+ const parts = filePath.split(path_1.sep);
54
+ const fileName = parts.pop();
55
+ return fileName ? `${parts.join(path_1.sep)}${path_1.sep}` : undefined;
56
+ }
57
+ /**
58
+ * Tests whether the given path is an empty directory
59
+ * @param path The path to check
60
+ */
61
+ function isEmptyDirectory(path) {
62
+ if (!isDirectory(path)) {
63
+ throw new Error(`isEmptyDirectory function expects '${path}' to be a directory`);
64
+ }
65
+ const contentLength = getFiles(path).length + getFolders(path).length;
66
+ return contentLength === 0;
67
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const suite_1 = require("@rocketmakers/shell-tests/suite");
4
+ const fs_1 = require("fs");
5
+ const promises_1 = require("fs/promises");
6
+ const fs_2 = require("../source/fs");
7
+ const packagePaths_1 = require("./packagePaths");
8
+ (0, suite_1.sandboxedTestSuite)({ suiteName: 'FileSystem', sandboxRootPath: (0, packagePaths_1.sandboxPath)() }, () => {
9
+ describe('isDirectory', () => {
10
+ it('when passed empty string, returns false', () => {
11
+ expect((0, fs_2.isDirectory)('')).toBe(false);
12
+ });
13
+ it('when passed whitespace, returns false', () => {
14
+ expect((0, fs_2.isDirectory)(' \n\t\r')).toBe(false);
15
+ });
16
+ it('when passed a path that does not exist, returns false', () => {
17
+ expect((0, fs_2.isDirectory)((0, packagePaths_1.packagePath)('source', 'alan'))).toBe(false);
18
+ });
19
+ it('when passed a file path, returns false', () => {
20
+ expect((0, fs_2.isDirectory)((0, packagePaths_1.packagePath)('source', 'fs.ts'))).toBe(false);
21
+ });
22
+ it('when passed a directory path, returns true', () => {
23
+ expect((0, fs_2.isDirectory)((0, packagePaths_1.packagePath)('source'))).toBe(true);
24
+ });
25
+ it('when passed a directory path with a trailing slash, returns true', () => {
26
+ expect((0, fs_2.isDirectory)(`${(0, packagePaths_1.packagePath)('source/')}/`)).toBe(true);
27
+ });
28
+ });
29
+ describe('isEmptyDirectory', () => {
30
+ const emptyDirectoryPath = (0, packagePaths_1.sandboxPath)('empty-dir');
31
+ beforeEach(async () => {
32
+ if (!(0, fs_1.existsSync)(emptyDirectoryPath)) {
33
+ return (0, promises_1.mkdir)(emptyDirectoryPath, { recursive: true });
34
+ }
35
+ });
36
+ it('when passed empty string, throws an error', () => {
37
+ expect(() => (0, fs_2.isEmptyDirectory)('')).toThrow();
38
+ });
39
+ it('when passed whitespace, throws an error', () => {
40
+ expect(() => (0, fs_2.isEmptyDirectory)(' \n\t\r')).toThrow();
41
+ });
42
+ it('when passed a path that does not exist, throws an error', () => {
43
+ expect(() => (0, fs_2.isEmptyDirectory)((0, packagePaths_1.packagePath)('source', 'alan'))).toThrow();
44
+ });
45
+ it('when passed a file path, throws an error', () => {
46
+ expect(() => (0, fs_2.isEmptyDirectory)((0, packagePaths_1.packagePath)('source', 'fs.ts'))).toThrow();
47
+ });
48
+ it('when passed a path to an empty directory, returns true', () => {
49
+ expect((0, fs_2.isEmptyDirectory)(emptyDirectoryPath)).toBe(true);
50
+ });
51
+ it('when passed a path to a directory that is not empty, returns false', () => {
52
+ expect((0, fs_2.isEmptyDirectory)((0, packagePaths_1.packagePath)('source'))).toBe(false);
53
+ });
54
+ });
55
+ describe('getDirectoryPathFromFilePath', () => {
56
+ const expectUndefined = ['', '/'];
57
+ const expectDirPath = [
58
+ ['/myFile.txt', '/'],
59
+ ['./myFile.txt', './'],
60
+ ['/path.to/myFile.txt', '/path.to/'],
61
+ ['/path-to/myFile.txt', '/path-to/'],
62
+ ['./path/to/myFile.txt', './path/to/'],
63
+ ['../../up/then/down/some-file.yaml', '../../up/then/down/'],
64
+ ['/cheeky/path/noExtension', '/cheeky/path/'],
65
+ ['/some/path/to/directory/that/does/not/exist', '/some/path/to/directory/that/does/not/'],
66
+ [(0, packagePaths_1.sandboxPath)('some-file.json'), `${(0, packagePaths_1.sandboxPath)()}/`],
67
+ ];
68
+ it.each(expectUndefined)("'%s', returns undefined", testPath => {
69
+ expect((0, fs_2.getDirectoryPathFromFilePath)(testPath)).toBeUndefined();
70
+ });
71
+ it.each(expectDirPath)(`'%s', returns '%s'`, (testPath, expectedPath) => {
72
+ expect((0, fs_2.getDirectoryPathFromFilePath)(testPath)).toEqual(expectedPath);
73
+ });
74
+ });
75
+ describe('getFolders', () => {
76
+ it('when path contains a mix of files and folders, returns folders', async () => {
77
+ const parentPath = (0, packagePaths_1.sandboxPath)('getFilesTests');
78
+ await (0, promises_1.mkdir)(parentPath);
79
+ const files = ['file-1', 'file-2', 'file-3'];
80
+ const folders = ['dir-1', 'dir-2', 'dir-3'];
81
+ for (const fileName of files) {
82
+ await (0, promises_1.writeFile)((0, packagePaths_1.packagePath)(parentPath, fileName), 'content');
83
+ }
84
+ for (const folderName of folders) {
85
+ await (0, promises_1.mkdir)((0, packagePaths_1.packagePath)(parentPath, folderName), { recursive: true });
86
+ }
87
+ const result = (0, fs_2.getFolders)(parentPath);
88
+ const expectedResult = [
89
+ {
90
+ name: 'dir-1',
91
+ path: (0, packagePaths_1.packagePath)(parentPath, 'dir-1'),
92
+ },
93
+ {
94
+ name: 'dir-2',
95
+ path: (0, packagePaths_1.packagePath)(parentPath, 'dir-2'),
96
+ },
97
+ {
98
+ name: 'dir-3',
99
+ path: (0, packagePaths_1.packagePath)(parentPath, 'dir-3'),
100
+ },
101
+ ];
102
+ expect(result).toEqual(expectedResult);
103
+ });
104
+ });
105
+ describe('getFiles', () => {
106
+ it('when path contains a mix of files and folders, returns files', async () => {
107
+ const parentPath = (0, packagePaths_1.sandboxPath)('getFilesTests');
108
+ await (0, promises_1.mkdir)(parentPath);
109
+ const files = ['file-1', 'file-2', 'file-3'];
110
+ const folders = ['dir-1', 'dir-2', 'dir-3'];
111
+ for (const fileName of files) {
112
+ await (0, promises_1.writeFile)((0, packagePaths_1.packagePath)(parentPath, fileName), 'content');
113
+ }
114
+ for (const folderName of folders) {
115
+ await (0, promises_1.mkdir)((0, packagePaths_1.packagePath)(parentPath, folderName), { recursive: true });
116
+ }
117
+ const result = (0, fs_2.getFiles)(parentPath);
118
+ const expectedResult = [
119
+ {
120
+ name: 'file-1',
121
+ path: (0, packagePaths_1.packagePath)(parentPath, 'file-1'),
122
+ },
123
+ {
124
+ name: 'file-2',
125
+ path: (0, packagePaths_1.packagePath)(parentPath, 'file-2'),
126
+ },
127
+ {
128
+ name: 'file-3',
129
+ path: (0, packagePaths_1.packagePath)(parentPath, 'file-3'),
130
+ },
131
+ ];
132
+ expect(result).toEqual(expectedResult);
133
+ });
134
+ });
135
+ });
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Creates an absolute path based on a relative path from the root of this package
3
+ * @param parts
4
+ */
5
+ export declare function packagePath(...parts: string[]): string;
6
+ /**
7
+ * Creates an absolute path relative to the sandbox testing path
8
+ * @param parts The parts of the path relative to the testing sandbox path
9
+ */
10
+ export declare function sandboxPath(...parts: string[]): string;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.packagePath = packagePath;
4
+ exports.sandboxPath = sandboxPath;
5
+ const path_1 = require("path");
6
+ /**
7
+ * Creates an absolute path based on a relative path from the root of this package
8
+ * @param parts
9
+ */
10
+ function packagePath(...parts) {
11
+ return (0, path_1.resolve)(__dirname, '..', ...parts);
12
+ }
13
+ /**
14
+ * Creates an absolute path relative to the sandbox testing path
15
+ * @param parts The parts of the path relative to the testing sandbox path
16
+ */
17
+ function sandboxPath(...parts) {
18
+ return (0, path_1.join)(packagePath('_tests-sandbox_'), ...parts);
19
+ }
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@rocketmakers/shell-fs",
3
+ "version": "0.1.0",
4
+ "exports": {
5
+ ".": {
6
+ "types": "./lib/fs.d.ts",
7
+ "default": "./lib/fs.js"
8
+ }
9
+ },
10
+ "devDependencies": {
11
+ "@types/jest": "29.5.14",
12
+ "@types/node": "22.13.9",
13
+ "eslint": "8.57.1",
14
+ "jest": "29.7.0",
15
+ "jest-junit": "16.0.0",
16
+ "ts-jest": "29.3.0",
17
+ "typescript": "5.8.2",
18
+ "@rocketmakers/shell-tests": "0.1.0",
19
+ "eslint-config-shell": "0.1.0",
20
+ "tsconfig-shell": "0.1.0"
21
+ },
22
+ "directories": {
23
+ "lib": "lib"
24
+ },
25
+ "engines": {
26
+ "node": " ^20 || ^22"
27
+ },
28
+ "files": [
29
+ "lib/**/*.js",
30
+ "lib/**/*.d.ts",
31
+ "!lib/index.js",
32
+ "!lib/index.d.ts"
33
+ ],
34
+ "keywords": [],
35
+ "license": "MIT",
36
+ "repository": "Rocketmakers/rocketmakers-packages",
37
+ "scripts": {
38
+ "build": "tsc -p .",
39
+ "lint": "eslint . --ext .ts",
40
+ "lint-fix": "pnpm lint --fix",
41
+ "test-integration": "jest --runInBand"
42
+ }
43
+ }