@aneuhold/core-ts-lib 2.2.7 → 2.2.8

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.
Files changed (40) hide show
  1. package/lib/index.d.ts +4 -3
  2. package/lib/index.d.ts.map +1 -1
  3. package/lib/index.js +2 -1
  4. package/lib/index.js.map +1 -1
  5. package/lib/index.ts +7 -5
  6. package/lib/interfaces/ITracer.d.ts.map +1 -1
  7. package/lib/interfaces/ITracer.js.map +1 -1
  8. package/lib/interfaces/ITracer.ts +2 -8
  9. package/lib/services/ArrayService.d.ts.map +1 -1
  10. package/lib/services/ArrayService.js.map +1 -1
  11. package/lib/services/ArrayService.ts +1 -4
  12. package/lib/services/DateService/DateService.d.ts.map +1 -1
  13. package/lib/services/DateService/DateService.js +1 -3
  14. package/lib/services/DateService/DateService.js.map +1 -1
  15. package/lib/services/DateService/DateService.ts +7 -25
  16. package/lib/services/DependencyService.d.ts.map +1 -1
  17. package/lib/services/DependencyService.js +1 -3
  18. package/lib/services/DependencyService.js.map +1 -1
  19. package/lib/services/DependencyService.ts +10 -32
  20. package/lib/services/FileSystemService/FileSystemService.d.ts +38 -12
  21. package/lib/services/FileSystemService/FileSystemService.d.ts.map +1 -1
  22. package/lib/services/FileSystemService/FileSystemService.js +83 -26
  23. package/lib/services/FileSystemService/FileSystemService.js.map +1 -1
  24. package/lib/services/FileSystemService/FileSystemService.ts +138 -53
  25. package/lib/services/FileSystemService/GlobMatchingService.d.ts +48 -0
  26. package/lib/services/FileSystemService/GlobMatchingService.d.ts.map +1 -0
  27. package/lib/services/FileSystemService/GlobMatchingService.js +129 -0
  28. package/lib/services/FileSystemService/GlobMatchingService.js.map +1 -0
  29. package/lib/services/FileSystemService/GlobMatchingService.ts +153 -0
  30. package/lib/services/PackageService.d.ts +60 -4
  31. package/lib/services/PackageService.d.ts.map +1 -1
  32. package/lib/services/PackageService.js +182 -43
  33. package/lib/services/PackageService.js.map +1 -1
  34. package/lib/services/PackageService.ts +241 -119
  35. package/lib/utils/ErrorUtils.d.ts.map +1 -1
  36. package/lib/utils/ErrorUtils.js.map +1 -1
  37. package/lib/utils/ErrorUtils.ts +1 -3
  38. package/package.json +1 -1
  39. package/lib/services/DateService/DateService.spec.ts +0 -98
  40. package/lib/services/FileSystemService/FileSystemService.spec.ts +0 -133
@@ -5,6 +5,7 @@ import { promisify } from 'util';
5
5
  import ErrorUtils from '../../utils/ErrorUtils.js';
6
6
  import { DR } from '../DependencyRegistry.js';
7
7
  import StringService from '../StringService.js';
8
+ import GlobMatchingService from './GlobMatchingService.js';
8
9
  const execAsync = promisify(exec);
9
10
  /**
10
11
  * A service which can be used to interact with the file system, only in build
@@ -18,8 +19,8 @@ export default class FileSystemService {
18
19
  *
19
20
  * @param folderPath the path to the folder which contains the file that should
20
21
  * be updated
21
- * @param fileName
22
- * @param textToInsert
22
+ * @param fileName the name of the file to update
23
+ * @param textToInsert the text to insert into the file
23
24
  */
