@aneuhold/core-ts-lib 2.2.1 → 2.2.3
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/LICENSE +1 -1
- package/lib/services/FileSystemService/FileSystemService.d.ts +30 -3
- package/lib/services/FileSystemService/FileSystemService.d.ts.map +1 -1
- package/lib/services/FileSystemService/FileSystemService.js +58 -10
- package/lib/services/FileSystemService/FileSystemService.js.map +1 -1
- package/lib/services/FileSystemService/FileSystemService.ts +84 -12
- package/package.json +4 -6
- package/lib/services/DateService/DateService.spec.ts +0 -98
- package/lib/services/FileSystemService/FileSystemService.spec.ts +0 -133
package/LICENSE
CHANGED
|
@@ -21,9 +21,17 @@ export default class FileSystemService {
|
|
|
21
21
|
* @param targetFolderPath
|
|
22
22
|
* @param ignoreExtensions is an array with extensions that should be
|
|
23
23
|
* ignored. For example, if you want to ignore all .ts files, you would pass
|
|
24
|
-
* in ['ts'].
|
|
24
|
+
* in ['.ts']. Multi-part extensions like '.spec.ts' are also supported.
|
|
25
25
|
*/
|
|
26
26
|
static copyFolderContents(sourceFolderPath: string, targetFolderPath: string, ignoreExtensions?: string[]): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Checks if a file should be ignored based on the provided extensions.
|
|
29
|
+
* Supports both simple extensions (e.g., '.ts') and multi-part extensions (e.g., '.spec.ts').
|
|
30
|
+
*
|
|
31
|
+
* @param filePath the path to the file to check
|
|
32
|
+
* @param ignoreExtensions array of extensions to ignore
|
|
33
|
+
*/
|
|
34
|
+
private static shouldIgnoreFile;
|
|
27
35
|
static checkOrCreateFolder(folderPath: string): Promise<void>;
|
|
28
36
|
static deleteFolder(folderPath: string): Promise<void>;
|
|
29
37
|
/**
|
|
@@ -33,7 +41,7 @@ export default class FileSystemService {
|
|
|
33
41
|
*
|
|
34
42
|
* If only relative file paths are needed, use {@link getAllFilePathsRelative}.
|
|
35
43
|
*
|
|
36
|
-
* @param dirPath
|
|
44
|
+
* @param dirPath the directory path to search for files in
|
|
37
45
|
*/
|
|
38
46
|
static getAllFilePaths(dirPath: string): Promise<string[]>;
|
|
39
47
|
/**
|
|
@@ -43,7 +51,7 @@ export default class FileSystemService {
|
|
|
43
51
|
*
|
|
44
52
|
* If absolute file paths are needed, use {@link getAllFilePaths}.
|
|
45
53
|
*
|
|
46
|
-
* @param dirPath
|
|
54
|
+
* @param dirPath the directory path to search for files in
|
|
47
55
|
*/
|
|
48
56
|
static getAllFilePathsRelative(dirPath: string): Promise<string[]>;
|
|
49
57
|
/**
|
|
@@ -64,5 +72,24 @@ export default class FileSystemService {
|
|
|
64
72
|
* @param stopAt - Optional directory path to stop searching at (defaults to root)
|
|
65
73
|
*/
|
|
66
74
|
static findFileUpTree(startDir: string, fileName: string, stopAt?: string): Promise<string | null>;
|
|
75
|
+
/**
|
|
76
|
+
* Searches for all files with the given name by traversing up the directory tree
|
|
77
|
+
* starting from the specified directory. Returns all found files from closest
|
|
78
|
+
* to furthest (root).
|
|
79
|
+
*
|
|
80
|
+
* @param startDir - The directory to start searching from
|
|
81
|
+
* @param fileName - The name of the file to search for
|
|
82
|
+
* @param stopAt - Optional directory path to stop searching at (defaults to root)
|
|
83
|
+
*/
|
|
84
|
+
static findAllFilesUpTree(startDir: string, fileName: string, stopAt?: string): Promise<string[]>;
|
|
85
|
+
/**
|
|
86
|
+
* Internal helper method that traverses up the directory tree looking for files.
|
|
87
|
+
*
|
|
88
|
+
* @param startDir - The directory to start searching from
|
|
89
|
+
* @param fileName - The name of the file to search for
|
|
90
|
+
* @param stopAt - Optional directory path to stop searching at (defaults to root)
|
|
91
|
+
* @param findFirst - If true, stops after finding the first file
|
|
92
|
+
*/
|
|
93
|
+
private static traverseDirectoryTree;
|
|
67
94
|
}
|
|
68
95
|
//# sourceMappingURL=FileSystemService.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileSystemService.d.ts","sourceRoot":"","sources":["../../../src/services/FileSystemService/FileSystemService.ts"],"names":[],"mappings":"AAoBA;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAiB;IACpC;;;;;;;;;OASG;WACU,iBAAiB,CAC5B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC;IAsBhB;;;;;;;;OAQG;WACU,kBAAkB,CAC7B,gBAAgB,EAAE,MAAM,EACxB,gBAAgB,EAAE,MAAM,EACxB,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAC1B,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"FileSystemService.d.ts","sourceRoot":"","sources":["../../../src/services/FileSystemService/FileSystemService.ts"],"names":[],"mappings":"AAoBA;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAiB;IACpC;;;;;;;;;OASG;WACU,iBAAiB,CAC5B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC;IAsBhB;;;;;;;;OAQG;WACU,kBAAkB,CAC7B,gBAAgB,EAAE,MAAM,EACxB,gBAAgB,EAAE,MAAM,EACxB,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAC1B,OAAO,CAAC,IAAI,CAAC;IAgChB;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;WAkBlB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;WAWtD,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU5D;;;;;;;;OAQG;WACU,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAoBhE;;;;;;;;OAQG;WACU,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAOxE;;;;;OAKG;WACU,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC;IAYlD;;;;;;;;;OASG;WACU,cAAc,CACzB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAUzB;;;;;;;;OAQG;WACU,kBAAkB,CAC7B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,EAAE,CAAC;IASpB;;;;;;;OAOG;mBACkB,qBAAqB;CA0C3C"}
|
|
@@ -47,7 +47,7 @@ export default class FileSystemService {
|
|
|
47
47
|
* @param targetFolderPath
|
|
48
48
|
* @param ignoreExtensions is an array with extensions that should be
|
|
49
49
|
* ignored. For example, if you want to ignore all .ts files, you would pass
|
|
50
|
-
* in ['ts'].
|
|
50
|
+
* in ['.ts']. Multi-part extensions like '.spec.ts' are also supported.
|
|
51
51
|
*/
|
|
52
52
|
static async copyFolderContents(sourceFolderPath, targetFolderPath, ignoreExtensions) {
|
|
53
53
|
// Check if the source directory exists first
|
|
@@ -61,18 +61,36 @@ export default class FileSystemService {
|
|
|
61
61
|
await FileSystemService.checkOrCreateFolder(targetFolderPath);
|
|
62
62
|
// Get the files in the source directory
|
|
63
63
|
const sourceFilePaths = await FileSystemService.getAllFilePathsRelative(sourceFolderPath);
|
|
64
|
-
// console.log(sourceFilePaths);
|
|
65
64
|
await Promise.all(sourceFilePaths.map(async (sourceFilePath) => {
|
|
66
65
|
const sourceFile = path.join(sourceFolderPath, sourceFilePath);
|
|
67
66
|
const targetFile = path.join(targetFolderPath, sourceFilePath);
|
|
68
|
-
|
|
69
|
-
if (
|
|
70
|
-
ignoreExtensions
|
|
67
|
+
// Check if the file should be ignored based on extensions
|
|
68
|
+
if (ignoreExtensions &&
|
|
69
|
+
FileSystemService.shouldIgnoreFile(sourceFile, ignoreExtensions)) {
|
|
71
70
|
return;
|
|
72
71
|
}
|
|
73
72
|
await cp(sourceFile, targetFile, { recursive: true });
|
|
74
73
|
}));
|
|
75
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Checks if a file should be ignored based on the provided extensions.
|
|
77
|
+
* Supports both simple extensions (e.g., '.ts') and multi-part extensions (e.g., '.spec.ts').
|
|
78
|
+
*
|
|
79
|
+
* @param filePath the path to the file to check
|
|
80
|
+
* @param ignoreExtensions array of extensions to ignore
|
|
81
|
+
*/
|
|
82
|
+
static shouldIgnoreFile(filePath, ignoreExtensions) {
|
|
83
|
+
const fileName = path.basename(filePath);
|
|
84
|
+
return ignoreExtensions.some((extension) => {
|
|
85
|
+
// Handle multi-part extensions like '.spec.ts'
|
|
86
|
+
if (extension.includes('.', 1)) {
|
|
87
|
+
return fileName.endsWith(extension);
|
|
88
|
+
}
|
|
89
|
+
// Handle simple extensions like '.ts'
|
|
90
|
+
const fileExtension = StringService.getFileNameExtension(filePath);
|
|
91
|
+
return fileExtension === extension;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
76
94
|
static async checkOrCreateFolder(folderPath) {
|
|
77
95
|
try {
|
|
78
96
|
await access(folderPath);
|
|
@@ -99,7 +117,7 @@ export default class FileSystemService {
|
|
|
99
117
|
*
|
|
100
118
|
* If only relative file paths are needed, use {@link getAllFilePathsRelative}.
|
|
101
119
|
*
|
|
102
|
-
* @param dirPath
|
|
120
|
+
* @param dirPath the directory path to search for files in
|
|
103
121
|
*/
|
|
104
122
|
static async getAllFilePaths(dirPath) {
|
|
105
123
|
const filePaths = [];
|
|
@@ -123,7 +141,7 @@ export default class FileSystemService {
|
|
|
123
141
|
*
|
|
124
142
|
* If absolute file paths are needed, use {@link getAllFilePaths}.
|
|
125
143
|
*
|
|
126
|
-
* @param dirPath
|
|
144
|
+
* @param dirPath the directory path to search for files in
|
|
127
145
|
*/
|
|
128
146
|
static async getAllFilePathsRelative(dirPath) {
|
|
129
147
|
const filePaths = await this.getAllFilePaths(dirPath);
|
|
@@ -158,13 +176,43 @@ export default class FileSystemService {
|
|
|
158
176
|
* @param stopAt - Optional directory path to stop searching at (defaults to root)
|
|
159
177
|
*/
|
|
160
178
|
static async findFileUpTree(startDir, fileName, stopAt) {
|
|
179
|
+
const results = await this.traverseDirectoryTree(startDir, fileName, stopAt, true // findFirst = true
|
|
180
|
+
);
|
|
181
|
+
return results.length > 0 ? results[0] : null;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Searches for all files with the given name by traversing up the directory tree
|
|
185
|
+
* starting from the specified directory. Returns all found files from closest
|
|
186
|
+
* to furthest (root).
|
|
187
|
+
*
|
|
188
|
+
* @param startDir - The directory to start searching from
|
|
189
|
+
* @param fileName - The name of the file to search for
|
|
190
|
+
* @param stopAt - Optional directory path to stop searching at (defaults to root)
|
|
191
|
+
*/
|
|
192
|
+
static async findAllFilesUpTree(startDir, fileName, stopAt) {
|
|
193
|
+
return this.traverseDirectoryTree(startDir, fileName, stopAt, false // findFirst = false
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Internal helper method that traverses up the directory tree looking for files.
|
|
198
|
+
*
|
|
199
|
+
* @param startDir - The directory to start searching from
|
|
200
|
+
* @param fileName - The name of the file to search for
|
|
201
|
+
* @param stopAt - Optional directory path to stop searching at (defaults to root)
|
|
202
|
+
* @param findFirst - If true, stops after finding the first file
|
|
203
|
+
*/
|
|
204
|
+
static async traverseDirectoryTree(startDir, fileName, stopAt, findFirst = false) {
|
|
205
|
+
const results = [];
|
|
161
206
|
let currentDir = path.resolve(startDir);
|
|
162
207
|
const rootDir = stopAt ? path.resolve(stopAt) : path.parse(currentDir).root;
|
|
163
208
|
while (currentDir !== rootDir) {
|
|
164
209
|
const filePath = path.join(currentDir, fileName);
|
|
165
210
|
try {
|
|
166
211
|
await access(filePath);
|
|
167
|
-
|
|
212
|
+
results.push(filePath);
|
|
213
|
+
if (findFirst) {
|
|
214
|
+
return results;
|
|
215
|
+
}
|
|
168
216
|
}
|
|
169
217
|
catch {
|
|
170
218
|
// File doesn't exist, continue searching
|
|
@@ -180,12 +228,12 @@ export default class FileSystemService {
|
|
|
180
228
|
const filePath = path.join(currentDir, fileName);
|
|
181
229
|
try {
|
|
182
230
|
await access(filePath);
|
|
183
|
-
|
|
231
|
+
results.push(filePath);
|
|
184
232
|
}
|
|
185
233
|
catch {
|
|
186
234
|
// File not found
|
|
187
|
-
return null;
|
|
188
235
|
}
|
|
236
|
+
return results;
|
|
189
237
|
}
|
|
190
238
|
}
|
|
191
239
|
//# sourceMappingURL=FileSystemService.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileSystemService.js","sourceRoot":"","sources":["../../../src/services/FileSystemService/FileSystemService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EACL,MAAM,EACN,UAAU,EACV,EAAE,EACF,KAAK,EACL,QAAQ,EACR,OAAO,EACP,EAAE,EACF,IAAI,EACJ,SAAS,EACV,MAAM,aAAa,CAAC;AACrB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,UAAU,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAEhD,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAElC;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAiB;IACpC;;;;;;;;;OASG;IACH,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAC5B,UAAkB,EAClB,QAAgB,EAChB,YAAoB;QAEpB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAEjD,MAAM,iBAAiB,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;QAExD,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;YACvB,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC9C,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;gBACzC,MAAM,UAAU,CAAC,QAAQ,EAAE,KAAK,YAAY,EAAE,CAAC,CAAC;gBAChD,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,YAAY,SAAS,QAAQ,GAAG,CAAC,CAAC;YAC7D,CAAC;iBAAM,CAAC;gBACN,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,wBAAwB,QAAQ,GAAG,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,EAAE,CAAC,MAAM,CAAC,IAAI,CACZ,YAAY,QAAQ,+CAA+C,YAAY,UAAU,CAC1F,CAAC;YACF,MAAM,SAAS,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAC7B,gBAAwB,EACxB,gBAAwB,EACxB,gBAA2B;QAE3B,6CAA6C;QAC7C,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,gBAAgB,mBAAmB,CAAC,CAAC;YAC1E,OAAO;QACT,CAAC;QACD,MAAM,iBAAiB,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;QAE9D,wCAAwC;QACxC,MAAM,eAAe,GACnB,MAAM,iBAAiB,CAAC,uBAAuB,CAAC,gBAAgB,CAAC,CAAC;QAEpE,
|
|
1
|
+
{"version":3,"file":"FileSystemService.js","sourceRoot":"","sources":["../../../src/services/FileSystemService/FileSystemService.ts"],"names":[],"mappings":"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"}
|
|
@@ -66,7 +66,7 @@ export default class FileSystemService {
|
|
|
66
66
|
* @param targetFolderPath
|
|
67
67
|
* @param ignoreExtensions is an array with extensions that should be
|
|
68
68
|
* ignored. For example, if you want to ignore all .ts files, you would pass
|
|
69
|
-
* in ['ts'].
|
|
69
|
+
* in ['.ts']. Multi-part extensions like '.spec.ts' are also supported.
|
|
70
70
|
*/
|
|
71
71
|
static async copyFolderContents(
|
|
72
72
|
sourceFolderPath: string,
|
|
@@ -86,18 +86,15 @@ export default class FileSystemService {
|
|
|
86
86
|
const sourceFilePaths =
|
|
87
87
|
await FileSystemService.getAllFilePathsRelative(sourceFolderPath);
|
|
88
88
|
|
|
89
|
-
// console.log(sourceFilePaths);
|
|
90
|
-
|
|
91
89
|
await Promise.all(
|
|
92
90
|
sourceFilePaths.map(async (sourceFilePath) => {
|
|
93
91
|
const sourceFile = path.join(sourceFolderPath, sourceFilePath);
|
|
94
92
|
const targetFile = path.join(targetFolderPath, sourceFilePath);
|
|
95
93
|
|
|
96
|
-
|
|
97
|
-
StringService.getFileNameExtension(sourceFile);
|
|
94
|
+
// Check if the file should be ignored based on extensions
|
|
98
95
|
if (
|
|
99
|
-
|
|
100
|
-
ignoreExtensions
|
|
96
|
+
ignoreExtensions &&
|
|
97
|
+
FileSystemService.shouldIgnoreFile(sourceFile, ignoreExtensions)
|
|
101
98
|
) {
|
|
102
99
|
return;
|
|
103
100
|
}
|
|
@@ -107,6 +104,31 @@ export default class FileSystemService {
|
|
|
107
104
|
);
|
|
108
105
|
}
|
|
109
106
|
|
|
107
|
+
/**
|
|
108
|
+
* Checks if a file should be ignored based on the provided extensions.
|
|
109
|
+
* Supports both simple extensions (e.g., '.ts') and multi-part extensions (e.g., '.spec.ts').
|
|
110
|
+
*
|
|
111
|
+
* @param filePath the path to the file to check
|
|
112
|
+
* @param ignoreExtensions array of extensions to ignore
|
|
113
|
+
*/
|
|
114
|
+
private static shouldIgnoreFile(
|
|
115
|
+
filePath: string,
|
|
116
|
+
ignoreExtensions: string[]
|
|
117
|
+
): boolean {
|
|
118
|
+
const fileName = path.basename(filePath);
|
|
119
|
+
|
|
120
|
+
return ignoreExtensions.some((extension) => {
|
|
121
|
+
// Handle multi-part extensions like '.spec.ts'
|
|
122
|
+
if (extension.includes('.', 1)) {
|
|
123
|
+
return fileName.endsWith(extension);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Handle simple extensions like '.ts'
|
|
127
|
+
const fileExtension = StringService.getFileNameExtension(filePath);
|
|
128
|
+
return fileExtension === extension;
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
110
132
|
static async checkOrCreateFolder(folderPath: string): Promise<void> {
|
|
111
133
|
try {
|
|
112
134
|
await access(folderPath);
|
|
@@ -135,7 +157,7 @@ export default class FileSystemService {
|
|
|
135
157
|
*
|
|
136
158
|
* If only relative file paths are needed, use {@link getAllFilePathsRelative}.
|
|
137
159
|
*
|
|
138
|
-
* @param dirPath
|
|
160
|
+
* @param dirPath the directory path to search for files in
|
|
139
161
|
*/
|
|
140
162
|
static async getAllFilePaths(dirPath: string): Promise<string[]> {
|
|
141
163
|
const filePaths: string[] = [];
|
|
@@ -164,7 +186,7 @@ export default class FileSystemService {
|
|
|
164
186
|
*
|
|
165
187
|
* If absolute file paths are needed, use {@link getAllFilePaths}.
|
|
166
188
|
*
|
|
167
|
-
* @param dirPath
|
|
189
|
+
* @param dirPath the directory path to search for files in
|
|
168
190
|
*/
|
|
169
191
|
static async getAllFilePathsRelative(dirPath: string): Promise<string[]> {
|
|
170
192
|
const filePaths = await this.getAllFilePaths(dirPath);
|
|
@@ -206,6 +228,52 @@ export default class FileSystemService {
|
|
|
206
228
|
fileName: string,
|
|
207
229
|
stopAt?: string
|
|
208
230
|
): Promise<string | null> {
|
|
231
|
+
const results = await this.traverseDirectoryTree(
|
|
232
|
+
startDir,
|
|
233
|
+
fileName,
|
|
234
|
+
stopAt,
|
|
235
|
+
true // findFirst = true
|
|
236
|
+
);
|
|
237
|
+
return results.length > 0 ? results[0] : null;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Searches for all files with the given name by traversing up the directory tree
|
|
242
|
+
* starting from the specified directory. Returns all found files from closest
|
|
243
|
+
* to furthest (root).
|
|
244
|
+
*
|
|
245
|
+
* @param startDir - The directory to start searching from
|
|
246
|
+
* @param fileName - The name of the file to search for
|
|
247
|
+
* @param stopAt - Optional directory path to stop searching at (defaults to root)
|
|
248
|
+
*/
|
|
249
|
+
static async findAllFilesUpTree(
|
|
250
|
+
startDir: string,
|
|
251
|
+
fileName: string,
|
|
252
|
+
stopAt?: string
|
|
253
|
+
): Promise<string[]> {
|
|
254
|
+
return this.traverseDirectoryTree(
|
|
255
|
+
startDir,
|
|
256
|
+
fileName,
|
|
257
|
+
stopAt,
|
|
258
|
+
false // findFirst = false
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Internal helper method that traverses up the directory tree looking for files.
|
|
264
|
+
*
|
|
265
|
+
* @param startDir - The directory to start searching from
|
|
266
|
+
* @param fileName - The name of the file to search for
|
|
267
|
+
* @param stopAt - Optional directory path to stop searching at (defaults to root)
|
|
268
|
+
* @param findFirst - If true, stops after finding the first file
|
|
269
|
+
*/
|
|
270
|
+
private static async traverseDirectoryTree(
|
|
271
|
+
startDir: string,
|
|
272
|
+
fileName: string,
|
|
273
|
+
stopAt?: string,
|
|
274
|
+
findFirst = false
|
|
275
|
+
): Promise<string[]> {
|
|
276
|
+
const results: string[] = [];
|
|
209
277
|
let currentDir = path.resolve(startDir);
|
|
210
278
|
const rootDir = stopAt ? path.resolve(stopAt) : path.parse(currentDir).root;
|
|
211
279
|
|
|
@@ -214,7 +282,10 @@ export default class FileSystemService {
|
|
|
214
282
|
|
|
215
283
|
try {
|
|
216
284
|
await access(filePath);
|
|
217
|
-
|
|
285
|
+
results.push(filePath);
|
|
286
|
+
if (findFirst) {
|
|
287
|
+
return results;
|
|
288
|
+
}
|
|
218
289
|
} catch {
|
|
219
290
|
// File doesn't exist, continue searching
|
|
220
291
|
}
|
|
@@ -231,10 +302,11 @@ export default class FileSystemService {
|
|
|
231
302
|
const filePath = path.join(currentDir, fileName);
|
|
232
303
|
try {
|
|
233
304
|
await access(filePath);
|
|
234
|
-
|
|
305
|
+
results.push(filePath);
|
|
235
306
|
} catch {
|
|
236
307
|
// File not found
|
|
237
|
-
return null;
|
|
238
308
|
}
|
|
309
|
+
|
|
310
|
+
return results;
|
|
239
311
|
}
|
|
240
312
|
}
|
package/package.json
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
"name": "@aneuhold/core-ts-lib",
|
|
3
3
|
"author": "Anton G. Neuhold Jr.",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "2.2.
|
|
5
|
+
"version": "2.2.3",
|
|
6
6
|
"description": "A core library for all of my TypeScript projects",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"build": "rimraf lib && tsc --project tsconfig.build.json && tsx ./scripts/copyTsFiles.ts",
|
|
10
10
|
"watch": "nodemon --ignore lib/ -e ts --exec \"tsc --project tsconfig.build.json && tsx ./scripts/copyTsFiles.ts\"",
|
|
11
11
|
"lint": "eslint",
|
|
12
|
-
"test": "
|
|
12
|
+
"test": "vitest run",
|
|
13
13
|
"jsr:validate": "tsx ./scripts/validateJsrPublish.ts",
|
|
14
14
|
"npm:validate": "tsx ./scripts/validateNpmPublish.ts",
|
|
15
15
|
"checkAll": "pnpm build && pnpm lint && pnpm test && pnpm jsr:validate",
|
|
@@ -41,16 +41,14 @@
|
|
|
41
41
|
"Node.js"
|
|
42
42
|
],
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@types/jest": "^29.5.14",
|
|
45
44
|
"@types/node": "^22.15.3",
|
|
46
45
|
"eslint": "^9.26.0",
|
|
47
|
-
"jest": "^29.7.*",
|
|
48
46
|
"jsr": "*",
|
|
49
47
|
"nodemon": "^3.1.10",
|
|
50
48
|
"prettier": "^3.5.3",
|
|
51
49
|
"rimraf": "^6.0.1",
|
|
52
|
-
"ts-jest": "^29.3.2",
|
|
53
50
|
"tsx": "^4.19.4",
|
|
54
|
-
"typescript": "~5.8.3"
|
|
51
|
+
"typescript": "~5.8.3",
|
|
52
|
+
"vitest": "^3.2.3"
|
|
55
53
|
}
|
|
56
54
|
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import DateService from './DateService.js';
|
|
2
|
-
|
|
3
|
-
describe('DateService', () => {
|
|
4
|
-
describe('addWeeks', () => {
|
|
5
|
-
it('should successfully add weeks to a date', () => {
|
|
6
|
-
const result = DateService.addWeeks(new Date(2024, 0, 1), 1);
|
|
7
|
-
expect(result).toEqual(new Date(2024, 0, 8));
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
it('should successfully add weeks to a date that crosses months', () => {
|
|
11
|
-
const result = DateService.addWeeks(new Date(2024, 0, 23), 2);
|
|
12
|
-
expect(result).toEqual(new Date(2024, 1, 6));
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it('should successfully add weeks to a date that crosses years', () => {
|
|
16
|
-
const result = DateService.addWeeks(new Date(2024, 11, 25), 1);
|
|
17
|
-
expect(result).toEqual(new Date(2025, 0, 1));
|
|
18
|
-
});
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
describe('getWeekOfMonth', () => {
|
|
22
|
-
it('should successfully get the week of month for a date', () => {
|
|
23
|
-
const result = DateService.getWeekOfMonth(new Date(2024, 0, 14));
|
|
24
|
-
expect(result).toEqual(3);
|
|
25
|
-
|
|
26
|
-
const result2 = DateService.getWeekOfMonth(new Date(2024, 0, 1));
|
|
27
|
-
expect(result2).toEqual(1);
|
|
28
|
-
|
|
29
|
-
const result3 = DateService.getWeekOfMonth(new Date(2024, 0, 31));
|
|
30
|
-
expect(result3).toEqual(5);
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
describe('getWeekDayOfXWeekOfMonth', () => {
|
|
35
|
-
it('should successfully get the 2nd monday of January 2024', () => {
|
|
36
|
-
const result = DateService.getWeekDayOfXWeekOfMonth(
|
|
37
|
-
new Date(2024, 0, 1),
|
|
38
|
-
1,
|
|
39
|
-
2
|
|
40
|
-
);
|
|
41
|
-
expect(result).toEqual(new Date(2024, 0, 8));
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('should successfully get the 3rd monday of January 2024', () => {
|
|
45
|
-
const result = DateService.getWeekDayOfXWeekOfMonth(
|
|
46
|
-
new Date(2024, 0, 1),
|
|
47
|
-
1,
|
|
48
|
-
3
|
|
49
|
-
);
|
|
50
|
-
expect(result).toEqual(new Date(2024, 0, 15));
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('should successfully get the 3rd tuesday of January 2024', () => {
|
|
54
|
-
const result = DateService.getWeekDayOfXWeekOfMonth(
|
|
55
|
-
new Date(2024, 0, 1),
|
|
56
|
-
2,
|
|
57
|
-
3
|
|
58
|
-
);
|
|
59
|
-
expect(result).toEqual(new Date(2024, 0, 16));
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('should successfully get the 1st Saturday of January 2024', () => {
|
|
63
|
-
const result = DateService.getWeekDayOfXWeekOfMonth(
|
|
64
|
-
new Date(2024, 0, 1),
|
|
65
|
-
6,
|
|
66
|
-
1
|
|
67
|
-
);
|
|
68
|
-
expect(result).toEqual(new Date(2024, 0, 6));
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('should successfully get the 1st sunday of January 2024', () => {
|
|
72
|
-
const result = DateService.getWeekDayOfXWeekOfMonth(
|
|
73
|
-
new Date(2024, 0, 1),
|
|
74
|
-
0,
|
|
75
|
-
1
|
|
76
|
-
);
|
|
77
|
-
expect(result).toEqual(new Date(2024, 0, 7));
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('should successfully get the last sunday of January 2024', () => {
|
|
81
|
-
const result = DateService.getWeekDayOfXWeekOfMonth(
|
|
82
|
-
new Date(2024, 0, 1),
|
|
83
|
-
0,
|
|
84
|
-
'last'
|
|
85
|
-
);
|
|
86
|
-
expect(result).toEqual(new Date(2024, 0, 28));
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it('should return null if the week and day do not exist', () => {
|
|
90
|
-
const result = DateService.getWeekDayOfXWeekOfMonth(
|
|
91
|
-
new Date(2024, 0, 1),
|
|
92
|
-
0,
|
|
93
|
-
5
|
|
94
|
-
);
|
|
95
|
-
expect(result).toEqual(null);
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
});
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { writeFile } from 'fs/promises';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import FileSystemService from './FileSystemService.js';
|
|
4
|
-
|
|
5
|
-
const TEST_FOLDER_NAME = '__fileSystemService-tests__';
|
|
6
|
-
|
|
7
|
-
describe('FileSystemService', () => {
|
|
8
|
-
afterAll(async () => {
|
|
9
|
-
await deleteTestFolder();
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
describe('copyFolderContents', () => {
|
|
13
|
-
it('should successfully copy all contents when target folder doesnt exist', async () => {
|
|
14
|
-
// Make a test folder with a folder and a couple files in it
|
|
15
|
-
const testName = 'copyFolderContents-1';
|
|
16
|
-
const sourceFolderName = `${testName}-source`;
|
|
17
|
-
const sourceFolderPath = await createTestFolder(sourceFolderName);
|
|
18
|
-
await createTestFiles(sourceFolderPath, {
|
|
19
|
-
'file1.txt': 'test text',
|
|
20
|
-
'file2.txt': 'test text',
|
|
21
|
-
subFolder: {
|
|
22
|
-
'subFile1.txt': 'sub test text',
|
|
23
|
-
'subFile2.txt': 'sub test text'
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
const targetFolderPath = path.join(
|
|
28
|
-
TEST_FOLDER_NAME,
|
|
29
|
-
`${testName}-target`
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
// Execute
|
|
33
|
-
await FileSystemService.copyFolderContents(
|
|
34
|
-
sourceFolderPath,
|
|
35
|
-
targetFolderPath
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
// Assert
|
|
39
|
-
const expectedContents = (
|
|
40
|
-
await FileSystemService.getAllFilePathsRelative(sourceFolderPath)
|
|
41
|
-
).sort();
|
|
42
|
-
const actualContents = (
|
|
43
|
-
await FileSystemService.getAllFilePathsRelative(targetFolderPath)
|
|
44
|
-
).sort();
|
|
45
|
-
expect(actualContents).toEqual(expectedContents);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('should successfully copy only files that arent ignored', async () => {
|
|
49
|
-
// Make a test folder with a folder and a couple files in it
|
|
50
|
-
const testName = 'copyFolderContents-2';
|
|
51
|
-
const sourceFolderName = `${testName}-source`;
|
|
52
|
-
const sourceFolderPath = await createTestFolder(sourceFolderName);
|
|
53
|
-
await createTestFiles(sourceFolderPath, {
|
|
54
|
-
'file1.txt': 'test text',
|
|
55
|
-
'file2.txt': 'test text',
|
|
56
|
-
subFolder: {
|
|
57
|
-
'subFile1.txt': 'sub test text',
|
|
58
|
-
'subFile2.txt': 'sub test text'
|
|
59
|
-
},
|
|
60
|
-
javascript: {
|
|
61
|
-
'file1.js': 'test text',
|
|
62
|
-
'file2.js': 'test text'
|
|
63
|
-
},
|
|
64
|
-
typescript: {
|
|
65
|
-
'file1.ts': 'test text',
|
|
66
|
-
'file2.ts': 'test text'
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
const targetFolderPath = path.join(
|
|
71
|
-
TEST_FOLDER_NAME,
|
|
72
|
-
`${testName}-target`
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
// Execute
|
|
76
|
-
await FileSystemService.copyFolderContents(
|
|
77
|
-
sourceFolderPath,
|
|
78
|
-
targetFolderPath,
|
|
79
|
-
['ts']
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
// Assert
|
|
83
|
-
const expectedContents = (
|
|
84
|
-
await FileSystemService.getAllFilePathsRelative(sourceFolderPath)
|
|
85
|
-
)
|
|
86
|
-
.filter((sourceFilePath) => !sourceFilePath.endsWith('.ts'))
|
|
87
|
-
.sort();
|
|
88
|
-
const actualContents = (
|
|
89
|
-
await FileSystemService.getAllFilePathsRelative(targetFolderPath)
|
|
90
|
-
).sort();
|
|
91
|
-
expect(actualContents).toEqual(expectedContents);
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Creates test files and folders based on the provided structure
|
|
98
|
-
*
|
|
99
|
-
* @param folderPath The path where the files and folders should be created
|
|
100
|
-
* @param fileStructure An object representing the file structure to create
|
|
101
|
-
*/
|
|
102
|
-
async function createTestFiles(folderPath: string, fileStructure: object) {
|
|
103
|
-
await FileSystemService.checkOrCreateFolder(folderPath);
|
|
104
|
-
|
|
105
|
-
await Promise.all(
|
|
106
|
-
Object.entries(fileStructure).map(async ([key, value]) => {
|
|
107
|
-
if (typeof value === 'string') {
|
|
108
|
-
await writeFile(path.join(folderPath, key), value);
|
|
109
|
-
} else if (typeof value === 'object') {
|
|
110
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
111
|
-
await createTestFiles(path.join(folderPath, key), value);
|
|
112
|
-
}
|
|
113
|
-
})
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Creates a test folder within the main test directory
|
|
119
|
-
*
|
|
120
|
-
* @param folderName The name of the folder to create
|
|
121
|
-
*/
|
|
122
|
-
async function createTestFolder(folderName: string): Promise<string> {
|
|
123
|
-
const testFolderPath = path.join(TEST_FOLDER_NAME, folderName);
|
|
124
|
-
await FileSystemService.checkOrCreateFolder(testFolderPath);
|
|
125
|
-
return testFolderPath;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Deletes the main test folder and all its contents
|
|
130
|
-
*/
|
|
131
|
-
async function deleteTestFolder(): Promise<void> {
|
|
132
|
-
await FileSystemService.deleteFolder(TEST_FOLDER_NAME);
|
|
133
|
-
}
|