24
25
  static async findAndInsertText(folderPath, fileName, textToInsert) {
25
26
  const filePath = path.join(folderPath, fileName);
@@ -43,8 +44,8 @@ export default class FileSystemService {
43
44
  /**
44
45
  * Copies the contents of one folder to another folder.
45
46
  *
46
- * @param sourceFolderPath
47
- * @param targetFolderPath
47
+ * @param sourceFolderPath the path to the source folder
48
+ * @param targetFolderPath the path to the target folder
48
49
  * @param ignoreExtensions is an array with extensions that should be
49
50
  * ignored. For example, if you want to ignore all .ts files, you would pass
50
51
  * in ['.ts']. Multi-part extensions like '.spec.ts' are also supported.
@@ -65,32 +66,12 @@ export default class FileSystemService {
65
66
  const sourceFile = path.join(sourceFolderPath, sourceFilePath);
66
67
  const targetFile = path.join(targetFolderPath, sourceFilePath);
67
68
  // Check if the file should be ignored based on extensions
68
- if (ignoreExtensions &&
69
- FileSystemService.shouldIgnoreFile(sourceFile, ignoreExtensions)) {
69
+ if (ignoreExtensions && FileSystemService.shouldIgnoreFile(sourceFile, ignoreExtensions)) {
70
70
  return;
71
71
  }
72
72
  await cp(sourceFile, targetFile, { recursive: true });
73
73
  }));
74
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
- }
94
75
  static async checkOrCreateFolder(folderPath) {
95
76
  try {
96
77
  await access(folderPath);
@@ -146,7 +127,11 @@ export default class FileSystemService {
146
127
  static async getAllFilePathsRelative(dirPath) {
147
128
  const filePaths = await this.getAllFilePaths(dirPath);
148
129
  return filePaths.map((filePath) => {
149
- return filePath.replace(dirPath, '');
130
+ const relativePath = filePath.replace(dirPath, '');
131
+ // Remove leading path separator if present
132
+ return relativePath.startsWith('/') || relativePath.startsWith('\\')
133
+ ? relativePath.slice(1)
134
+ : relativePath;
150
135
  });
151
136
  }
152
137
  /**
@@ -193,6 +178,59 @@ export default class FileSystemService {
193
178
  return this.traverseDirectoryTree(startDir, fileName, stopAt, false // findFirst = false
194
179
  );
195
180
  }
181
+ /**
182
+ * Replaces all occurrences of a string in files within a directory.
183
+ * Supports glob patterns for including/excluding files and handles URL encoding.
184
+ *
185
+ * @param options Configuration object for the replacement operation
186
+ */
187
+ static async replaceInFiles(options) {
188
+ const { searchString, replaceString, rootPath, includePatterns = ['**/*'], excludePatterns = ['**/node_modules/**', '**/.*/**'], includeUrlEncoded = true, dryRun = false } = options;
189
+ DR.logger.info(`Replacing "${searchString}" with "${replaceString}" in ${rootPath}`);
190
+ if (dryRun) {
191
+ DR.logger.info('DRY RUN MODE - No files will be modified');
192
+ }
193
+ const allFiles = await this.getAllFilePaths(rootPath);
194
+ const filesToProcess = GlobMatchingService.getMatchingFiles(allFiles, rootPath, includePatterns, excludePatterns);
195
+ let processedCount = 0;
196
+ let modifiedCount = 0;
197
+ for (const filePath of filesToProcess) {
198
+ try {
199
+ const content = await readFile(filePath, 'utf8');
200
+ let hasChanges = false;
201
+ let updatedContent = content;
202
+ // Replace the main string
203
+ if (content.includes(searchString)) {
204
+ updatedContent = updatedContent.replaceAll(searchString, replaceString);
205
+ hasChanges = true;
206
+ }
207
+ // Replace URL-encoded version if requested
208
+ if (includeUrlEncoded) {
209
+ const encodedSearchString = encodeURIComponent(searchString);
210
+ const encodedReplaceString = encodeURIComponent(replaceString);
211
+ if (updatedContent.includes(encodedSearchString)) {
212
+ updatedContent = updatedContent.replaceAll(encodedSearchString, encodedReplaceString);
213
+ hasChanges = true;
214
+ }
215
+ }
216
+ if (hasChanges) {
217
+ const relativePath = path.relative(rootPath, filePath);
218
+ DR.logger.info(`${dryRun ? 'Would update' : 'Updating'} ${relativePath}...`);
219
+ if (!dryRun) {
220
+ await writeFile(filePath, updatedContent, 'utf8');
221
+ }
222
+ modifiedCount++;
223
+ }
224
+ processedCount++;
225
+ }
226
+ catch (error) {
227
+ // Skip binary files or files we can't read
228
+ DR.logger.verbose.info(`Skipping ${filePath}: ${ErrorUtils.getErrorString(error)}`);
229
+ continue;
230
+ }
231
+ }
232
+ DR.logger.info(`${dryRun ? 'Would process' : 'Processed'} ${processedCount} files, ${dryRun ? 'would modify' : 'modified'} ${modifiedCount} files`);
233
+ }
196
234
  /**
197
235
  * Internal helper method that traverses up the directory tree looking for files.
198
236
  *
@@ -235,5 +273,24 @@ export default class FileSystemService {
235
273
  }
236
274
  return results;
237
275
  }
276
+ /**
277
+ * Checks if a file should be ignored based on the provided extensions.
278
+ * Supports both simple extensions (e.g., '.ts') and multi-part extensions (e.g., '.spec.ts').
279
+ *
280
+ * @param filePath the path to the file to check
281
+ * @param ignoreExtensions array of extensions to ignore
282
+ */
283
+ static shouldIgnoreFile(filePath, ignoreExtensions) {
284
+ const fileName = path.basename(filePath);
285
+ return ignoreExtensions.some((extension) => {
286
+ // Handle multi-part extensions like '.spec.ts'
287
+ if (extension.includes('.', 1)) {
288
+ return fileName.endsWith(extension);
289
+ }
290
+ // Handle simple extensions like '.ts'
291
+ const fileExtension = StringService.getFileNameExtension(filePath);
292
+ return fileExtension === extension;
293
+ });
294
+ }
238
295
  }
239
296
  //# sourceMappingURL=FileSystemService.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FileSystemService.js","sourceRoot":"","sources":["../../../src/services/FileSystemService/FileSystemService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FileSystemService.js","sourceRoot":"","sources":["../../../src/services/FileSystemService/FileSystemService.ts"],"names":[],"mappings":"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"}
@@ -1,23 +1,34 @@
1
1
  import { exec } from 'child_process';
2
- import {
3
- access,
4
- appendFile,
5
- cp,
6
- mkdir,
7
- readFile,
8
- readdir,
9
- rm,
10
- stat,
11
- writeFile
12
- } from 'fs/promises';
2
+ import { access, appendFile, cp, mkdir, readFile, readdir, rm, stat, writeFile } from 'fs/promises';
13
3
  import path from 'path';
14
4
  import { promisify } from 'util';
15
5
  import ErrorUtils from '../../utils/ErrorUtils.js';
16
6
  import { DR } from '../DependencyRegistry.js';
17
7
  import StringService from '../StringService.js';
8
+ import GlobMatchingService from './GlobMatchingService.js';
18
9
 
19
10
  const execAsync = promisify(exec);
20
11
 
12
+ /**
13
+ * Options for the replaceInFiles method
14
+ */
15
+ export type ReplaceInFilesOptions = {
16
+ /** The string to search for */
17
+ searchString: string;
18
+ /** The string to replace it with */
19
+ replaceString: string;
20
+ /** The root directory to search in */
21
+ rootPath: string;
22
+ /** Array of glob-like patterns to include (defaults to all files) */
23
+ includePatterns?: string[];
24
+ /** Array of glob-like patterns to exclude (defaults to common ignore patterns) */
25
+ excludePatterns?: string[];
26
+ /** Whether to also replace URL-encoded versions of the strings */
27
+ includeUrlEncoded?: boolean;
28
+ /** If true, only shows what would be changed without making changes */
29
+ dryRun?: boolean;
30
+ };
31
+
21
32
  /**
22
33
  * A service which can be used to interact with the file system, only in build
23
34
  * steps.
@@ -30,8 +41,8 @@ export default class FileSystemService {
30
41
  *
31
42
  * @param folderPath the path to the folder which contains the file that should
32
43
  * be updated
33
- * @param fileName
34
- * @param textToInsert
44
+ * @param fileName the name of the file to update
45
+ * @param textToInsert the text to insert into the file
35
46
  */
36
47
  static async findAndInsertText(
37
48
  folderPath: string,
@@ -62,8 +73,8 @@ export default class FileSystemService {
62
73
  /**
63
74
  * Copies the contents of one folder to another folder.
64
75
  *
65
- * @param sourceFolderPath
66
- * @param targetFolderPath
76
+ * @param sourceFolderPath the path to the source folder
77
+ * @param targetFolderPath the path to the target folder
67
78
  * @param ignoreExtensions is an array with extensions that should be
68
79
  * ignored. For example, if you want to ignore all .ts files, you would pass
69
80
  * in ['.ts']. Multi-part extensions like '.spec.ts' are also supported.
@@ -83,8 +94,7 @@ export default class FileSystemService {
83
94
  await FileSystemService.checkOrCreateFolder(targetFolderPath);
84
95
 
85
96
  // Get the files in the source directory
86
- const sourceFilePaths =
87
- await FileSystemService.getAllFilePathsRelative(sourceFolderPath);
97
+ const sourceFilePaths = await FileSystemService.getAllFilePathsRelative(sourceFolderPath);
88
98
 
89
99
  await Promise.all(
90
100
  sourceFilePaths.map(async (sourceFilePath) => {
@@ -92,10 +102,7 @@ export default class FileSystemService {
92
102
  const targetFile = path.join(targetFolderPath, sourceFilePath);
93
103
 
94
104
  // Check if the file should be ignored based on extensions
95
- if (
96
- ignoreExtensions &&
97
- FileSystemService.shouldIgnoreFile(sourceFile, ignoreExtensions)
98
- ) {
105
+ if (ignoreExtensions && FileSystemService.shouldIgnoreFile(sourceFile, ignoreExtensions)) {
99
106
  return;
100
107
  }
101
108
 
@@ -104,38 +111,11 @@ export default class FileSystemService {
104
111
  );
105
112
  }
106
113
 
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
-
132
114
  static async checkOrCreateFolder(folderPath: string): Promise<void> {
133
115
  try {
134
116
  await access(folderPath);
135
117
  } catch {
136
- DR.logger.verbose.info(
137
- `Directory "${folderPath}" does not exist. Creating it now...`
138
- );
118
+ DR.logger.verbose.info(`Directory "${folderPath}" does not exist. Creating it now...`);
139
119
  await mkdir(folderPath, { recursive: true });
140
120
  }
141
121
  }
@@ -191,7 +171,11 @@ export default class FileSystemService {
191
171
  static async getAllFilePathsRelative(dirPath: string): Promise<string[]> {
192
172
  const filePaths = await this.getAllFilePaths(dirPath);
193
173
  return filePaths.map((filePath) => {
194
- return filePath.replace(dirPath, '');
174
+ const relativePath = filePath.replace(dirPath, '');
175
+ // Remove leading path separator if present
176
+ return relativePath.startsWith('/') || relativePath.startsWith('\\')
177
+ ? relativePath.slice(1)
178
+ : relativePath;
195
179
  });
196
180
  }
197
181
 
@@ -206,9 +190,7 @@ export default class FileSystemService {
206
190
  const { stdout } = await execAsync('git status --porcelain');
207
191
  return stdout.trim().length > 0;
208
192
  } catch (error) {
209
- DR.logger.error(
210
- `Failed to check for pending changes: ${ErrorUtils.getErrorString(error)}`
211
- );
193
+ DR.logger.error(`Failed to check for pending changes: ${ErrorUtils.getErrorString(error)}`);
212
194
  return false;
213
195
  }
214
196
  }
@@ -259,6 +241,87 @@ export default class FileSystemService {
259
241
  );
260
242
  }
261
243
 
244
+ /**
245
+ * Replaces all occurrences of a string in files within a directory.
246
+ * Supports glob patterns for including/excluding files and handles URL encoding.
247
+ *
248
+ * @param options Configuration object for the replacement operation
249
+ */
250
+ static async replaceInFiles(options: ReplaceInFilesOptions): Promise<void> {
251
+ const {
252
+ searchString,
253
+ replaceString,
254
+ rootPath,
255
+ includePatterns = ['**/*'],
256
+ excludePatterns = ['**/node_modules/**', '**/.*/**'],
257
+ includeUrlEncoded = true,
258
+ dryRun = false
259
+ } = options;
260
+
261
+ DR.logger.info(`Replacing "${searchString}" with "${replaceString}" in ${rootPath}`);
262
+
263
+ if (dryRun) {
264
+ DR.logger.info('DRY RUN MODE - No files will be modified');
265
+ }
266
+
267
+ const allFiles = await this.getAllFilePaths(rootPath);
268
+ const filesToProcess = GlobMatchingService.getMatchingFiles(
269
+ allFiles,
270
+ rootPath,
271
+ includePatterns,
272
+ excludePatterns
273
+ );
274
+
275
+ let processedCount = 0;
276
+ let modifiedCount = 0;
277
+
278
+ for (const filePath of filesToProcess) {
279
+ try {
280
+ const content = await readFile(filePath, 'utf8');
281
+ let hasChanges = false;
282
+ let updatedContent = content;
283
+
284
+ // Replace the main string
285
+ if (content.includes(searchString)) {
286
+ updatedContent = updatedContent.replaceAll(searchString, replaceString);
287
+ hasChanges = true;
288
+ }
289
+
290
+ // Replace URL-encoded version if requested
291
+ if (includeUrlEncoded) {
292
+ const encodedSearchString = encodeURIComponent(searchString);
293
+ const encodedReplaceString = encodeURIComponent(replaceString);
294
+
295
+ if (updatedContent.includes(encodedSearchString)) {
296
+ updatedContent = updatedContent.replaceAll(encodedSearchString, encodedReplaceString);
297
+ hasChanges = true;
298
+ }
299
+ }
300
+
301
+ if (hasChanges) {
302
+ const relativePath = path.relative(rootPath, filePath);
303
+ DR.logger.info(`${dryRun ? 'Would update' : 'Updating'} ${relativePath}...`);
304
+
305
+ if (!dryRun) {
306
+ await writeFile(filePath, updatedContent, 'utf8');
307
+ }
308
+
309
+ modifiedCount++;
310
+ }
311
+
312
+ processedCount++;
313
+ } catch (error) {
314
+ // Skip binary files or files we can't read
315
+ DR.logger.verbose.info(`Skipping ${filePath}: ${ErrorUtils.getErrorString(error)}`);
316
+ continue;
317
+ }
318
+ }
319
+
320
+ DR.logger.info(
321
+ `${dryRun ? 'Would process' : 'Processed'} ${processedCount} files, ${dryRun ? 'would modify' : 'modified'} ${modifiedCount} files`
322
+ );
323
+ }
324
+
262
325
  /**
263
326
  * Internal helper method that traverses up the directory tree looking for files.
264
327
  *
@@ -309,4 +372,26 @@ export default class FileSystemService {
309
372
 
310
373
  return results;
311
374
  }
375
+
376
+ /**
377
+ * Checks if a file should be ignored based on the provided extensions.
378
+ * Supports both simple extensions (e.g., '.ts') and multi-part extensions (e.g., '.spec.ts').
379
+ *
380
+ * @param filePath the path to the file to check
381
+ * @param ignoreExtensions array of extensions to ignore
382
+ */
383
+ private static shouldIgnoreFile(filePath: string, ignoreExtensions: string[]): boolean {
384
+ const fileName = path.basename(filePath);
385
+
386
+ return ignoreExtensions.some((extension) => {
387
+ // Handle multi-part extensions like '.spec.ts'
388
+ if (extension.includes('.', 1)) {
389
+ return fileName.endsWith(extension);
390
+ }
391
+
392
+ // Handle simple extensions like '.ts'
393
+ const fileExtension = StringService.getFileNameExtension(filePath);
394
+ return fileExtension === extension;
395
+ });
396
+ }
312
397
  }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * A service for handling glob-like pattern matching operations.
3
+ * Supports common glob patterns like **, *, and exact matches.
4
+ *
5
+ * Inspired by the isaacs/node-glob library (ISC License)
6
+ * but simplified for basic use cases.
7
+ */
8
+ export default class GlobMatchingService {
9
+ /**
10
+ * Gets files matching the include patterns while excluding those that match exclude patterns.
11
+ * Uses simple glob-like matching for common patterns.
12
+ *
13
+ * @param allFiles Array of all file paths to filter
14
+ * @param rootPath The root directory path for computing relative paths
15
+ * @param includePatterns Array of glob-like patterns to include
16
+ * @param excludePatterns Array of glob-like patterns to exclude
17
+ */
18
+ static getMatchingFiles(allFiles: string[], rootPath: string, includePatterns: string[], excludePatterns: string[]): string[];
19
+ /**
20
+ * Simple glob-like pattern matching for common use cases.
21
+ * Supports:
22
+ * - ** for any number of directories (globstar)
23
+ * - * for any characters except path separators
24
+ * - Exact matches
25
+ *
26
+ * @param filePath The file path to test
27
+ * @param pattern The pattern to match against
28
+ */
29
+ static matchesPattern(filePath: string, pattern: string): boolean;
30
+ /**
31
+ * Match path segments against pattern segments with support for globstar (**).
32
+ *
33
+ * The idea is that each segment doesn't cross path separators. It should
34
+ * be split by '/' and then matched segment by segment.
35
+ *
36
+ * @param pathSegments Array of path segments
37
+ * @param patternSegments Array of pattern segments
38
+ */
39
+ private static matchSegments;
40
+ /**
41
+ * Match a single segment with support for * wildcard
42
+ *
43
+ * @param pathSegment Single path segment
44
+ * @param patternSegment Single pattern segment
45
+ */
46
+ private static matchSingleSegment;
47
+ }
48
+ //# sourceMappingURL=GlobMatchingService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlobMatchingService.d.ts","sourceRoot":"","sources":["../../../src/services/FileSystemService/GlobMatchingService.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,mBAAmB;IACtC;;;;;;;;OAQG;IACH,MAAM,CAAC,gBAAgB,CACrB,QAAQ,EAAE,MAAM,EAAE,EAClB,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,EAAE,EACzB,eAAe,EAAE,MAAM,EAAE,GACxB,MAAM,EAAE;IAcX;;;;;;;;;OASG;IACH,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IAiBjE;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAuD5B;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;CAiBlC"}
@@ -0,0 +1,129 @@
1
+ import path from 'path';
2
+ /**
3
+ * A service for handling glob-like pattern matching operations.
4
+ * Supports common glob patterns like **, *, and exact matches.
5
+ *
6
+ * Inspired by the isaacs/node-glob library (ISC License)
7
+ * but simplified for basic use cases.
8
+ */
9
+ export default class GlobMatchingService {
10
+ /**
11
+ * Gets files matching the include patterns while excluding those that match exclude patterns.
12
+ * Uses simple glob-like matching for common patterns.
13
+ *
14
+ * @param allFiles Array of all file paths to filter
15
+ * @param rootPath The root directory path for computing relative paths
16
+ * @param includePatterns Array of glob-like patterns to include
17
+ * @param excludePatterns Array of glob-like patterns to exclude
18
+ */
19
+ static getMatchingFiles(allFiles, rootPath, includePatterns, excludePatterns) {
20
+ return allFiles.filter((filePath) => {
21
+ const relativePath = path.relative(rootPath, filePath);
22
+ // Check if file matches any exclude pattern
23
+ if (excludePatterns.some((pattern) => this.matchesPattern(relativePath, pattern))) {
24
+ return false;
25
+ }
26
+ // Check if file matches any include pattern
27
+ return includePatterns.some((pattern) => this.matchesPattern(relativePath, pattern));
28
+ });
29
+ }
30
+ /**
31
+ * Simple glob-like pattern matching for common use cases.
32
+ * Supports:
33
+ * - ** for any number of directories (globstar)
34
+ * - * for any characters except path separators
35
+ * - Exact matches
36
+ *
37
+ * @param filePath The file path to test
38
+ * @param pattern The pattern to match against
39
+ */
40
+ static matchesPattern(filePath, pattern) {
41
+ // Normalize path separators to forward slashes
42
+ const normalizedPath = filePath.replace(/\\/g, '/');
43
+ const normalizedPattern = pattern.replace(/\\/g, '/');
44
+ // Handle special case of **/* which should match everything
45
+ if (normalizedPattern === '**/*') {
46
+ return true;
47
+ }
48
+ // Split into segments for more precise matching
49
+ const pathSegments = normalizedPath.split('/');
50
+ const patternSegments = normalizedPattern.split('/');
51
+ return this.matchSegments(pathSegments, patternSegments);
52
+ }
53
+ /**
54
+ * Match path segments against pattern segments with support for globstar (**).
55
+ *
56
+ * The idea is that each segment doesn't cross path separators. It should
57
+ * be split by '/' and then matched segment by segment.
58
+ *
59
+ * @param pathSegments Array of path segments
60
+ * @param patternSegments Array of pattern segments
61
+ */
62
+ static matchSegments(pathSegments, patternSegments) {
63
+ let pathIndex = 0;
64
+ let patternIndex = 0;
65
+ while (pathIndex < pathSegments.length && patternIndex < patternSegments.length) {
66
+ const pathSegment = pathSegments[pathIndex];
67
+ const patternSegment = patternSegments[patternIndex];
68
+ if (patternSegment === '**') {
69
+ // Handle globstar - it can match zero or more segments
70
+ patternIndex++;
71
+ // If ** is the last segment, it matches everything remaining
72
+ if (patternIndex >= patternSegments.length) {
73
+ return true;
74
+ }
75
+ // Try to match the rest of the pattern against remaining path segments
76
+ const remainingPattern = patternSegments.slice(patternIndex);
77
+ // Try matching from current position onwards
78
+ for (let i = pathIndex; i <= pathSegments.length; i++) {
79
+ const remainingPath = pathSegments.slice(i);
80
+ if (this.matchSegments(remainingPath, remainingPattern)) {
81
+ return true;
82
+ }
83
+ }
84
+ return false;
85
+ }
86
+ else if (this.matchSingleSegment(pathSegment, patternSegment)) {
87
+ // Regular segment match
88
+ pathIndex++;
89
+ patternIndex++;
90
+ }
91
+ else {
92
+ return false;
93
+ }
94
+ }
95
+ // Check if we've consumed both path and pattern completely
96
+ // or if remaining pattern segments are only globstars
97
+ const remainingPattern = patternSegments.slice(patternIndex);
98
+ const pathConsumed = pathIndex >= pathSegments.length;
99
+ const patternConsumed = patternIndex >= patternSegments.length;
100
+ if (pathConsumed && patternConsumed) {
101
+ return true;
102
+ }
103
+ if (pathConsumed && remainingPattern.every((seg) => seg === '**')) {
104
+ return true;
105
+ }
106
+ return false;
107
+ }
108
+ /**
109
+ * Match a single segment with support for * wildcard
110
+ *
111
+ * @param pathSegment Single path segment
112
+ * @param patternSegment Single pattern segment
113
+ */
114
+ static matchSingleSegment(pathSegment, patternSegment) {
115
+ if (patternSegment === '*') {
116
+ return true;
117
+ }
118
+ if (patternSegment === pathSegment) {
119
+ return true;
120
+ }
121
+ // Convert pattern to regex for more complex matching
122
+ const regexPattern = patternSegment
123
+ .replace(/\./g, '\\.') // Escape dots
124
+ .replace(/\*/g, '[^/]*'); // * matches anything except slashes
125
+ const regex = new RegExp(`^${regexPattern}$`);
126
+ return regex.test(pathSegment);
127
+ }
128
+ }
129
+ //# sourceMappingURL=GlobMatchingService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlobMatchingService.js","sourceRoot":"","sources":["../../../src/services/FileSystemService/GlobMatchingService.ts"],"names":[],"mappings":"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"}