@node-cli/search 3.0.1 → 3.1.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/dist/core.d.ts CHANGED
@@ -20,7 +20,8 @@ export declare class Search {
20
20
  printMode?: string;
21
21
  gitIgnoreHandler: GitIgnoreHandler;
22
22
  ignoreGitIgnore?: boolean;
23
- constructor({ boring, command, dot, grep, ignoreCase, short, path, pattern, stats, type, ignoreExtension, ignoreFile, ignoreFolder, printMode, ignoreGitIgnore, }: {
23
+ minifyForLLM?: boolean;
24
+ constructor({ boring, command, dot, grep, ignoreCase, short, path, pattern, stats, type, ignoreExtension, ignoreFile, ignoreFolder, printMode, ignoreGitIgnore, minifyForLLM, }: {
24
25
  boring?: boolean;
25
26
  command?: string;
26
27
  dot?: boolean;
@@ -36,11 +37,11 @@ export declare class Search {
36
37
  ignoreFolder?: string[];
37
38
  printMode?: string;
38
39
  ignoreGitIgnore?: boolean;
40
+ minifyForLLM?: boolean;
39
41
  });
40
42
  shouldIgnoreFolder(directory: string): boolean;
41
43
  shouldIgnoreFile(filePath: string): boolean;
42
44
  filterHidden(value: string[] | string): boolean;
43
- isBinaryFileExtension(filePath: string): boolean;
44
45
  start(returnResults?: boolean): Promise<string>;
45
46
  scanFileSystem(nodes: string[]): Promise<void>;
46
47
  readFileContent(filePath: string): Promise<string>;
package/dist/core.js CHANGED
@@ -1,12 +1,13 @@
1
- import { basename, extname, join, relative } from "node:path";
2
- import { GitIgnoreHandler } from "./gitIgnoreHandler.js";
3
- import { STR_TYPE_BOTH, STR_TYPE_DIRECTORY, STR_TYPE_FILE, checkPattern, formatLongListings, printStatistics, runCommandOnNode, runGrepOnNode } from "./utilities.js";
1
+ import { basename, join, relative } from "node:path";
4
2
  import { promisify } from "node:util";
5
3
  import { Logger } from "@node-cli/logger";
6
4
  import { Performance } from "@node-cli/perf";
7
5
  import fs from "fs-extra";
8
6
  import kleur from "kleur";
9
7
  import plur from "plur";
8
+ import { GitIgnoreHandler } from "./gitIgnoreHandler.js";
9
+ import { minifyFileContent } from "./minifiers.js";
10
+ import { STR_TYPE_BOTH, STR_TYPE_DIRECTORY, STR_TYPE_FILE, checkPattern, formatLongListings, getFileExtension, isBinaryFileExtension, printStatistics, runCommandOnNode, runGrepOnNode } from "./utilities.js";
10
11
  const lstatAsync = promisify(fs.lstat);
11
12
  const readdirAsync = promisify(fs.readdir);
12
13
  const readFileAsync = promisify(fs.readFile);
@@ -38,7 +39,8 @@ export class Search {
38
39
  printMode;
39
40
  gitIgnoreHandler;
40
41
  ignoreGitIgnore;
41
- constructor({ boring, command, dot, grep, ignoreCase, short, path, pattern, stats, type, ignoreExtension, ignoreFile, ignoreFolder, printMode, ignoreGitIgnore }){
42
+ minifyForLLM;
43
+ constructor({ boring, command, dot, grep, ignoreCase, short, path, pattern, stats, type, ignoreExtension, ignoreFile, ignoreFolder, printMode, ignoreGitIgnore, minifyForLLM }){
42
44
  this.path = path;
43
45
  this.rePattern = pattern ? new RegExp(pattern, ignoreCase ? "i" : "") : undefined;
44
46
  this.type = type || STR_TYPE_BOTH;
@@ -58,6 +60,7 @@ export class Search {
58
60
  this.ignoreFolders = ignoreFolder || [];
59
61
  this.printMode = printMode;
60
62
  this.ignoreGitIgnore = ignoreGitIgnore;
63
+ this.minifyForLLM = minifyForLLM;
61
64
  this.gitIgnoreHandler = new GitIgnoreHandler();
62
65
  try {
63
66
  this.grep = grep ? new RegExp(grep, ignoreCase ? "gi" : "g") : undefined;
@@ -84,7 +87,7 @@ export class Search {
84
87
  if (!this.ignoreExtensions || this.ignoreExtensions.length === 0) {
85
88
  return false;
86
89
  }
87
- const extension = extname(filePath).toLowerCase().replace(/^\./, "");
90
+ const extension = getFileExtension(filePath);
88
91
  // Check for exact extension match
89
92
  if (this.ignoreExtensions.includes(extension)) {
90
93
  return true;
@@ -108,70 +111,6 @@ export class Search {
108
111
  }
109
112
  return value[0] !== ".";
110
113
  }
111
- isBinaryFileExtension(filePath) {
112
- const ext = extname(filePath).toLowerCase().replace(/^\./, "");
113
- // If there's no extension, assume it's binary
114
- /* istanbul ignore if */ if (!ext) {
115
- return true;
116
- }
117
- const binaryExtensions = [
118
- // Executables and compiled code
119
- "exe",
120
- "dll",
121
- "so",
122
- "dylib",
123
- "bin",
124
- "obj",
125
- "o",
126
- // Compressed files
127
- "zip",
128
- "tar",
129
- "gz",
130
- "rar",
131
- "7z",
132
- "jar",
133
- "war",
134
- // Media files
135
- "jpg",
136
- "jpeg",
137
- "png",
138
- "gif",
139
- "bmp",
140
- "ico",
141
- "tif",
142
- "tiff",
143
- "mp3",
144
- "mp4",
145
- "avi",
146
- "mov",
147
- "wmv",
148
- "flv",
149
- "wav",
150
- "ogg",
151
- // Document formats
152
- "pdf",
153
- "doc",
154
- "docx",
155
- "xls",
156
- "xlsx",
157
- "ppt",
158
- "pptx",
159
- // Database files
160
- "db",
161
- "sqlite",
162
- "mdb",
163
- // Other binary formats
164
- "class",
165
- "pyc",
166
- "pyd",
167
- "pyo",
168
- "woff",
169
- "woff2",
170
- "ttf",
171
- "otf"
172
- ];
173
- return binaryExtensions.includes(ext);
174
- }
175
114
  async start(returnResults = false) {
176
115
  if (this.displayStats) {
177
116
  perf.start();
@@ -254,13 +193,13 @@ export class Search {
254
193
  async readFileContent(filePath) {
255
194
  try {
256
195
  // Check if it's a known binary extension
257
- /* istanbul ignore if */ if (this.isBinaryFileExtension(filePath)) {
258
- return "[Binary file]";
196
+ /* v8 ignore next */ if (isBinaryFileExtension(filePath)) {
197
+ return null;
259
198
  }
260
199
  const content = await readFileAsync(filePath, "utf8");
261
- return content;
262
- } catch (error) {
263
- /* istanbul ignore next */ return `Error reading file: ${error.message}`;
200
+ return this.minifyForLLM ? await minifyFileContent(filePath, content) : content;
201
+ } catch (_error) {
202
+ /* v8 ignore next */ return null;
264
203
  }
265
204
  }
266
205
  async printFilesContent(returnResults) {
@@ -299,13 +238,15 @@ export class Search {
299
238
  const relativePath = relative(this.path, node.name);
300
239
  const content = await this.readFileContent(node.name);
301
240
  if (returnResults) {
302
- loggerInMemory.log(`<document index="${i + 1}">`);
303
- loggerInMemory.log(`<source>./${relativePath}</source>`);
304
- loggerInMemory.log("<document_content>");
305
- loggerInMemory.log(content);
306
- loggerInMemory.log("</document_content>");
307
- loggerInMemory.log("</document>");
308
- } else {
241
+ if (content) {
242
+ loggerInMemory.log(`<document index="${i + 1}">`);
243
+ loggerInMemory.log(`<source>./${relativePath}</source>`);
244
+ loggerInMemory.log("<document_content>");
245
+ loggerInMemory.log(content);
246
+ loggerInMemory.log("</document_content>");
247
+ loggerInMemory.log("</document>");
248
+ }
249
+ } else if (content) {
309
250
  logger.log(`<document index="${i + 1}">`);
310
251
  logger.log(`<source>./${relativePath}</source>`);
311
252
  logger.log("<document_content>");
@@ -325,7 +266,7 @@ export class Search {
325
266
  return results;
326
267
  }
327
268
  async shouldIgnoreByGitIgnore(nodePath, isDirectory) {
328
- /* istanbul ignore if */ if (this.ignoreGitIgnore) {
269
+ if (this.ignoreGitIgnore) {
329
270
  return false;
330
271
  }
331
272
  return this.gitIgnoreHandler.isIgnored(nodePath, isDirectory);
@@ -345,7 +286,7 @@ export class Search {
345
286
  ].includes(this.printMode)) {
346
287
  return await this.printFilesContent(returnResults);
347
288
  }
348
- /* istanbul ignore if */ if (!this.boring) {
289
+ /* v8 ignore next */ if (!this.boring) {
349
290
  logger.log();
350
291
  }
351
292
  for (const node of this.nodesList){
@@ -357,7 +298,7 @@ export class Search {
357
298
  owner: "",
358
299
  size: ""
359
300
  }, name, separator = "";
360
- /* istanbul ignore if */ if (this.displayLongListing) {
301
+ /* v8 ignore next */ if (this.displayLongListing) {
361
302
  list = await formatLongListings(node.stat, node.type);
362
303
  separator = "\t";
363
304
  }
@@ -373,14 +314,14 @@ export class Search {
373
314
  }
374
315
  if (this.grep && node.type === STR_TYPE_FILE) {
375
316
  const { totalMatchingLines, results } = await runGrepOnNode(node.name, this.grep);
376
- /* istanbul ignore else */ if (totalMatchingLines) {
317
+ /* v8 ignore next */ if (totalMatchingLines) {
377
318
  this.totalFileFound++;
378
319
  const occurrences = plur("occurrence", totalMatchingLines);
379
320
  logger.log(` %s${separator}%s${separator}%s${separator}%s${separator}%s`, list.mode.trim(), list.owner.trim(), list.size.trim(), list.mdate, name, `(${kleur.white(totalMatchingLines)} ${occurrences})`);
380
321
  logger.log(`${results.join("\n")}\n`);
381
322
  }
382
323
  } else {
383
- /* istanbul ignore next */ if (!this.grep) {
324
+ /* v8 ignore next */ if (!this.grep) {
384
325
  logger.log(` %s${separator}%s${separator}%s${separator}%s${separator}%s`, list.mode.trim(), list.owner.trim(), list.size.trim(), list.mdate, name);
385
326
  if (node.command) {
386
327
  await runCommandOnNode(node.name, node.command);
package/dist/core.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core.ts"],"sourcesContent":["import { basename, extname, join, relative } from \"node:path\";\n\nimport { GitIgnoreHandler } from \"./gitIgnoreHandler.js\";\nimport {\n\tSTR_TYPE_BOTH,\n\tSTR_TYPE_DIRECTORY,\n\tSTR_TYPE_FILE,\n\tcheckPattern,\n\tformatLongListings,\n\tprintStatistics,\n\trunCommandOnNode,\n\trunGrepOnNode,\n} from \"./utilities.js\";\n\nimport { promisify } from \"node:util\";\nimport { Logger } from \"@node-cli/logger\";\nimport { Performance } from \"@node-cli/perf\";\nimport fs from \"fs-extra\";\nimport kleur from \"kleur\";\nimport plur from \"plur\";\n\nconst lstatAsync = promisify(fs.lstat);\nconst readdirAsync = promisify(fs.readdir);\nconst readFileAsync = promisify(fs.readFile);\nconst perf = new Performance();\nconst logger = new Logger({\n\tboring: process.env.NODE_ENV === \"test\",\n});\nconst loggerInMemory = new Logger({\n\tinMemory: true,\n});\n\nexport class Search {\n\tboring?: boolean;\n\tcommand?: string;\n\tdisplayHiddenFilesAndFolders?: boolean;\n\tdisplayLongListing?: boolean;\n\tdisplayStats?: boolean;\n\tgrep?: RegExp;\n\tnodesList?: any[];\n\tpath?: string;\n\trePattern?: RegExp;\n\ttotalDirFound?: number;\n\ttotalDirScanned?: number;\n\ttotalFileFound?: number;\n\ttotalFileScanned?: number;\n\ttype?: string;\n\tignoreExtensions?: string[];\n\tignoreFiles?: string[];\n\tignoreFolders?: string[];\n\tprintMode?: string;\n\tgitIgnoreHandler: GitIgnoreHandler;\n\tignoreGitIgnore?: boolean;\n\n\tconstructor({\n\t\tboring,\n\t\tcommand,\n\t\tdot,\n\t\tgrep,\n\t\tignoreCase,\n\t\tshort,\n\t\tpath,\n\t\tpattern,\n\t\tstats,\n\t\ttype,\n\t\tignoreExtension,\n\t\tignoreFile,\n\t\tignoreFolder,\n\t\tprintMode,\n\t\tignoreGitIgnore,\n\t}: {\n\t\tboring?: boolean;\n\t\tcommand?: string;\n\t\tdot?: boolean;\n\t\tgrep?: string | RegExp;\n\t\tignoreCase?: boolean;\n\t\tshort?: boolean;\n\t\tpath?: string;\n\t\tpattern?: string;\n\t\tstats?: boolean;\n\t\ttype?: string;\n\t\tignoreExtension?: string[];\n\t\tignoreFile?: string[];\n\t\tignoreFolder?: string[];\n\t\tprintMode?: string;\n\t\tignoreGitIgnore?: boolean;\n\t}) {\n\t\tthis.path = path;\n\t\tthis.rePattern = pattern\n\t\t\t? new RegExp(pattern, ignoreCase ? \"i\" : \"\")\n\t\t\t: undefined;\n\t\tthis.type = type || STR_TYPE_BOTH;\n\t\tthis.boring = boring;\n\t\tkleur.enabled = !boring;\n\t\tthis.displayLongListing = !short;\n\t\tthis.displayStats = stats;\n\t\tthis.displayHiddenFilesAndFolders = dot;\n\t\tthis.nodesList = [];\n\t\tthis.totalDirScanned = 0;\n\t\tthis.totalFileScanned = 0;\n\t\tthis.totalDirFound = 0;\n\t\tthis.totalFileFound = 0;\n\t\tthis.command = command ? command.trim() : undefined;\n\t\tthis.ignoreExtensions =\n\t\t\t(ignoreExtension && ignoreExtension.map((ext) => ext.toLowerCase())) ||\n\t\t\t[];\n\t\tthis.ignoreFiles = ignoreFile || [];\n\t\tthis.ignoreFolders = ignoreFolder || [];\n\t\tthis.printMode = printMode;\n\t\tthis.ignoreGitIgnore = ignoreGitIgnore;\n\t\tthis.gitIgnoreHandler = new GitIgnoreHandler();\n\t\ttry {\n\t\t\tthis.grep = grep ? new RegExp(grep, ignoreCase ? \"gi\" : \"g\") : undefined;\n\t\t} catch (error) {\n\t\t\tlogger.error(error);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tshouldIgnoreFolder(directory: string) {\n\t\tconst folderName = basename(directory);\n\t\t// Check for exact folder name match\n\t\tif (this.ignoreFolders && this.ignoreFolders.includes(folderName)) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tshouldIgnoreFile(filePath: string) {\n\t\t// First check if the file is in the ignoreFiles list\n\t\tconst filename = basename(filePath);\n\t\tif (this.ignoreFiles && this.ignoreFiles.includes(filename)) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Then check if the extension should be ignored\n\t\tif (!this.ignoreExtensions || this.ignoreExtensions.length === 0) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst extension = extname(filePath).toLowerCase().replace(/^\\./, \"\");\n\n\t\t// Check for exact extension match\n\t\tif (this.ignoreExtensions.includes(extension)) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Check for complex patterns like \"min.js\"\n\t\tfor (const pattern of this.ignoreExtensions) {\n\t\t\t// Skip patterns that don't contain a dot\n\t\t\tif (!pattern.includes(\".\")) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Check if the filename ends with the pattern\n\t\t\tif (filename.toLowerCase().endsWith(`.${pattern}`)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tfilterHidden(value: string[] | string) {\n\t\tif (this.displayHiddenFilesAndFolders) {\n\t\t\treturn true;\n\t\t}\n\t\treturn value[0] !== \".\";\n\t}\n\n\tisBinaryFileExtension(filePath: string): boolean {\n\t\tconst ext = extname(filePath).toLowerCase().replace(/^\\./, \"\");\n\n\t\t// If there's no extension, assume it's binary\n\t\t/* istanbul ignore if */\n\t\tif (!ext) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst binaryExtensions = [\n\t\t\t// Executables and compiled code\n\t\t\t\"exe\",\n\t\t\t\"dll\",\n\t\t\t\"so\",\n\t\t\t\"dylib\",\n\t\t\t\"bin\",\n\t\t\t\"obj\",\n\t\t\t\"o\",\n\t\t\t// Compressed files\n\t\t\t\"zip\",\n\t\t\t\"tar\",\n\t\t\t\"gz\",\n\t\t\t\"rar\",\n\t\t\t\"7z\",\n\t\t\t\"jar\",\n\t\t\t\"war\",\n\t\t\t// Media files\n\t\t\t\"jpg\",\n\t\t\t\"jpeg\",\n\t\t\t\"png\",\n\t\t\t\"gif\",\n\t\t\t\"bmp\",\n\t\t\t\"ico\",\n\t\t\t\"tif\",\n\t\t\t\"tiff\",\n\t\t\t\"mp3\",\n\t\t\t\"mp4\",\n\t\t\t\"avi\",\n\t\t\t\"mov\",\n\t\t\t\"wmv\",\n\t\t\t\"flv\",\n\t\t\t\"wav\",\n\t\t\t\"ogg\",\n\t\t\t// Document formats\n\t\t\t\"pdf\",\n\t\t\t\"doc\",\n\t\t\t\"docx\",\n\t\t\t\"xls\",\n\t\t\t\"xlsx\",\n\t\t\t\"ppt\",\n\t\t\t\"pptx\",\n\t\t\t// Database files\n\t\t\t\"db\",\n\t\t\t\"sqlite\",\n\t\t\t\"mdb\",\n\t\t\t// Other binary formats\n\t\t\t\"class\",\n\t\t\t\"pyc\",\n\t\t\t\"pyd\",\n\t\t\t\"pyo\",\n\t\t\t\"woff\",\n\t\t\t\"woff2\",\n\t\t\t\"ttf\",\n\t\t\t\"otf\",\n\t\t];\n\n\t\treturn binaryExtensions.includes(ext);\n\t}\n\n\tasync start(returnResults = false) {\n\t\tif (this.displayStats) {\n\t\t\tperf.start();\n\t\t}\n\t\tawait this.scanFileSystem([this.path]);\n\t\tconst results = await this.postProcessResults(returnResults);\n\n\t\tif (this.displayStats) {\n\t\t\tperf.stop();\n\t\t\tprintStatistics({\n\t\t\t\tduration: perf.results.duration,\n\t\t\t\tgrep: this.grep,\n\t\t\t\tpattern: this.rePattern,\n\t\t\t\ttotalDirScanned: this.totalDirScanned,\n\t\t\t\ttotalDirsFound: this.totalDirFound,\n\t\t\t\ttotalFileScanned: this.totalFileScanned,\n\t\t\t\ttotalFilesFound: this.totalFileFound,\n\t\t\t\ttype: this.type,\n\t\t\t});\n\t\t}\n\t\treturn returnResults ? results : undefined;\n\t}\n\n\tasync scanFileSystem(nodes: string[]) {\n\t\tfor (const node of nodes) {\n\t\t\tlet result: boolean | RegExpExecArray,\n\t\t\t\tfiles: string[],\n\t\t\t\tshortname: string,\n\t\t\t\tstat: fs.Stats;\n\t\t\ttry {\n\t\t\t\tstat = await lstatAsync(node);\n\t\t\t} catch {\n\t\t\t\t// ignore read permission denied errors silently...\n\t\t\t}\n\n\t\t\tconst isDirectory = stat && stat.isDirectory();\n\t\t\tconst isFile = stat && stat.isFile();\n\n\t\t\t// Add this check to respect .gitignore patterns\n\t\t\tif (await this.shouldIgnoreByGitIgnore(node, isDirectory)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (isDirectory && !this.shouldIgnoreFolder(node)) {\n\t\t\t\tthis.totalDirScanned++;\n\n\t\t\t\tresult = checkPattern(this.rePattern, node);\n\t\t\t\tif (result) {\n\t\t\t\t\tthis.totalDirFound++;\n\t\t\t\t\tthis.nodesList.push({\n\t\t\t\t\t\tcommand: this.command,\n\t\t\t\t\t\tmatch: result,\n\t\t\t\t\t\tname: node,\n\t\t\t\t\t\tstat,\n\t\t\t\t\t\ttype: STR_TYPE_DIRECTORY,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tfiles = await readdirAsync(node);\n\t\t\t\t\tawait this.scanFileSystem(\n\t\t\t\t\t\tfiles\n\t\t\t\t\t\t\t.filter((element) => this.filterHidden(element))\n\t\t\t\t\t\t\t.map(function (file) {\n\t\t\t\t\t\t\t\treturn join(node, file);\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t} catch {\n\t\t\t\t\t// nothing to declare\n\t\t\t\t}\n\t\t\t} else if (isFile) {\n\t\t\t\t// Skip files with ignored extensions\n\t\t\t\tif (this.shouldIgnoreFile(node)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tthis.totalFileScanned++;\n\t\t\t\tshortname = basename(node);\n\t\t\t\tconst patternResult = checkPattern(this.rePattern, shortname);\n\t\t\t\tif (patternResult) {\n\t\t\t\t\tthis.totalFileFound++;\n\t\t\t\t\tthis.nodesList.push({\n\t\t\t\t\t\tcommand: this.command,\n\t\t\t\t\t\tmatch: patternResult[0],\n\t\t\t\t\t\tname: node,\n\t\t\t\t\t\tstat,\n\t\t\t\t\t\ttype: STR_TYPE_FILE,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tasync readFileContent(filePath: string): Promise<string> {\n\t\ttry {\n\t\t\t// Check if it's a known binary extension\n\t\t\t/* istanbul ignore if */\n\t\t\tif (this.isBinaryFileExtension(filePath)) {\n\t\t\t\treturn \"[Binary file]\";\n\t\t\t}\n\t\t\tconst content = await readFileAsync(filePath, \"utf8\");\n\t\t\treturn content;\n\t\t} catch (error) {\n\t\t\t/* istanbul ignore next */\n\t\t\treturn `Error reading file: ${error.message}`;\n\t\t}\n\t}\n\n\tasync printFilesContent(returnResults: boolean) {\n\t\tconst fileNodes = this.nodesList.filter(\n\t\t\t(node) => node.type === STR_TYPE_FILE,\n\t\t);\n\n\t\tif (this.printMode === \"simple\") {\n\t\t\tfor (const node of fileNodes) {\n\t\t\t\tconst relativePath = relative(this.path, node.name);\n\t\t\t\tif (returnResults) {\n\t\t\t\t\tloggerInMemory.log(`---\\n./${relativePath}\\n---`);\n\t\t\t\t} else {\n\t\t\t\t\tlogger.log(`---\\n./${relativePath}\\n---`);\n\t\t\t\t}\n\t\t\t\tconst content = await this.readFileContent(node.name);\n\t\t\t\tif (returnResults) {\n\t\t\t\t\tloggerInMemory.log(content);\n\t\t\t\t} else {\n\t\t\t\t\tlogger.log(content);\n\t\t\t\t}\n\t\t\t\t// adding a new line after each file content except the last one\n\t\t\t\tif (node !== fileNodes[fileNodes.length - 1]) {\n\t\t\t\t\tif (returnResults) {\n\t\t\t\t\t\tloggerInMemory.log(\"\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlogger.log(\"\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (this.printMode === \"xml\") {\n\t\t\tif (returnResults) {\n\t\t\t\tloggerInMemory.log(\"<documents>\");\n\t\t\t} else {\n\t\t\t\tlogger.log(\"<documents>\");\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < fileNodes.length; i++) {\n\t\t\t\tconst node = fileNodes[i];\n\t\t\t\tconst relativePath = relative(this.path, node.name);\n\t\t\t\tconst content = await this.readFileContent(node.name);\n\n\t\t\t\tif (returnResults) {\n\t\t\t\t\tloggerInMemory.log(`<document index=\"${i + 1}\">`);\n\t\t\t\t\tloggerInMemory.log(`<source>./${relativePath}</source>`);\n\t\t\t\t\tloggerInMemory.log(\"<document_content>\");\n\t\t\t\t\tloggerInMemory.log(content);\n\t\t\t\t\tloggerInMemory.log(\"</document_content>\");\n\t\t\t\t\tloggerInMemory.log(\"</document>\");\n\t\t\t\t} else {\n\t\t\t\t\tlogger.log(`<document index=\"${i + 1}\">`);\n\t\t\t\t\tlogger.log(`<source>./${relativePath}</source>`);\n\t\t\t\t\tlogger.log(\"<document_content>\");\n\t\t\t\t\tlogger.log(content);\n\t\t\t\t\tlogger.log(\"</document_content>\");\n\t\t\t\t\tlogger.log(\"</document>\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (returnResults) {\n\t\t\t\tloggerInMemory.log(\"</documents>\");\n\t\t\t} else {\n\t\t\t\tlogger.log(\"</documents>\");\n\t\t\t}\n\t\t}\n\t\tconst results = returnResults ? loggerInMemory.getMemoryLogs() : undefined;\n\t\tloggerInMemory.clearMemoryLogs();\n\t\treturn results;\n\t}\n\n\tasync shouldIgnoreByGitIgnore(\n\t\tnodePath: string,\n\t\tisDirectory: boolean,\n\t): Promise<boolean> {\n\t\t/* istanbul ignore if */\n\t\tif (this.ignoreGitIgnore) {\n\t\t\treturn false;\n\t\t}\n\t\treturn this.gitIgnoreHandler.isIgnored(nodePath, isDirectory);\n\t}\n\n\tasync postProcessResults(returnResults: boolean) {\n\t\tif (this.grep) {\n\t\t\t/**\n\t\t\t * Resetting the number of files found, since we want to\n\t\t\t * show how many matched the grep, not how many matched the\n\t\t\t * pattern (in the file name).\n\t\t\t */\n\t\t\tthis.totalFileFound = 0;\n\t\t}\n\n\t\t// If printMode is enabled, handle file content printing and return\n\t\tif (this.printMode && [\"simple\", \"xml\"].includes(this.printMode)) {\n\t\t\treturn await this.printFilesContent(returnResults);\n\t\t}\n\n\t\t/* istanbul ignore if */\n\t\tif (!this.boring) {\n\t\t\tlogger.log();\n\t\t}\n\n\t\tfor (const node of this.nodesList) {\n\t\t\tif (\n\t\t\t\t(this.type === STR_TYPE_FILE && node.type === STR_TYPE_FILE) ||\n\t\t\t\t(this.type === STR_TYPE_DIRECTORY &&\n\t\t\t\t\tnode.type === STR_TYPE_DIRECTORY) ||\n\t\t\t\tthis.type === STR_TYPE_BOTH\n\t\t\t) {\n\t\t\t\tlet list: {\n\t\t\t\t\t\tgroup?: string;\n\t\t\t\t\t\tmdate?: string;\n\t\t\t\t\t\tmode?: string;\n\t\t\t\t\t\towner?: string;\n\t\t\t\t\t\tsize?: string;\n\t\t\t\t\t} = {\n\t\t\t\t\t\tgroup: \"\",\n\t\t\t\t\t\tmdate: \"\",\n\t\t\t\t\t\tmode: \"\",\n\t\t\t\t\t\towner: \"\",\n\t\t\t\t\t\tsize: \"\",\n\t\t\t\t\t},\n\t\t\t\t\tname: string,\n\t\t\t\t\tseparator: string = \"\";\n\n\t\t\t\t/* istanbul ignore if */\n\t\t\t\tif (this.displayLongListing) {\n\t\t\t\t\tlist = await formatLongListings(node.stat, node.type);\n\t\t\t\t\tseparator = \"\\t\";\n\t\t\t\t}\n\n\t\t\t\tconst color = node.type === STR_TYPE_FILE ? kleur.gray : kleur.blue;\n\t\t\t\tname = relative(this.path, node.name);\n\n\t\t\t\tif (node.match) {\n\t\t\t\t\tconst matchStr = String(node.match); // Ensure match is a string\n\t\t\t\t\tconst match = new RegExp(matchStr, \"g\");\n\t\t\t\t\tconst highlightedMatch = kleur.black().bgYellow(matchStr);\n\t\t\t\t\tname = color(name.replace(match, highlightedMatch));\n\t\t\t\t} else {\n\t\t\t\t\tname = color(name);\n\t\t\t\t}\n\n\t\t\t\tif (this.grep && node.type === STR_TYPE_FILE) {\n\t\t\t\t\tconst { totalMatchingLines, results } = await runGrepOnNode(\n\t\t\t\t\t\tnode.name,\n\t\t\t\t\t\tthis.grep,\n\t\t\t\t\t);\n\t\t\t\t\t/* istanbul ignore else */\n\t\t\t\t\tif (totalMatchingLines) {\n\t\t\t\t\t\tthis.totalFileFound++;\n\t\t\t\t\t\tconst occurrences = plur(\"occurrence\", totalMatchingLines);\n\n\t\t\t\t\t\tlogger.log(\n\t\t\t\t\t\t\t` %s${separator}%s${separator}%s${separator}%s${separator}%s`,\n\t\t\t\t\t\t\tlist.mode.trim(),\n\t\t\t\t\t\t\tlist.owner.trim(),\n\t\t\t\t\t\t\tlist.size.trim(),\n\t\t\t\t\t\t\tlist.mdate,\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t`(${kleur.white(totalMatchingLines)} ${occurrences})`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tlogger.log(`${results.join(\"\\n\")}\\n`);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t/* istanbul ignore next */\n\t\t\t\t\tif (!this.grep) {\n\t\t\t\t\t\tlogger.log(\n\t\t\t\t\t\t\t` %s${separator}%s${separator}%s${separator}%s${separator}%s`,\n\t\t\t\t\t\t\tlist.mode.trim(),\n\t\t\t\t\t\t\tlist.owner.trim(),\n\t\t\t\t\t\t\tlist.size.trim(),\n\t\t\t\t\t\t\tlist.mdate,\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (node.command) {\n\t\t\t\t\t\t\tawait runCommandOnNode(node.name, node.command);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"],"names":["basename","extname","join","relative","GitIgnoreHandler","STR_TYPE_BOTH","STR_TYPE_DIRECTORY","STR_TYPE_FILE","checkPattern","formatLongListings","printStatistics","runCommandOnNode","runGrepOnNode","promisify","Logger","Performance","fs","kleur","plur","lstatAsync","lstat","readdirAsync","readdir","readFileAsync","readFile","perf","logger","boring","process","env","NODE_ENV","loggerInMemory","inMemory","Search","command","displayHiddenFilesAndFolders","displayLongListing","displayStats","grep","nodesList","path","rePattern","totalDirFound","totalDirScanned","totalFileFound","totalFileScanned","type","ignoreExtensions","ignoreFiles","ignoreFolders","printMode","gitIgnoreHandler","ignoreGitIgnore","constructor","dot","ignoreCase","short","pattern","stats","ignoreExtension","ignoreFile","ignoreFolder","RegExp","undefined","enabled","trim","map","ext","toLowerCase","error","exit","shouldIgnoreFolder","directory","folderName","includes","shouldIgnoreFile","filePath","filename","length","extension","replace","endsWith","filterHidden","value","isBinaryFileExtension","binaryExtensions","start","returnResults","scanFileSystem","results","postProcessResults","stop","duration","totalDirsFound","totalFilesFound","nodes","node","result","files","shortname","stat","isDirectory","isFile","shouldIgnoreByGitIgnore","push","match","name","filter","element","file","patternResult","readFileContent","content","message","printFilesContent","fileNodes","relativePath","log","i","getMemoryLogs","clearMemoryLogs","nodePath","isIgnored","list","group","mdate","mode","owner","size","separator","color","gray","blue","matchStr","String","highlightedMatch","black","bgYellow","totalMatchingLines","occurrences","white"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/core.ts"],"sourcesContent":["import { basename, extname, join, relative } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { Logger } from \"@node-cli/logger\";\nimport { Performance } from \"@node-cli/perf\";\nimport fs from \"fs-extra\";\nimport kleur from \"kleur\";\nimport plur from \"plur\";\n\nimport { GitIgnoreHandler } from \"./gitIgnoreHandler.js\";\nimport { minifyCss, minifyFileContent, minifyJs } from \"./minifiers.js\";\nimport {\n\tSTR_TYPE_BOTH,\n\tSTR_TYPE_DIRECTORY,\n\tSTR_TYPE_FILE,\n\tcheckPattern,\n\tformatLongListings,\n\tgetFileExtension,\n\tisBinaryFileExtension,\n\tprintStatistics,\n\trunCommandOnNode,\n\trunGrepOnNode,\n} from \"./utilities.js\";\n\nconst lstatAsync = promisify(fs.lstat);\nconst readdirAsync = promisify(fs.readdir);\nconst readFileAsync = promisify(fs.readFile);\nconst perf = new Performance();\nconst logger = new Logger({\n\tboring: process.env.NODE_ENV === \"test\",\n});\nconst loggerInMemory = new Logger({\n\tinMemory: true,\n});\n\nexport class Search {\n\tboring?: boolean;\n\tcommand?: string;\n\tdisplayHiddenFilesAndFolders?: boolean;\n\tdisplayLongListing?: boolean;\n\tdisplayStats?: boolean;\n\tgrep?: RegExp;\n\tnodesList?: any[];\n\tpath?: string;\n\trePattern?: RegExp;\n\ttotalDirFound?: number;\n\ttotalDirScanned?: number;\n\ttotalFileFound?: number;\n\ttotalFileScanned?: number;\n\ttype?: string;\n\tignoreExtensions?: string[];\n\tignoreFiles?: string[];\n\tignoreFolders?: string[];\n\tprintMode?: string;\n\tgitIgnoreHandler: GitIgnoreHandler;\n\tignoreGitIgnore?: boolean;\n\tminifyForLLM?: boolean;\n\n\tconstructor({\n\t\tboring,\n\t\tcommand,\n\t\tdot,\n\t\tgrep,\n\t\tignoreCase,\n\t\tshort,\n\t\tpath,\n\t\tpattern,\n\t\tstats,\n\t\ttype,\n\t\tignoreExtension,\n\t\tignoreFile,\n\t\tignoreFolder,\n\t\tprintMode,\n\t\tignoreGitIgnore,\n\t\tminifyForLLM,\n\t}: {\n\t\tboring?: boolean;\n\t\tcommand?: string;\n\t\tdot?: boolean;\n\t\tgrep?: string | RegExp;\n\t\tignoreCase?: boolean;\n\t\tshort?: boolean;\n\t\tpath?: string;\n\t\tpattern?: string;\n\t\tstats?: boolean;\n\t\ttype?: string;\n\t\tignoreExtension?: string[];\n\t\tignoreFile?: string[];\n\t\tignoreFolder?: string[];\n\t\tprintMode?: string;\n\t\tignoreGitIgnore?: boolean;\n\t\tminifyForLLM?: boolean;\n\t}) {\n\t\tthis.path = path;\n\t\tthis.rePattern = pattern\n\t\t\t? new RegExp(pattern, ignoreCase ? \"i\" : \"\")\n\t\t\t: undefined;\n\t\tthis.type = type || STR_TYPE_BOTH;\n\t\tthis.boring = boring;\n\t\tkleur.enabled = !boring;\n\t\tthis.displayLongListing = !short;\n\t\tthis.displayStats = stats;\n\t\tthis.displayHiddenFilesAndFolders = dot;\n\t\tthis.nodesList = [];\n\t\tthis.totalDirScanned = 0;\n\t\tthis.totalFileScanned = 0;\n\t\tthis.totalDirFound = 0;\n\t\tthis.totalFileFound = 0;\n\t\tthis.command = command ? command.trim() : undefined;\n\t\tthis.ignoreExtensions =\n\t\t\t(ignoreExtension && ignoreExtension.map((ext) => ext.toLowerCase())) ||\n\t\t\t[];\n\t\tthis.ignoreFiles = ignoreFile || [];\n\t\tthis.ignoreFolders = ignoreFolder || [];\n\t\tthis.printMode = printMode;\n\t\tthis.ignoreGitIgnore = ignoreGitIgnore;\n\t\tthis.minifyForLLM = minifyForLLM;\n\t\tthis.gitIgnoreHandler = new GitIgnoreHandler();\n\t\ttry {\n\t\t\tthis.grep = grep ? new RegExp(grep, ignoreCase ? \"gi\" : \"g\") : undefined;\n\t\t} catch (error) {\n\t\t\tlogger.error(error);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tshouldIgnoreFolder(directory: string) {\n\t\tconst folderName = basename(directory);\n\t\t// Check for exact folder name match\n\t\tif (this.ignoreFolders && this.ignoreFolders.includes(folderName)) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tshouldIgnoreFile(filePath: string) {\n\t\t// First check if the file is in the ignoreFiles list\n\t\tconst filename = basename(filePath);\n\t\tif (this.ignoreFiles && this.ignoreFiles.includes(filename)) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Then check if the extension should be ignored\n\t\tif (!this.ignoreExtensions || this.ignoreExtensions.length === 0) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst extension = getFileExtension(filePath);\n\n\t\t// Check for exact extension match\n\t\tif (this.ignoreExtensions.includes(extension)) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Check for complex patterns like \"min.js\"\n\t\tfor (const pattern of this.ignoreExtensions) {\n\t\t\t// Skip patterns that don't contain a dot\n\t\t\tif (!pattern.includes(\".\")) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Check if the filename ends with the pattern\n\t\t\tif (filename.toLowerCase().endsWith(`.${pattern}`)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tfilterHidden(value: string[] | string) {\n\t\tif (this.displayHiddenFilesAndFolders) {\n\t\t\treturn true;\n\t\t}\n\t\treturn value[0] !== \".\";\n\t}\n\n\tasync start(returnResults = false) {\n\t\tif (this.displayStats) {\n\t\t\tperf.start();\n\t\t}\n\t\tawait this.scanFileSystem([this.path]);\n\t\tconst results = await this.postProcessResults(returnResults);\n\n\t\tif (this.displayStats) {\n\t\t\tperf.stop();\n\t\t\tprintStatistics({\n\t\t\t\tduration: perf.results.duration,\n\t\t\t\tgrep: this.grep,\n\t\t\t\tpattern: this.rePattern,\n\t\t\t\ttotalDirScanned: this.totalDirScanned,\n\t\t\t\ttotalDirsFound: this.totalDirFound,\n\t\t\t\ttotalFileScanned: this.totalFileScanned,\n\t\t\t\ttotalFilesFound: this.totalFileFound,\n\t\t\t\ttype: this.type,\n\t\t\t});\n\t\t}\n\t\treturn returnResults ? results : undefined;\n\t}\n\n\tasync scanFileSystem(nodes: string[]) {\n\t\tfor (const node of nodes) {\n\t\t\tlet result: boolean | RegExpExecArray,\n\t\t\t\tfiles: string[],\n\t\t\t\tshortname: string,\n\t\t\t\tstat: fs.Stats;\n\t\t\ttry {\n\t\t\t\tstat = await lstatAsync(node);\n\t\t\t} catch {\n\t\t\t\t// ignore read permission denied errors silently...\n\t\t\t}\n\n\t\t\tconst isDirectory = stat && stat.isDirectory();\n\t\t\tconst isFile = stat && stat.isFile();\n\n\t\t\t// Add this check to respect .gitignore patterns\n\t\t\tif (await this.shouldIgnoreByGitIgnore(node, isDirectory)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (isDirectory && !this.shouldIgnoreFolder(node)) {\n\t\t\t\tthis.totalDirScanned++;\n\n\t\t\t\tresult = checkPattern(this.rePattern, node);\n\t\t\t\tif (result) {\n\t\t\t\t\tthis.totalDirFound++;\n\t\t\t\t\tthis.nodesList.push({\n\t\t\t\t\t\tcommand: this.command,\n\t\t\t\t\t\tmatch: result,\n\t\t\t\t\t\tname: node,\n\t\t\t\t\t\tstat,\n\t\t\t\t\t\ttype: STR_TYPE_DIRECTORY,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tfiles = await readdirAsync(node);\n\t\t\t\t\tawait this.scanFileSystem(\n\t\t\t\t\t\tfiles\n\t\t\t\t\t\t\t.filter((element) => this.filterHidden(element))\n\t\t\t\t\t\t\t.map(function (file) {\n\t\t\t\t\t\t\t\treturn join(node, file);\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t} catch {\n\t\t\t\t\t// nothing to declare\n\t\t\t\t}\n\t\t\t} else if (isFile) {\n\t\t\t\t// Skip files with ignored extensions\n\t\t\t\tif (this.shouldIgnoreFile(node)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tthis.totalFileScanned++;\n\t\t\t\tshortname = basename(node);\n\t\t\t\tconst patternResult = checkPattern(this.rePattern, shortname);\n\t\t\t\tif (patternResult) {\n\t\t\t\t\tthis.totalFileFound++;\n\t\t\t\t\tthis.nodesList.push({\n\t\t\t\t\t\tcommand: this.command,\n\t\t\t\t\t\tmatch: patternResult[0],\n\t\t\t\t\t\tname: node,\n\t\t\t\t\t\tstat,\n\t\t\t\t\t\ttype: STR_TYPE_FILE,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tasync readFileContent(filePath: string): Promise<string> {\n\t\ttry {\n\t\t\t// Check if it's a known binary extension\n\t\t\t/* v8 ignore next */\n\t\t\tif (isBinaryFileExtension(filePath)) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst content = await readFileAsync(filePath, \"utf8\");\n\t\t\treturn this.minifyForLLM\n\t\t\t\t? await minifyFileContent(filePath, content)\n\t\t\t\t: content;\n\t\t} catch (_error) {\n\t\t\t/* v8 ignore next */\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync printFilesContent(returnResults: boolean) {\n\t\tconst fileNodes = this.nodesList.filter(\n\t\t\t(node) => node.type === STR_TYPE_FILE,\n\t\t);\n\n\t\tif (this.printMode === \"simple\") {\n\t\t\tfor (const node of fileNodes) {\n\t\t\t\tconst relativePath = relative(this.path, node.name);\n\t\t\t\tif (returnResults) {\n\t\t\t\t\tloggerInMemory.log(`---\\n./${relativePath}\\n---`);\n\t\t\t\t} else {\n\t\t\t\t\tlogger.log(`---\\n./${relativePath}\\n---`);\n\t\t\t\t}\n\t\t\t\tconst content = await this.readFileContent(node.name);\n\t\t\t\tif (returnResults) {\n\t\t\t\t\tloggerInMemory.log(content);\n\t\t\t\t} else {\n\t\t\t\t\tlogger.log(content);\n\t\t\t\t}\n\t\t\t\t// adding a new line after each file content except the last one\n\t\t\t\tif (node !== fileNodes[fileNodes.length - 1]) {\n\t\t\t\t\tif (returnResults) {\n\t\t\t\t\t\tloggerInMemory.log(\"\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlogger.log(\"\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (this.printMode === \"xml\") {\n\t\t\tif (returnResults) {\n\t\t\t\tloggerInMemory.log(\"<documents>\");\n\t\t\t} else {\n\t\t\t\tlogger.log(\"<documents>\");\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < fileNodes.length; i++) {\n\t\t\t\tconst node = fileNodes[i];\n\t\t\t\tconst relativePath = relative(this.path, node.name);\n\t\t\t\tconst content = await this.readFileContent(node.name);\n\n\t\t\t\tif (returnResults) {\n\t\t\t\t\tif (content) {\n\t\t\t\t\t\tloggerInMemory.log(`<document index=\"${i + 1}\">`);\n\t\t\t\t\t\tloggerInMemory.log(`<source>./${relativePath}</source>`);\n\t\t\t\t\t\tloggerInMemory.log(\"<document_content>\");\n\t\t\t\t\t\tloggerInMemory.log(content);\n\t\t\t\t\t\tloggerInMemory.log(\"</document_content>\");\n\t\t\t\t\t\tloggerInMemory.log(\"</document>\");\n\t\t\t\t\t}\n\t\t\t\t} else if (content) {\n\t\t\t\t\tlogger.log(`<document index=\"${i + 1}\">`);\n\t\t\t\t\tlogger.log(`<source>./${relativePath}</source>`);\n\t\t\t\t\tlogger.log(\"<document_content>\");\n\t\t\t\t\tlogger.log(content);\n\t\t\t\t\tlogger.log(\"</document_content>\");\n\t\t\t\t\tlogger.log(\"</document>\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (returnResults) {\n\t\t\t\tloggerInMemory.log(\"</documents>\");\n\t\t\t} else {\n\t\t\t\tlogger.log(\"</documents>\");\n\t\t\t}\n\t\t}\n\t\tconst results = returnResults ? loggerInMemory.getMemoryLogs() : undefined;\n\t\tloggerInMemory.clearMemoryLogs();\n\t\treturn results;\n\t}\n\n\tasync shouldIgnoreByGitIgnore(\n\t\tnodePath: string,\n\t\tisDirectory: boolean,\n\t): Promise<boolean> {\n\t\tif (this.ignoreGitIgnore) {\n\t\t\treturn false;\n\t\t}\n\t\treturn this.gitIgnoreHandler.isIgnored(nodePath, isDirectory);\n\t}\n\n\tasync postProcessResults(returnResults: boolean) {\n\t\tif (this.grep) {\n\t\t\t/**\n\t\t\t * Resetting the number of files found, since we want to\n\t\t\t * show how many matched the grep, not how many matched the\n\t\t\t * pattern (in the file name).\n\t\t\t */\n\t\t\tthis.totalFileFound = 0;\n\t\t}\n\n\t\t// If printMode is enabled, handle file content printing and return\n\t\tif (this.printMode && [\"simple\", \"xml\"].includes(this.printMode)) {\n\t\t\treturn await this.printFilesContent(returnResults);\n\t\t}\n\n\t\t/* v8 ignore next */\n\t\tif (!this.boring) {\n\t\t\tlogger.log();\n\t\t}\n\n\t\tfor (const node of this.nodesList) {\n\t\t\tif (\n\t\t\t\t(this.type === STR_TYPE_FILE && node.type === STR_TYPE_FILE) ||\n\t\t\t\t(this.type === STR_TYPE_DIRECTORY &&\n\t\t\t\t\tnode.type === STR_TYPE_DIRECTORY) ||\n\t\t\t\tthis.type === STR_TYPE_BOTH\n\t\t\t) {\n\t\t\t\tlet list: {\n\t\t\t\t\t\tgroup?: string;\n\t\t\t\t\t\tmdate?: string;\n\t\t\t\t\t\tmode?: string;\n\t\t\t\t\t\towner?: string;\n\t\t\t\t\t\tsize?: string;\n\t\t\t\t\t} = {\n\t\t\t\t\t\tgroup: \"\",\n\t\t\t\t\t\tmdate: \"\",\n\t\t\t\t\t\tmode: \"\",\n\t\t\t\t\t\towner: \"\",\n\t\t\t\t\t\tsize: \"\",\n\t\t\t\t\t},\n\t\t\t\t\tname: string,\n\t\t\t\t\tseparator: string = \"\";\n\n\t\t\t\t/* v8 ignore next */\n\t\t\t\tif (this.displayLongListing) {\n\t\t\t\t\tlist = await formatLongListings(node.stat, node.type);\n\t\t\t\t\tseparator = \"\\t\";\n\t\t\t\t}\n\n\t\t\t\tconst color = node.type === STR_TYPE_FILE ? kleur.gray : kleur.blue;\n\t\t\t\tname = relative(this.path, node.name);\n\n\t\t\t\tif (node.match) {\n\t\t\t\t\tconst matchStr = String(node.match); // Ensure match is a string\n\t\t\t\t\tconst match = new RegExp(matchStr, \"g\");\n\t\t\t\t\tconst highlightedMatch = kleur.black().bgYellow(matchStr);\n\t\t\t\t\tname = color(name.replace(match, highlightedMatch));\n\t\t\t\t} else {\n\t\t\t\t\tname = color(name);\n\t\t\t\t}\n\n\t\t\t\tif (this.grep && node.type === STR_TYPE_FILE) {\n\t\t\t\t\tconst { totalMatchingLines, results } = await runGrepOnNode(\n\t\t\t\t\t\tnode.name,\n\t\t\t\t\t\tthis.grep,\n\t\t\t\t\t);\n\t\t\t\t\t/* v8 ignore next */\n\t\t\t\t\tif (totalMatchingLines) {\n\t\t\t\t\t\tthis.totalFileFound++;\n\t\t\t\t\t\tconst occurrences = plur(\"occurrence\", totalMatchingLines);\n\n\t\t\t\t\t\tlogger.log(\n\t\t\t\t\t\t\t` %s${separator}%s${separator}%s${separator}%s${separator}%s`,\n\t\t\t\t\t\t\tlist.mode.trim(),\n\t\t\t\t\t\t\tlist.owner.trim(),\n\t\t\t\t\t\t\tlist.size.trim(),\n\t\t\t\t\t\t\tlist.mdate,\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t`(${kleur.white(totalMatchingLines)} ${occurrences})`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tlogger.log(`${results.join(\"\\n\")}\\n`);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t/* v8 ignore next */\n\t\t\t\t\tif (!this.grep) {\n\t\t\t\t\t\tlogger.log(\n\t\t\t\t\t\t\t` %s${separator}%s${separator}%s${separator}%s${separator}%s`,\n\t\t\t\t\t\t\tlist.mode.trim(),\n\t\t\t\t\t\t\tlist.owner.trim(),\n\t\t\t\t\t\t\tlist.size.trim(),\n\t\t\t\t\t\t\tlist.mdate,\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (node.command) {\n\t\t\t\t\t\t\tawait runCommandOnNode(node.name, node.command);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"],"names":["basename","join","relative","promisify","Logger","Performance","fs","kleur","plur","GitIgnoreHandler","minifyFileContent","STR_TYPE_BOTH","STR_TYPE_DIRECTORY","STR_TYPE_FILE","checkPattern","formatLongListings","getFileExtension","isBinaryFileExtension","printStatistics","runCommandOnNode","runGrepOnNode","lstatAsync","lstat","readdirAsync","readdir","readFileAsync","readFile","perf","logger","boring","process","env","NODE_ENV","loggerInMemory","inMemory","Search","command","displayHiddenFilesAndFolders","displayLongListing","displayStats","grep","nodesList","path","rePattern","totalDirFound","totalDirScanned","totalFileFound","totalFileScanned","type","ignoreExtensions","ignoreFiles","ignoreFolders","printMode","gitIgnoreHandler","ignoreGitIgnore","minifyForLLM","constructor","dot","ignoreCase","short","pattern","stats","ignoreExtension","ignoreFile","ignoreFolder","RegExp","undefined","enabled","trim","map","ext","toLowerCase","error","exit","shouldIgnoreFolder","directory","folderName","includes","shouldIgnoreFile","filePath","filename","length","extension","endsWith","filterHidden","value","start","returnResults","scanFileSystem","results","postProcessResults","stop","duration","totalDirsFound","totalFilesFound","nodes","node","result","files","shortname","stat","isDirectory","isFile","shouldIgnoreByGitIgnore","push","match","name","filter","element","file","patternResult","readFileContent","content","_error","printFilesContent","fileNodes","relativePath","log","i","getMemoryLogs","clearMemoryLogs","nodePath","isIgnored","list","group","mdate","mode","owner","size","separator","color","gray","blue","matchStr","String","highlightedMatch","black","bgYellow","replace","totalMatchingLines","occurrences","white"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- /* istanbul ignore file */ import { basename, dirname, join, relative } from "node:path";
1
+ /* v8 ignore start */ import { basename, dirname, join, relative } from "node:path";
2
2
  import { promisify } from "node:util";
3
3
  import fs from "fs-extra";
4
4
  import micromatch from "micromatch";
@@ -114,6 +114,6 @@ const readFileAsync = promisify(fs.readFile);
114
114
  */ clearCache() {
115
115
  this.ignoredPathsCache.clear();
116
116
  }
117
- }
117
+ } /* v8 ignore stop */
118
118
 
119
119
  //# sourceMappingURL=gitIgnoreHandler.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/gitIgnoreHandler.ts"],"sourcesContent":["/* istanbul ignore file */\nimport { basename, dirname, join, relative } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport fs from \"fs-extra\";\nimport micromatch from \"micromatch\";\n\nconst readFileAsync = promisify(fs.readFile);\n\n/**\n * Represents a pattern from a .gitignore file\n */\ninterface GitIgnorePattern {\n\t/** The actual pattern string */\n\tpattern: string;\n\t/** Whether this is a negated pattern (starts with !) */\n\tisNegated: boolean;\n\t/** Whether this pattern is specific to directories (ends with /) */\n\tisDirectory: boolean;\n}\n\n/**\n * Handles parsing and matching of .gitignore patterns\n */\nexport class GitIgnoreHandler {\n\t/** Map to store ignore patterns by directory */\n\tprivate ignorePatterns: Map<string, GitIgnorePattern[]>;\n\t/** Cache to store already processed paths */\n\tprivate ignoredPathsCache: Map<string, boolean>;\n\n\tconstructor() {\n\t\tthis.ignorePatterns = new Map<string, GitIgnorePattern[]>();\n\t\tthis.ignoredPathsCache = new Map<string, boolean>();\n\t}\n\n\t/**\n\t * Parse a .gitignore file and return the patterns\n\t * @param filePath Path to the .gitignore file\n\t * @returns Array of parsed patterns\n\t */\n\tasync parseGitIgnoreFile(filePath: string): Promise<GitIgnorePattern[]> {\n\t\ttry {\n\t\t\tconst content = await readFileAsync(filePath, \"utf8\");\n\t\t\treturn content\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.filter((line) => {\n\t\t\t\t\t// Remove comments and empty lines\n\t\t\t\t\tconst trimmedLine = line.trim();\n\t\t\t\t\treturn trimmedLine && !trimmedLine.startsWith(\"#\");\n\t\t\t\t})\n\t\t\t\t.map((pattern) => {\n\t\t\t\t\t// Handle negated patterns (those starting with !)\n\t\t\t\t\tconst isNegated = pattern.startsWith(\"!\");\n\t\t\t\t\t// Remove leading ! for negated patterns\n\t\t\t\t\tconst cleanPattern = isNegated ? pattern.slice(1) : pattern;\n\t\t\t\t\t// Handle directory-specific patterns (those ending with /)\n\t\t\t\t\tconst isDirectory = cleanPattern.endsWith(\"/\");\n\t\t\t\t\t// Remove trailing / for directory patterns\n\t\t\t\t\tconst finalPattern = isDirectory\n\t\t\t\t\t\t? cleanPattern.slice(0, -1)\n\t\t\t\t\t\t: cleanPattern;\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tpattern: finalPattern,\n\t\t\t\t\t\tisNegated,\n\t\t\t\t\t\tisDirectory,\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t} catch (_error) {\n\t\t\t// If file doesn't exist or can't be read, return empty array\n\t\t\treturn [];\n\t\t}\n\t}\n\n\t/**\n\t * Load .gitignore files from a directory and its parents\n\t * @param directory Directory to load .gitignore from\n\t */\n\tasync loadGitIgnorePatterns(directory: string): Promise<void> {\n\t\t// If we've already loaded patterns for this directory, return\n\t\tif (this.ignorePatterns.has(directory)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Load .gitignore from current directory\n\t\tconst gitIgnorePath = join(directory, \".gitignore\");\n\t\tconst patterns = await this.parseGitIgnoreFile(gitIgnorePath);\n\t\tthis.ignorePatterns.set(directory, patterns);\n\n\t\t// Load patterns from parent directories (if not at root)\n\t\tconst parentDir = dirname(directory);\n\t\tif (parentDir !== directory) {\n\t\t\tawait this.loadGitIgnorePatterns(parentDir);\n\t\t}\n\t}\n\n\t/**\n\t * Check if a path should be ignored based on .gitignore rules\n\t * @param path Path to check\n\t * @param isDirectory Whether the path is a directory\n\t * @returns True if the path should be ignored, false otherwise\n\t */\n\tasync isIgnored(\n\t\tpath: string,\n\t\tisDirectory: boolean = false,\n\t): Promise<boolean> {\n\t\t// Check cache first\n\t\tconst cacheKey = `${path}:${isDirectory}`;\n\t\tif (this.ignoredPathsCache.has(cacheKey)) {\n\t\t\treturn this.ignoredPathsCache.get(cacheKey)!;\n\t\t}\n\n\t\t// Get the directory containing the path\n\t\tconst directory = isDirectory ? path : dirname(path);\n\n\t\t// Load .gitignore patterns if not already loaded\n\t\tawait this.loadGitIgnorePatterns(directory);\n\n\t\t// Get the relative path from the containing directory\n\t\tconst filename = basename(path);\n\n\t\t// Start with not ignored\n\t\tlet ignored = false;\n\n\t\t// Check patterns from current directory up to root\n\t\tlet currentDir = directory;\n\t\twhile (true) {\n\t\t\tconst patterns = this.ignorePatterns.get(currentDir) || [];\n\n\t\t\t// Calculate relative path from this directory to the file\n\t\t\tconst relPath = relative(currentDir, path);\n\n\t\t\tfor (const {\n\t\t\t\tpattern,\n\t\t\t\tisNegated,\n\t\t\t\tisDirectory: isPatternForDir,\n\t\t\t} of patterns) {\n\t\t\t\t// Skip directory-specific patterns if checking a file\n\t\t\t\tif (isPatternForDir && !isDirectory) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Check if pattern matches\n\t\t\t\tconst matches =\n\t\t\t\t\tmicromatch.isMatch(relPath, pattern) ||\n\t\t\t\t\tmicromatch.isMatch(filename, pattern);\n\n\t\t\t\tif (matches) {\n\t\t\t\t\t// Negated patterns override previous ignores\n\t\t\t\t\tignored = !isNegated;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Move to parent directory\n\t\t\tconst parentDir = dirname(currentDir);\n\t\t\tif (parentDir === currentDir) {\n\t\t\t\tbreak; // We've reached the root\n\t\t\t}\n\t\t\tcurrentDir = parentDir;\n\t\t}\n\n\t\t// Cache the result\n\t\tthis.ignoredPathsCache.set(cacheKey, ignored);\n\t\treturn ignored;\n\t}\n\n\t/**\n\t * Clear the cache of ignored paths\n\t */\n\tclearCache(): void {\n\t\tthis.ignoredPathsCache.clear();\n\t}\n}\n"],"names":["basename","dirname","join","relative","promisify","fs","micromatch","readFileAsync","readFile","GitIgnoreHandler","ignorePatterns","ignoredPathsCache","constructor","Map","parseGitIgnoreFile","filePath","content","split","filter","line","trimmedLine","trim","startsWith","map","pattern","isNegated","cleanPattern","slice","isDirectory","endsWith","finalPattern","_error","loadGitIgnorePatterns","directory","has","gitIgnorePath","patterns","set","parentDir","isIgnored","path","cacheKey","get","filename","ignored","currentDir","relPath","isPatternForDir","matches","isMatch","clearCache","clear"],"mappings":"AAAA,wBAAwB,GACxB,SAASA,QAAQ,EAAEC,OAAO,EAAEC,IAAI,EAAEC,QAAQ,QAAQ,YAAY;AAC9D,SAASC,SAAS,QAAQ,YAAY;AACtC,OAAOC,QAAQ,WAAW;AAC1B,OAAOC,gBAAgB,aAAa;AAEpC,MAAMC,gBAAgBH,UAAUC,GAAGG,QAAQ;AAc3C;;CAEC,GACD,OAAO,MAAMC;IACZ,8CAA8C,GAC9C,AAAQC,eAAgD;IACxD,2CAA2C,GAC3C,AAAQC,kBAAwC;IAEhDC,aAAc;QACb,IAAI,CAACF,cAAc,GAAG,IAAIG;QAC1B,IAAI,CAACF,iBAAiB,GAAG,IAAIE;IAC9B;IAEA;;;;EAIC,GACD,MAAMC,mBAAmBC,QAAgB,EAA+B;QACvE,IAAI;YACH,MAAMC,UAAU,MAAMT,cAAcQ,UAAU;YAC9C,OAAOC,QACLC,KAAK,CAAC,MACNC,MAAM,CAAC,CAACC;gBACR,kCAAkC;gBAClC,MAAMC,cAAcD,KAAKE,IAAI;gBAC7B,OAAOD,eAAe,CAACA,YAAYE,UAAU,CAAC;YAC/C,GACCC,GAAG,CAAC,CAACC;gBACL,kDAAkD;gBAClD,MAAMC,YAAYD,QAAQF,UAAU,CAAC;gBACrC,wCAAwC;gBACxC,MAAMI,eAAeD,YAAYD,QAAQG,KAAK,CAAC,KAAKH;gBACpD,2DAA2D;gBAC3D,MAAMI,cAAcF,aAAaG,QAAQ,CAAC;gBAC1C,2CAA2C;gBAC3C,MAAMC,eAAeF,cAClBF,aAAaC,KAAK,CAAC,GAAG,CAAC,KACvBD;gBAEH,OAAO;oBACNF,SAASM;oBACTL;oBACAG;gBACD;YACD;QACF,EAAE,OAAOG,QAAQ;YAChB,6DAA6D;YAC7D,OAAO,EAAE;QACV;IACD;IAEA;;;EAGC,GACD,MAAMC,sBAAsBC,SAAiB,EAAiB;QAC7D,8DAA8D;QAC9D,IAAI,IAAI,CAACvB,cAAc,CAACwB,GAAG,CAACD,YAAY;YACvC;QACD;QAEA,yCAAyC;QACzC,MAAME,gBAAgBjC,KAAK+B,WAAW;QACtC,MAAMG,WAAW,MAAM,IAAI,CAACtB,kBAAkB,CAACqB;QAC/C,IAAI,CAACzB,cAAc,CAAC2B,GAAG,CAACJ,WAAWG;QAEnC,yDAAyD;QACzD,MAAME,YAAYrC,QAAQgC;QAC1B,IAAIK,cAAcL,WAAW;YAC5B,MAAM,IAAI,CAACD,qBAAqB,CAACM;QAClC;IACD;IAEA;;;;;EAKC,GACD,MAAMC,UACLC,IAAY,EACZZ,cAAuB,KAAK,EACT;QACnB,oBAAoB;QACpB,MAAMa,WAAW,GAAGD,KAAK,CAAC,EAAEZ,aAAa;QACzC,IAAI,IAAI,CAACjB,iBAAiB,CAACuB,GAAG,CAACO,WAAW;YACzC,OAAO,IAAI,CAAC9B,iBAAiB,CAAC+B,GAAG,CAACD;QACnC;QAEA,wCAAwC;QACxC,MAAMR,YAAYL,cAAcY,OAAOvC,QAAQuC;QAE/C,iDAAiD;QACjD,MAAM,IAAI,CAACR,qBAAqB,CAACC;QAEjC,sDAAsD;QACtD,MAAMU,WAAW3C,SAASwC;QAE1B,yBAAyB;QACzB,IAAII,UAAU;QAEd,mDAAmD;QACnD,IAAIC,aAAaZ;QACjB,MAAO,KAAM;YACZ,MAAMG,WAAW,IAAI,CAAC1B,cAAc,CAACgC,GAAG,CAACG,eAAe,EAAE;YAE1D,0DAA0D;YAC1D,MAAMC,UAAU3C,SAAS0C,YAAYL;YAErC,KAAK,MAAM,EACVhB,OAAO,EACPC,SAAS,EACTG,aAAamB,eAAe,EAC5B,IAAIX,SAAU;gBACd,sDAAsD;gBACtD,IAAIW,mBAAmB,CAACnB,aAAa;oBACpC;gBACD;gBAEA,2BAA2B;gBAC3B,MAAMoB,UACL1C,WAAW2C,OAAO,CAACH,SAAStB,YAC5BlB,WAAW2C,OAAO,CAACN,UAAUnB;gBAE9B,IAAIwB,SAAS;oBACZ,6CAA6C;oBAC7CJ,UAAU,CAACnB;gBACZ;YACD;YAEA,2BAA2B;YAC3B,MAAMa,YAAYrC,QAAQ4C;YAC1B,IAAIP,cAAcO,YAAY;gBAC7B,OAAO,yBAAyB;YACjC;YACAA,aAAaP;QACd;QAEA,mBAAmB;QACnB,IAAI,CAAC3B,iBAAiB,CAAC0B,GAAG,CAACI,UAAUG;QACrC,OAAOA;IACR;IAEA;;EAEC,GACDM,aAAmB;QAClB,IAAI,CAACvC,iBAAiB,CAACwC,KAAK;IAC7B;AACD"}
1
+ {"version":3,"sources":["../src/gitIgnoreHandler.ts"],"sourcesContent":["/* v8 ignore start */\nimport { basename, dirname, join, relative } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport fs from \"fs-extra\";\nimport micromatch from \"micromatch\";\n\nconst readFileAsync = promisify(fs.readFile);\n\n/**\n * Represents a pattern from a .gitignore file\n */\ninterface GitIgnorePattern {\n\t/** The actual pattern string */\n\tpattern: string;\n\t/** Whether this is a negated pattern (starts with !) */\n\tisNegated: boolean;\n\t/** Whether this pattern is specific to directories (ends with /) */\n\tisDirectory: boolean;\n}\n\n/**\n * Handles parsing and matching of .gitignore patterns\n */\nexport class GitIgnoreHandler {\n\t/** Map to store ignore patterns by directory */\n\tprivate ignorePatterns: Map<string, GitIgnorePattern[]>;\n\t/** Cache to store already processed paths */\n\tprivate ignoredPathsCache: Map<string, boolean>;\n\n\tconstructor() {\n\t\tthis.ignorePatterns = new Map<string, GitIgnorePattern[]>();\n\t\tthis.ignoredPathsCache = new Map<string, boolean>();\n\t}\n\n\t/**\n\t * Parse a .gitignore file and return the patterns\n\t * @param filePath Path to the .gitignore file\n\t * @returns Array of parsed patterns\n\t */\n\tasync parseGitIgnoreFile(filePath: string): Promise<GitIgnorePattern[]> {\n\t\ttry {\n\t\t\tconst content = await readFileAsync(filePath, \"utf8\");\n\t\t\treturn content\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.filter((line) => {\n\t\t\t\t\t// Remove comments and empty lines\n\t\t\t\t\tconst trimmedLine = line.trim();\n\t\t\t\t\treturn trimmedLine && !trimmedLine.startsWith(\"#\");\n\t\t\t\t})\n\t\t\t\t.map((pattern) => {\n\t\t\t\t\t// Handle negated patterns (those starting with !)\n\t\t\t\t\tconst isNegated = pattern.startsWith(\"!\");\n\t\t\t\t\t// Remove leading ! for negated patterns\n\t\t\t\t\tconst cleanPattern = isNegated ? pattern.slice(1) : pattern;\n\t\t\t\t\t// Handle directory-specific patterns (those ending with /)\n\t\t\t\t\tconst isDirectory = cleanPattern.endsWith(\"/\");\n\t\t\t\t\t// Remove trailing / for directory patterns\n\t\t\t\t\tconst finalPattern = isDirectory\n\t\t\t\t\t\t? cleanPattern.slice(0, -1)\n\t\t\t\t\t\t: cleanPattern;\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tpattern: finalPattern,\n\t\t\t\t\t\tisNegated,\n\t\t\t\t\t\tisDirectory,\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t} catch (_error) {\n\t\t\t// If file doesn't exist or can't be read, return empty array\n\t\t\treturn [];\n\t\t}\n\t}\n\n\t/**\n\t * Load .gitignore files from a directory and its parents\n\t * @param directory Directory to load .gitignore from\n\t */\n\tasync loadGitIgnorePatterns(directory: string): Promise<void> {\n\t\t// If we've already loaded patterns for this directory, return\n\t\tif (this.ignorePatterns.has(directory)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Load .gitignore from current directory\n\t\tconst gitIgnorePath = join(directory, \".gitignore\");\n\t\tconst patterns = await this.parseGitIgnoreFile(gitIgnorePath);\n\t\tthis.ignorePatterns.set(directory, patterns);\n\n\t\t// Load patterns from parent directories (if not at root)\n\t\tconst parentDir = dirname(directory);\n\t\tif (parentDir !== directory) {\n\t\t\tawait this.loadGitIgnorePatterns(parentDir);\n\t\t}\n\t}\n\n\t/**\n\t * Check if a path should be ignored based on .gitignore rules\n\t * @param path Path to check\n\t * @param isDirectory Whether the path is a directory\n\t * @returns True if the path should be ignored, false otherwise\n\t */\n\tasync isIgnored(\n\t\tpath: string,\n\t\tisDirectory: boolean = false,\n\t): Promise<boolean> {\n\t\t// Check cache first\n\t\tconst cacheKey = `${path}:${isDirectory}`;\n\t\tif (this.ignoredPathsCache.has(cacheKey)) {\n\t\t\treturn this.ignoredPathsCache.get(cacheKey)!;\n\t\t}\n\n\t\t// Get the directory containing the path\n\t\tconst directory = isDirectory ? path : dirname(path);\n\n\t\t// Load .gitignore patterns if not already loaded\n\t\tawait this.loadGitIgnorePatterns(directory);\n\n\t\t// Get the relative path from the containing directory\n\t\tconst filename = basename(path);\n\n\t\t// Start with not ignored\n\t\tlet ignored = false;\n\n\t\t// Check patterns from current directory up to root\n\t\tlet currentDir = directory;\n\t\twhile (true) {\n\t\t\tconst patterns = this.ignorePatterns.get(currentDir) || [];\n\n\t\t\t// Calculate relative path from this directory to the file\n\t\t\tconst relPath = relative(currentDir, path);\n\n\t\t\tfor (const {\n\t\t\t\tpattern,\n\t\t\t\tisNegated,\n\t\t\t\tisDirectory: isPatternForDir,\n\t\t\t} of patterns) {\n\t\t\t\t// Skip directory-specific patterns if checking a file\n\t\t\t\tif (isPatternForDir && !isDirectory) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Check if pattern matches\n\t\t\t\tconst matches =\n\t\t\t\t\tmicromatch.isMatch(relPath, pattern) ||\n\t\t\t\t\tmicromatch.isMatch(filename, pattern);\n\n\t\t\t\tif (matches) {\n\t\t\t\t\t// Negated patterns override previous ignores\n\t\t\t\t\tignored = !isNegated;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Move to parent directory\n\t\t\tconst parentDir = dirname(currentDir);\n\t\t\tif (parentDir === currentDir) {\n\t\t\t\tbreak; // We've reached the root\n\t\t\t}\n\t\t\tcurrentDir = parentDir;\n\t\t}\n\n\t\t// Cache the result\n\t\tthis.ignoredPathsCache.set(cacheKey, ignored);\n\t\treturn ignored;\n\t}\n\n\t/**\n\t * Clear the cache of ignored paths\n\t */\n\tclearCache(): void {\n\t\tthis.ignoredPathsCache.clear();\n\t}\n}\n/* v8 ignore stop */\n"],"names":["basename","dirname","join","relative","promisify","fs","micromatch","readFileAsync","readFile","GitIgnoreHandler","ignorePatterns","ignoredPathsCache","constructor","Map","parseGitIgnoreFile","filePath","content","split","filter","line","trimmedLine","trim","startsWith","map","pattern","isNegated","cleanPattern","slice","isDirectory","endsWith","finalPattern","_error","loadGitIgnorePatterns","directory","has","gitIgnorePath","patterns","set","parentDir","isIgnored","path","cacheKey","get","filename","ignored","currentDir","relPath","isPatternForDir","matches","isMatch","clearCache","clear"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@
5
5
  export * from "./core";
6
6
  export * from "./defaults";
7
7
  export * from "./gitIgnoreHandler";
8
+ export * from "./minifiers";
8
9
  export * from "./parse";
9
10
  export * from "./search";
10
11
  export * from "./utilities";
@@ -0,0 +1,4 @@
1
+ export declare function minifyImports(content: string): string;
2
+ export declare function minifyJs(content: string): string;
3
+ export declare function minifyCss(content: string): string;
4
+ export declare function minifyFileContent(filePath: string, content: string): Promise<string>;
@@ -0,0 +1,110 @@
1
+ import { v4 as uuidv4 } from "uuid";
2
+ import { getFileExtension } from "./utilities.js";
3
+ export function minifyImports(content) {
4
+ return content.replace(/(import\s*\{)([^}]*?)(\}\s*from)/g, (_match, _importStart, importItems, _importEnd)=>{
5
+ // Process the items being imported
6
+ const cleanedItems = importItems.split(",").map((item)=>{
7
+ // Handle 'type' keyword specifically
8
+ return item.trim().replace(/(\btype\b)\s+/, "$1");
9
+ }).join(",");
10
+ return `import {${cleanedItems}} from`;
11
+ });
12
+ }
13
+ export function minifyJs(content) {
14
+ // Store template literals and regular expressions to protect them from minification
15
+ const tokenPrefix = `__PROTECTED_${uuidv4()}_`;
16
+ const protectedSegments = [];
17
+ // Function to create a unique token for each protected segment
18
+ const createToken = (index)=>`${tokenPrefix}${index}__`;
19
+ // Function to protect a segment of code with a custom handler
20
+ const protect = (pattern, handler)=>{
21
+ content = content.replace(pattern, (match)=>{
22
+ // If a handler is provided, use it to determine if we should protect this match
23
+ if (handler && !handler(match)) {
24
+ return ""; // Return empty string for JSDoc comments we don't want to keep
25
+ }
26
+ const index = protectedSegments.length;
27
+ protectedSegments.push(match);
28
+ return createToken(index);
29
+ });
30
+ };
31
+ // Protect template literals
32
+ protect(/`[\s\S]*?`/g);
33
+ // Protect regular expressions
34
+ // This regex pattern matches JavaScript regular expressions while avoiding division operators
35
+ protect(/(?<![a-zA-Z0-9_$])\/(?![*+?\/])(?:[^\r\n\[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*\])+\/[gimyus]*/g);
36
+ // Protect important JSDoc comments
37
+ protect(/\/\*\*[\s\S]*?\*\//g, (match)=>{
38
+ return match.includes("@param") || match.includes("@returns") || match.includes("@description");
39
+ });
40
+ // Remove comments (both single-line and multi-line)
41
+ content = content.replace(/\/\/.*$/gm, ""); // Remove single-line comments
42
+ content = content.replace(/\/\*[\s\S]*?\*\//g, ""); // Remove multi-line comments
43
+ // Compact import statements
44
+ content = minifyImports(content);
45
+ // Remove extra whitespace
46
+ content = content.replace(/^\s+/gm, ""); // Remove leading whitespace
47
+ content = content.replace(/\s+$/gm, ""); // Remove trailing whitespace
48
+ content = content.replace(/\s{2,}/g, " "); // Replace multiple spaces with a single space
49
+ // Compact newlines ( we protected template literals before)
50
+ content = content.replace(/\n+/g, " ");
51
+ // Replace semicolon + space with just semicolon
52
+ content = content.replace(/;\s+/g, ";");
53
+ // Replace colon + space with just colon
54
+ content = content.replace(/,\s+/g, ",");
55
+ // Remove spaces around operators (we protected regex operators before)
56
+ content = content.replace(/\s+([+\-*/%=&|<>!?:;,])\s+/g, "$1");
57
+ // Handle spaces around parentheses and brackets
58
+ content = content.replace(/\(\s+/g, "(");
59
+ content = content.replace(/\s+\)/g, ")");
60
+ content = content.replace(/\[\s+/g, "[");
61
+ content = content.replace(/\s+\]/g, "]");
62
+ // Handle spaces in all curly braces (for object literals, destructuring, etc.)
63
+ content = content.replace(/\{\s+/g, "{");
64
+ content = content.replace(/\s+\}/g, "}");
65
+ // Restore protected segments
66
+ // We need to handle nested tokens, so we'll iterate until all tokens are replaced
67
+ let previousContent = "";
68
+ while(previousContent !== content){
69
+ previousContent = content;
70
+ // Sort indices in descending order to handle nested tokens correctly
71
+ const indices = Array.from({
72
+ length: protectedSegments.length
73
+ }, (_, i)=>i).sort((a, b)=>b - a);
74
+ for (const index of indices){
75
+ const token = createToken(index);
76
+ const segment = protectedSegments[index];
77
+ // Use global replacement to catch all instances
78
+ const tokenRegex = new RegExp(token.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g");
79
+ content = content.replace(tokenRegex, ()=>segment);
80
+ }
81
+ }
82
+ return content;
83
+ }
84
+ export function minifyCss(content) {
85
+ // Remove CSS comments
86
+ content = content.replace(/\/\*[\s\S]*?\*\//g, "");
87
+ // Remove extra whitespace
88
+ content = content.replace(/\s+/g, " ");
89
+ content = content.replace(/\s*{\s*/g, "{");
90
+ content = content.replace(/\s*}\s*/g, "}");
91
+ content = content.replace(/\s*:\s*/g, ":");
92
+ content = content.replace(/\s*;\s*/g, ";");
93
+ content = content.replace(/\s*,\s*/g, ",");
94
+ return content;
95
+ }
96
+ export async function minifyFileContent(filePath, content) {
97
+ if (!content || content.length < 100) {
98
+ return content;
99
+ }
100
+ const fileExtension = getFileExtension(filePath);
101
+ if (content && content.length > 0 && (fileExtension.endsWith("js") || fileExtension.endsWith("ts") || /* v8 ignore next */ fileExtension.endsWith("jsx") || /* v8 ignore next */ fileExtension.endsWith("tsx"))) {
102
+ return minifyJs(content);
103
+ }
104
+ /* v8 ignore next */ if (content && content.length > 0 && fileExtension.endsWith("css")) {
105
+ return minifyCss(content);
106
+ }
107
+ return content;
108
+ }
109
+
110
+ //# sourceMappingURL=minifiers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/minifiers.ts"],"sourcesContent":["import { v4 as uuidv4 } from \"uuid\";\nimport { getFileExtension } from \"./utilities.js\";\n\nexport function minifyImports(content: string): string {\n\treturn content.replace(\n\t\t/(import\\s*\\{)([^}]*?)(\\}\\s*from)/g,\n\t\t(_match, _importStart, importItems, _importEnd) => {\n\t\t\t// Process the items being imported\n\t\t\tconst cleanedItems = importItems\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((item) => {\n\t\t\t\t\t// Handle 'type' keyword specifically\n\t\t\t\t\treturn item.trim().replace(/(\\btype\\b)\\s+/, \"$1\");\n\t\t\t\t})\n\t\t\t\t.join(\",\");\n\n\t\t\treturn `import {${cleanedItems}} from`;\n\t\t},\n\t);\n}\n\nexport function minifyJs(content: string): string {\n\t// Store template literals and regular expressions to protect them from minification\n\tconst tokenPrefix = `__PROTECTED_${uuidv4()}_`;\n\tconst protectedSegments: string[] = [];\n\n\t// Function to create a unique token for each protected segment\n\tconst createToken = (index: number) => `${tokenPrefix}${index}__`;\n\n\t// Function to protect a segment of code with a custom handler\n\tconst protect = (pattern: RegExp, handler?: (match: string) => boolean) => {\n\t\tcontent = content.replace(pattern, (match) => {\n\t\t\t// If a handler is provided, use it to determine if we should protect this match\n\t\t\tif (handler && !handler(match)) {\n\t\t\t\treturn \"\"; // Return empty string for JSDoc comments we don't want to keep\n\t\t\t}\n\t\t\tconst index = protectedSegments.length;\n\t\t\tprotectedSegments.push(match);\n\t\t\treturn createToken(index);\n\t\t});\n\t};\n\n\t// Protect template literals\n\tprotect(/`[\\s\\S]*?`/g);\n\n\t// Protect regular expressions\n\t// This regex pattern matches JavaScript regular expressions while avoiding division operators\n\tprotect(\n\t\t/(?<![a-zA-Z0-9_$])\\/(?![*+?\\/])(?:[^\\r\\n\\[/\\\\]|\\\\.|\\[(?:[^\\r\\n\\]\\\\]|\\\\.)*\\])+\\/[gimyus]*/g,\n\t);\n\n\t// Protect important JSDoc comments\n\tprotect(/\\/\\*\\*[\\s\\S]*?\\*\\//g, (match) => {\n\t\treturn (\n\t\t\tmatch.includes(\"@param\") ||\n\t\t\tmatch.includes(\"@returns\") ||\n\t\t\tmatch.includes(\"@description\")\n\t\t);\n\t});\n\n\t// Remove comments (both single-line and multi-line)\n\tcontent = content.replace(/\\/\\/.*$/gm, \"\"); // Remove single-line comments\n\tcontent = content.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\"); // Remove multi-line comments\n\n\t// Compact import statements\n\tcontent = minifyImports(content);\n\n\t// Remove extra whitespace\n\tcontent = content.replace(/^\\s+/gm, \"\"); // Remove leading whitespace\n\tcontent = content.replace(/\\s+$/gm, \"\"); // Remove trailing whitespace\n\tcontent = content.replace(/\\s{2,}/g, \" \"); // Replace multiple spaces with a single space\n\n\t// Compact newlines ( we protected template literals before)\n\tcontent = content.replace(/\\n+/g, \" \");\n\n\t// Replace semicolon + space with just semicolon\n\tcontent = content.replace(/;\\s+/g, \";\");\n\n\t// Replace colon + space with just colon\n\tcontent = content.replace(/,\\s+/g, \",\");\n\n\t// Remove spaces around operators (we protected regex operators before)\n\tcontent = content.replace(/\\s+([+\\-*/%=&|<>!?:;,])\\s+/g, \"$1\");\n\n\t// Handle spaces around parentheses and brackets\n\tcontent = content.replace(/\\(\\s+/g, \"(\");\n\tcontent = content.replace(/\\s+\\)/g, \")\");\n\tcontent = content.replace(/\\[\\s+/g, \"[\");\n\tcontent = content.replace(/\\s+\\]/g, \"]\");\n\n\t// Handle spaces in all curly braces (for object literals, destructuring, etc.)\n\tcontent = content.replace(/\\{\\s+/g, \"{\");\n\tcontent = content.replace(/\\s+\\}/g, \"}\");\n\n\t// Restore protected segments\n\t// We need to handle nested tokens, so we'll iterate until all tokens are replaced\n\tlet previousContent = \"\";\n\twhile (previousContent !== content) {\n\t\tpreviousContent = content;\n\t\t// Sort indices in descending order to handle nested tokens correctly\n\t\tconst indices = Array.from(\n\t\t\t{ length: protectedSegments.length },\n\t\t\t(_, i) => i,\n\t\t).sort((a, b) => b - a);\n\t\tfor (const index of indices) {\n\t\t\tconst token = createToken(index);\n\t\t\tconst segment = protectedSegments[index];\n\t\t\t// Use global replacement to catch all instances\n\t\t\tconst tokenRegex = new RegExp(\n\t\t\t\ttoken.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"),\n\t\t\t\t\"g\",\n\t\t\t);\n\t\t\tcontent = content.replace(tokenRegex, () => segment);\n\t\t}\n\t}\n\treturn content;\n}\n\nexport function minifyCss(content: string): string {\n\t// Remove CSS comments\n\tcontent = content.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\");\n\n\t// Remove extra whitespace\n\tcontent = content.replace(/\\s+/g, \" \");\n\tcontent = content.replace(/\\s*{\\s*/g, \"{\");\n\tcontent = content.replace(/\\s*}\\s*/g, \"}\");\n\tcontent = content.replace(/\\s*:\\s*/g, \":\");\n\tcontent = content.replace(/\\s*;\\s*/g, \";\");\n\tcontent = content.replace(/\\s*,\\s*/g, \",\");\n\n\treturn content;\n}\n\nexport async function minifyFileContent(\n\tfilePath: string,\n\tcontent: string,\n): Promise<string> {\n\tif (!content || content.length < 100) {\n\t\treturn content;\n\t}\n\n\tconst fileExtension = getFileExtension(filePath);\n\n\tif (\n\t\tcontent &&\n\t\tcontent.length > 0 &&\n\t\t(fileExtension.endsWith(\"js\") ||\n\t\t\tfileExtension.endsWith(\"ts\") ||\n\t\t\t/* v8 ignore next */\n\t\t\tfileExtension.endsWith(\"jsx\") ||\n\t\t\t/* v8 ignore next */\n\t\t\tfileExtension.endsWith(\"tsx\"))\n\t) {\n\t\treturn minifyJs(content);\n\t}\n\n\t/* v8 ignore next */\n\tif (content && content.length > 0 && fileExtension.endsWith(\"css\")) {\n\t\treturn minifyCss(content);\n\t}\n\n\treturn content;\n}\n"],"names":["v4","uuidv4","getFileExtension","minifyImports","content","replace","_match","_importStart","importItems","_importEnd","cleanedItems","split","map","item","trim","join","minifyJs","tokenPrefix","protectedSegments","createToken","index","protect","pattern","handler","match","length","push","includes","previousContent","indices","Array","from","_","i","sort","a","b","token","segment","tokenRegex","RegExp","minifyCss","minifyFileContent","filePath","fileExtension","endsWith"],"mappings":"AAAA,SAASA,MAAMC,MAAM,QAAQ,OAAO;AACpC,SAASC,gBAAgB,QAAQ,iBAAiB;AAElD,OAAO,SAASC,cAAcC,OAAe;IAC5C,OAAOA,QAAQC,OAAO,CACrB,qCACA,CAACC,QAAQC,cAAcC,aAAaC;QACnC,mCAAmC;QACnC,MAAMC,eAAeF,YACnBG,KAAK,CAAC,KACNC,GAAG,CAAC,CAACC;YACL,qCAAqC;YACrC,OAAOA,KAAKC,IAAI,GAAGT,OAAO,CAAC,iBAAiB;QAC7C,GACCU,IAAI,CAAC;QAEP,OAAO,CAAC,QAAQ,EAAEL,aAAa,MAAM,CAAC;IACvC;AAEF;AAEA,OAAO,SAASM,SAASZ,OAAe;IACvC,oFAAoF;IACpF,MAAMa,cAAc,CAAC,YAAY,EAAEhB,SAAS,CAAC,CAAC;IAC9C,MAAMiB,oBAA8B,EAAE;IAEtC,+DAA+D;IAC/D,MAAMC,cAAc,CAACC,QAAkB,GAAGH,cAAcG,MAAM,EAAE,CAAC;IAEjE,8DAA8D;IAC9D,MAAMC,UAAU,CAACC,SAAiBC;QACjCnB,UAAUA,QAAQC,OAAO,CAACiB,SAAS,CAACE;YACnC,gFAAgF;YAChF,IAAID,WAAW,CAACA,QAAQC,QAAQ;gBAC/B,OAAO,IAAI,+DAA+D;YAC3E;YACA,MAAMJ,QAAQF,kBAAkBO,MAAM;YACtCP,kBAAkBQ,IAAI,CAACF;YACvB,OAAOL,YAAYC;QACpB;IACD;IAEA,4BAA4B;IAC5BC,QAAQ;IAER,8BAA8B;IAC9B,8FAA8F;IAC9FA,QACC;IAGD,mCAAmC;IACnCA,QAAQ,uBAAuB,CAACG;QAC/B,OACCA,MAAMG,QAAQ,CAAC,aACfH,MAAMG,QAAQ,CAAC,eACfH,MAAMG,QAAQ,CAAC;IAEjB;IAEA,oDAAoD;IACpDvB,UAAUA,QAAQC,OAAO,CAAC,aAAa,KAAK,8BAA8B;IAC1ED,UAAUA,QAAQC,OAAO,CAAC,qBAAqB,KAAK,6BAA6B;IAEjF,4BAA4B;IAC5BD,UAAUD,cAAcC;IAExB,0BAA0B;IAC1BA,UAAUA,QAAQC,OAAO,CAAC,UAAU,KAAK,4BAA4B;IACrED,UAAUA,QAAQC,OAAO,CAAC,UAAU,KAAK,6BAA6B;IACtED,UAAUA,QAAQC,OAAO,CAAC,WAAW,MAAM,8CAA8C;IAEzF,4DAA4D;IAC5DD,UAAUA,QAAQC,OAAO,CAAC,QAAQ;IAElC,gDAAgD;IAChDD,UAAUA,QAAQC,OAAO,CAAC,SAAS;IAEnC,wCAAwC;IACxCD,UAAUA,QAAQC,OAAO,CAAC,SAAS;IAEnC,uEAAuE;IACvED,UAAUA,QAAQC,OAAO,CAAC,+BAA+B;IAEzD,gDAAgD;IAChDD,UAAUA,QAAQC,OAAO,CAAC,UAAU;IACpCD,UAAUA,QAAQC,OAAO,CAAC,UAAU;IACpCD,UAAUA,QAAQC,OAAO,CAAC,UAAU;IACpCD,UAAUA,QAAQC,OAAO,CAAC,UAAU;IAEpC,+EAA+E;IAC/ED,UAAUA,QAAQC,OAAO,CAAC,UAAU;IACpCD,UAAUA,QAAQC,OAAO,CAAC,UAAU;IAEpC,6BAA6B;IAC7B,kFAAkF;IAClF,IAAIuB,kBAAkB;IACtB,MAAOA,oBAAoBxB,QAAS;QACnCwB,kBAAkBxB;QAClB,qEAAqE;QACrE,MAAMyB,UAAUC,MAAMC,IAAI,CACzB;YAAEN,QAAQP,kBAAkBO,MAAM;QAAC,GACnC,CAACO,GAAGC,IAAMA,GACTC,IAAI,CAAC,CAACC,GAAGC,IAAMA,IAAID;QACrB,KAAK,MAAMf,SAASS,QAAS;YAC5B,MAAMQ,QAAQlB,YAAYC;YAC1B,MAAMkB,UAAUpB,iBAAiB,CAACE,MAAM;YACxC,gDAAgD;YAChD,MAAMmB,aAAa,IAAIC,OACtBH,MAAMhC,OAAO,CAAC,uBAAuB,SACrC;YAEDD,UAAUA,QAAQC,OAAO,CAACkC,YAAY,IAAMD;QAC7C;IACD;IACA,OAAOlC;AACR;AAEA,OAAO,SAASqC,UAAUrC,OAAe;IACxC,sBAAsB;IACtBA,UAAUA,QAAQC,OAAO,CAAC,qBAAqB;IAE/C,0BAA0B;IAC1BD,UAAUA,QAAQC,OAAO,CAAC,QAAQ;IAClCD,UAAUA,QAAQC,OAAO,CAAC,YAAY;IACtCD,UAAUA,QAAQC,OAAO,CAAC,YAAY;IACtCD,UAAUA,QAAQC,OAAO,CAAC,YAAY;IACtCD,UAAUA,QAAQC,OAAO,CAAC,YAAY;IACtCD,UAAUA,QAAQC,OAAO,CAAC,YAAY;IAEtC,OAAOD;AACR;AAEA,OAAO,eAAesC,kBACrBC,QAAgB,EAChBvC,OAAe;IAEf,IAAI,CAACA,WAAWA,QAAQqB,MAAM,GAAG,KAAK;QACrC,OAAOrB;IACR;IAEA,MAAMwC,gBAAgB1C,iBAAiByC;IAEvC,IACCvC,WACAA,QAAQqB,MAAM,GAAG,KAChBmB,CAAAA,cAAcC,QAAQ,CAAC,SACvBD,cAAcC,QAAQ,CAAC,SACvB,kBAAkB,GAClBD,cAAcC,QAAQ,CAAC,UACvB,kBAAkB,GAClBD,cAAcC,QAAQ,CAAC,MAAK,GAC5B;QACD,OAAO7B,SAASZ;IACjB;IAEA,kBAAkB,GAClB,IAAIA,WAAWA,QAAQqB,MAAM,GAAG,KAAKmB,cAAcC,QAAQ,CAAC,QAAQ;QACnE,OAAOJ,UAAUrC;IAClB;IAEA,OAAOA;AACR"}
package/dist/parse.js CHANGED
@@ -1,6 +1,6 @@
1
- import { defaultFlags, defaultParameters } from "./defaults.js";
1
+ /* v8 ignore start */ import { defaultFlags, defaultParameters } from "./defaults.js";
2
2
  import { parser } from "@node-cli/parser";
3
- /* istanbul ignore next */ export const config = parser({
3
+ /* v8 ignore start */ export const config = parser({
4
4
  meta: import.meta,
5
5
  examples: [
6
6
  {
@@ -114,6 +114,6 @@ import { parser } from "@node-cli/parser";
114
114
  usage: "search [options] [path]",
115
115
  defaultFlags,
116
116
  defaultParameters
117
- });
117
+ }); /* v8 ignore stop */
118
118
 
119
119
  //# sourceMappingURL=parse.js.map
package/dist/parse.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/parse.ts"],"sourcesContent":["import { defaultFlags, defaultParameters } from \"./defaults.js\";\n\nimport { parser } from \"@node-cli/parser\";\n\nexport type Flags = {\n\tboring?: boolean;\n\tdot?: boolean;\n\tignoreCase?: boolean;\n\tshort?: boolean;\n\tstats?: boolean;\n\tgrep?: string;\n\ttype?: string;\n\tignore?: string[];\n\tprintMode?: string;\n};\n\nexport type Parameters = {\n\tpath?: string;\n};\n\nexport type Configuration = {\n\tflags?: Flags;\n\tparameters?: Parameters;\n};\n\n/* istanbul ignore next */\nexport const config: Configuration = parser({\n\tmeta: import.meta,\n\texamples: [\n\t\t{\n\t\t\tcommand: 'search --type f --pattern \".jsx$\" src/',\n\t\t\tcomment:\n\t\t\t\t'## Find all files with the extension \".jsx\" in the \"src\" folder',\n\t\t},\n\t\t{\n\t\t\tcommand: 'search --type f --pattern \".sh$\" --command \"chmod +x\" bin/',\n\t\t\tcomment: `## Change the permissions to executable for all the files with\\n ## the extension \".sh\" found under the \"bin\" folder`,\n\t\t},\n\t\t{\n\t\t\tcommand: 'search --type f --pattern \".md$\" --grep \"Table of Content\"',\n\t\t\tcomment: `## Search in all the markdown files under the \"src\" folder for\\n ## the keywords \"Table of Content\"`,\n\t\t},\n\t],\n\tflags: {\n\t\tboring: {\n\t\t\tshortFlag: \"b\",\n\t\t\tdefault: defaultFlags.boring,\n\t\t\tdescription: \"Do not use color output\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\tcommand: {\n\t\t\tshortFlag: \"c\",\n\t\t\tdescription: \"Command to execute over each node (ex: chmod +x)\",\n\t\t\ttype: \"string\",\n\t\t},\n\t\tdot: {\n\t\t\tdefault: defaultFlags.dot,\n\t\t\tdescription: \"Show hidden files and directories\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\tgrep: {\n\t\t\tshortFlag: \"g\",\n\t\t\tdescription: \"A RegExp to match the content of the files found\",\n\t\t\ttype: \"string\",\n\t\t},\n\t\thelp: {\n\t\t\tshortFlag: \"h\",\n\t\t\tdescription: \"Display help instructions\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\tignoreCase: {\n\t\t\tshortFlag: \"i\",\n\t\t\tdefault: defaultFlags.ignoreCase,\n\t\t\tdescription: \"Ignore case when searching\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\tpattern: {\n\t\t\tshortFlag: \"p\",\n\t\t\tdescription: \"A regular expression to match file or folder names\",\n\t\t\ttype: \"string\",\n\t\t},\n\t\tshort: {\n\t\t\tdefault: defaultFlags.short,\n\t\t\tdescription: \"Short listing format (equivalent to ls)\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\tstats: {\n\t\t\tshortFlag: \"s\",\n\t\t\tdefault: defaultFlags.stats,\n\t\t\tdescription: \"Display some statistics\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\ttype: {\n\t\t\tshortFlag: \"t\",\n\t\t\tdefault: \"both\",\n\t\t\tdescription: \"Search for files (f) or directories (d)\",\n\t\t\ttype: \"string\",\n\t\t},\n\t\tversion: {\n\t\t\tshortFlag: \"v\",\n\t\t\tdescription: \"Output the current version\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\tignoreExtension: {\n\t\t\tshortFlag: \"I\",\n\t\t\tdescription: \"Ignore files extension, can be used multiple times\",\n\t\t\ttype: \"string\",\n\t\t\tisMultiple: true,\n\t\t},\n\t\tignoreFile: {\n\t\t\tshortFlag: \"F\",\n\t\t\tdescription: \"Ignore files name, can be used multiple times\",\n\t\t\ttype: \"string\",\n\t\t\tisMultiple: true,\n\t\t},\n\t\tignoreFolder: {\n\t\t\tshortFlag: \"D\",\n\t\t\tdescription: \"Ignore folders name, can be used multiple times\",\n\t\t\ttype: \"string\",\n\t\t\tisMultiple: true,\n\t\t},\n\t\tprintMode: {\n\t\t\tshortFlag: \"P\",\n\t\t\tdescription: \"Print mode (simple or xml)\",\n\t\t\ttype: \"string\",\n\t\t},\n\t\tignoreGitIgnore: {\n\t\t\tdescription: \"Ignore .gitignore files\",\n\t\t\tdefault: defaultFlags.ignoreGitIgnore,\n\t\t\ttype: \"boolean\",\n\t\t},\n\t},\n\tparameters: {\n\t\tpath: {\n\t\t\tdefault: \"current folder\",\n\t\t\tdescription: \"the path where to start the search\",\n\t\t},\n\t},\n\tusage: \"search [options] [path]\",\n\tdefaultFlags,\n\tdefaultParameters,\n});\n"],"names":["defaultFlags","defaultParameters","parser","config","meta","examples","command","comment","flags","boring","shortFlag","default","description","type","dot","grep","help","ignoreCase","pattern","short","stats","version","ignoreExtension","isMultiple","ignoreFile","ignoreFolder","printMode","ignoreGitIgnore","parameters","path","usage"],"mappings":"AAAA,SAASA,YAAY,EAAEC,iBAAiB,QAAQ,gBAAgB;AAEhE,SAASC,MAAM,QAAQ,mBAAmB;AAuB1C,wBAAwB,GACxB,OAAO,MAAMC,SAAwBD,OAAO;IAC3CE,MAAM;IACNC,UAAU;QACT;YACCC,SAAS;YACTC,SACC;QACF;QACA;YACCD,SAAS;YACTC,SAAS,CAAC,uHAAuH,CAAC;QACnI;QACA;YACCD,SAAS;YACTC,SAAS,CAAC,sGAAsG,CAAC;QAClH;KACA;IACDC,OAAO;QACNC,QAAQ;YACPC,WAAW;YACXC,SAASX,aAAaS,MAAM;YAC5BG,aAAa;YACbC,MAAM;QACP;QACAP,SAAS;YACRI,WAAW;YACXE,aAAa;YACbC,MAAM;QACP;QACAC,KAAK;YACJH,SAASX,aAAac,GAAG;YACzBF,aAAa;YACbC,MAAM;QACP;QACAE,MAAM;YACLL,WAAW;YACXE,aAAa;YACbC,MAAM;QACP;QACAG,MAAM;YACLN,WAAW;YACXE,aAAa;YACbC,MAAM;QACP;QACAI,YAAY;YACXP,WAAW;YACXC,SAASX,aAAaiB,UAAU;YAChCL,aAAa;YACbC,MAAM;QACP;QACAK,SAAS;YACRR,WAAW;YACXE,aAAa;YACbC,MAAM;QACP;QACAM,OAAO;YACNR,SAASX,aAAamB,KAAK;YAC3BP,aAAa;YACbC,MAAM;QACP;QACAO,OAAO;YACNV,WAAW;YACXC,SAASX,aAAaoB,KAAK;YAC3BR,aAAa;YACbC,MAAM;QACP;QACAA,MAAM;YACLH,WAAW;YACXC,SAAS;YACTC,aAAa;YACbC,MAAM;QACP;QACAQ,SAAS;YACRX,WAAW;YACXE,aAAa;YACbC,MAAM;QACP;QACAS,iBAAiB;YAChBZ,WAAW;YACXE,aAAa;YACbC,MAAM;YACNU,YAAY;QACb;QACAC,YAAY;YACXd,WAAW;YACXE,aAAa;YACbC,MAAM;YACNU,YAAY;QACb;QACAE,cAAc;YACbf,WAAW;YACXE,aAAa;YACbC,MAAM;YACNU,YAAY;QACb;QACAG,WAAW;YACVhB,WAAW;YACXE,aAAa;YACbC,MAAM;QACP;QACAc,iBAAiB;YAChBf,aAAa;YACbD,SAASX,aAAa2B,eAAe;YACrCd,MAAM;QACP;IACD;IACAe,YAAY;QACXC,MAAM;YACLlB,SAAS;YACTC,aAAa;QACd;IACD;IACAkB,OAAO;IACP9B;IACAC;AACD,GAAG"}
1
+ {"version":3,"sources":["../src/parse.ts"],"sourcesContent":["/* v8 ignore start */\nimport { defaultFlags, defaultParameters } from \"./defaults.js\";\n\nimport { parser } from \"@node-cli/parser\";\n\nexport type Flags = {\n\tboring?: boolean;\n\tdot?: boolean;\n\tignoreCase?: boolean;\n\tshort?: boolean;\n\tstats?: boolean;\n\tgrep?: string;\n\ttype?: string;\n\tignore?: string[];\n\tprintMode?: string;\n};\n\nexport type Parameters = {\n\tpath?: string;\n};\n\nexport type Configuration = {\n\tflags?: Flags;\n\tparameters?: Parameters;\n};\n\n/* v8 ignore start */\nexport const config: Configuration = parser({\n\tmeta: import.meta,\n\texamples: [\n\t\t{\n\t\t\tcommand: 'search --type f --pattern \".jsx$\" src/',\n\t\t\tcomment:\n\t\t\t\t'## Find all files with the extension \".jsx\" in the \"src\" folder',\n\t\t},\n\t\t{\n\t\t\tcommand: 'search --type f --pattern \".sh$\" --command \"chmod +x\" bin/',\n\t\t\tcomment: `## Change the permissions to executable for all the files with\\n ## the extension \".sh\" found under the \"bin\" folder`,\n\t\t},\n\t\t{\n\t\t\tcommand: 'search --type f --pattern \".md$\" --grep \"Table of Content\"',\n\t\t\tcomment: `## Search in all the markdown files under the \"src\" folder for\\n ## the keywords \"Table of Content\"`,\n\t\t},\n\t],\n\tflags: {\n\t\tboring: {\n\t\t\tshortFlag: \"b\",\n\t\t\tdefault: defaultFlags.boring,\n\t\t\tdescription: \"Do not use color output\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\tcommand: {\n\t\t\tshortFlag: \"c\",\n\t\t\tdescription: \"Command to execute over each node (ex: chmod +x)\",\n\t\t\ttype: \"string\",\n\t\t},\n\t\tdot: {\n\t\t\tdefault: defaultFlags.dot,\n\t\t\tdescription: \"Show hidden files and directories\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\tgrep: {\n\t\t\tshortFlag: \"g\",\n\t\t\tdescription: \"A RegExp to match the content of the files found\",\n\t\t\ttype: \"string\",\n\t\t},\n\t\thelp: {\n\t\t\tshortFlag: \"h\",\n\t\t\tdescription: \"Display help instructions\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\tignoreCase: {\n\t\t\tshortFlag: \"i\",\n\t\t\tdefault: defaultFlags.ignoreCase,\n\t\t\tdescription: \"Ignore case when searching\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\tpattern: {\n\t\t\tshortFlag: \"p\",\n\t\t\tdescription: \"A regular expression to match file or folder names\",\n\t\t\ttype: \"string\",\n\t\t},\n\t\tshort: {\n\t\t\tdefault: defaultFlags.short,\n\t\t\tdescription: \"Short listing format (equivalent to ls)\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\tstats: {\n\t\t\tshortFlag: \"s\",\n\t\t\tdefault: defaultFlags.stats,\n\t\t\tdescription: \"Display some statistics\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\ttype: {\n\t\t\tshortFlag: \"t\",\n\t\t\tdefault: \"both\",\n\t\t\tdescription: \"Search for files (f) or directories (d)\",\n\t\t\ttype: \"string\",\n\t\t},\n\t\tversion: {\n\t\t\tshortFlag: \"v\",\n\t\t\tdescription: \"Output the current version\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\tignoreExtension: {\n\t\t\tshortFlag: \"I\",\n\t\t\tdescription: \"Ignore files extension, can be used multiple times\",\n\t\t\ttype: \"string\",\n\t\t\tisMultiple: true,\n\t\t},\n\t\tignoreFile: {\n\t\t\tshortFlag: \"F\",\n\t\t\tdescription: \"Ignore files name, can be used multiple times\",\n\t\t\ttype: \"string\",\n\t\t\tisMultiple: true,\n\t\t},\n\t\tignoreFolder: {\n\t\t\tshortFlag: \"D\",\n\t\t\tdescription: \"Ignore folders name, can be used multiple times\",\n\t\t\ttype: \"string\",\n\t\t\tisMultiple: true,\n\t\t},\n\t\tprintMode: {\n\t\t\tshortFlag: \"P\",\n\t\t\tdescription: \"Print mode (simple or xml)\",\n\t\t\ttype: \"string\",\n\t\t},\n\t\tignoreGitIgnore: {\n\t\t\tdescription: \"Ignore .gitignore files\",\n\t\t\tdefault: defaultFlags.ignoreGitIgnore,\n\t\t\ttype: \"boolean\",\n\t\t},\n\t},\n\tparameters: {\n\t\tpath: {\n\t\t\tdefault: \"current folder\",\n\t\t\tdescription: \"the path where to start the search\",\n\t\t},\n\t},\n\tusage: \"search [options] [path]\",\n\tdefaultFlags,\n\tdefaultParameters,\n});\n/* v8 ignore stop */\n"],"names":["defaultFlags","defaultParameters","parser","config","meta","examples","command","comment","flags","boring","shortFlag","default","description","type","dot","grep","help","ignoreCase","pattern","short","stats","version","ignoreExtension","isMultiple","ignoreFile","ignoreFolder","printMode","ignoreGitIgnore","parameters","path","usage"],"mappings":"AAAA,mBAAmB,GACnB,SAASA,YAAY,EAAEC,iBAAiB,QAAQ,gBAAgB;AAEhE,SAASC,MAAM,QAAQ,mBAAmB;AAuB1C,mBAAmB,GACnB,OAAO,MAAMC,SAAwBD,OAAO;IAC3CE,MAAM;IACNC,UAAU;QACT;YACCC,SAAS;YACTC,SACC;QACF;QACA;YACCD,SAAS;YACTC,SAAS,CAAC,uHAAuH,CAAC;QACnI;QACA;YACCD,SAAS;YACTC,SAAS,CAAC,sGAAsG,CAAC;QAClH;KACA;IACDC,OAAO;QACNC,QAAQ;YACPC,WAAW;YACXC,SAASX,aAAaS,MAAM;YAC5BG,aAAa;YACbC,MAAM;QACP;QACAP,SAAS;YACRI,WAAW;YACXE,aAAa;YACbC,MAAM;QACP;QACAC,KAAK;YACJH,SAASX,aAAac,GAAG;YACzBF,aAAa;YACbC,MAAM;QACP;QACAE,MAAM;YACLL,WAAW;YACXE,aAAa;YACbC,MAAM;QACP;QACAG,MAAM;YACLN,WAAW;YACXE,aAAa;YACbC,MAAM;QACP;QACAI,YAAY;YACXP,WAAW;YACXC,SAASX,aAAaiB,UAAU;YAChCL,aAAa;YACbC,MAAM;QACP;QACAK,SAAS;YACRR,WAAW;YACXE,aAAa;YACbC,MAAM;QACP;QACAM,OAAO;YACNR,SAASX,aAAamB,KAAK;YAC3BP,aAAa;YACbC,MAAM;QACP;QACAO,OAAO;YACNV,WAAW;YACXC,SAASX,aAAaoB,KAAK;YAC3BR,aAAa;YACbC,MAAM;QACP;QACAA,MAAM;YACLH,WAAW;YACXC,SAAS;YACTC,aAAa;YACbC,MAAM;QACP;QACAQ,SAAS;YACRX,WAAW;YACXE,aAAa;YACbC,MAAM;QACP;QACAS,iBAAiB;YAChBZ,WAAW;YACXE,aAAa;YACbC,MAAM;YACNU,YAAY;QACb;QACAC,YAAY;YACXd,WAAW;YACXE,aAAa;YACbC,MAAM;YACNU,YAAY;QACb;QACAE,cAAc;YACbf,WAAW;YACXE,aAAa;YACbC,MAAM;YACNU,YAAY;QACb;QACAG,WAAW;YACVhB,WAAW;YACXE,aAAa;YACbC,MAAM;QACP;QACAc,iBAAiB;YAChBf,aAAa;YACbD,SAASX,aAAa2B,eAAe;YACrCd,MAAM;QACP;IACD;IACAe,YAAY;QACXC,MAAM;YACLlB,SAAS;YACTC,aAAa;QACd;IACD;IACAkB,OAAO;IACP9B;IACAC;AACD,GAAG,CACH,kBAAkB"}
package/dist/search.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- /* istanbul ignore file */ import path from "node:path";
2
+ /* v8 ignore start */ import path from "node:path";
3
3
  import { Logger } from "@node-cli/logger";
4
4
  import fs from "fs-extra";
5
5
  import { Search } from "./core.js";
@@ -26,6 +26,6 @@ const search = new Search({
26
26
  ...config.flags,
27
27
  path: customPath
28
28
  });
29
- await search.start();
29
+ await search.start(); /* v8 ignore stop */
30
30
 
31
31
  //# sourceMappingURL=search.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/search.ts"],"sourcesContent":["#!/usr/bin/env node\n/* istanbul ignore file */\n\nimport path from \"node:path\";\nimport { Logger } from \"@node-cli/logger\";\nimport fs from \"fs-extra\";\nimport { Search } from \"./core.js\";\nimport { config } from \"./parse.js\";\nimport { STR_TYPE_FILE } from \"./utilities.js\";\n\nconst logger = new Logger({\n\tboring: process.env.NODE_ENV === \"test\",\n});\n\nlet customPath = config.parameters[0];\nif (fs.pathExistsSync(customPath)) {\n\tcustomPath = path.resolve(customPath);\n} else {\n\tlogger.printErrorsAndExit([`Folder ${customPath} does not exist!`], 0);\n}\n\nif (config.flags.grep) {\n\t// forcing simplified display if grep is true.\n\tconfig.flags.short = true;\n\t// And forcing type to files\n\tconfig.flags.type = STR_TYPE_FILE;\n}\n\nconst search = new Search({\n\t...config.flags,\n\tpath: customPath,\n});\n\nawait search.start();\n"],"names":["path","Logger","fs","Search","config","STR_TYPE_FILE","logger","boring","process","env","NODE_ENV","customPath","parameters","pathExistsSync","resolve","printErrorsAndExit","flags","grep","short","type","search","start"],"mappings":";AACA,wBAAwB,GAExB,OAAOA,UAAU,YAAY;AAC7B,SAASC,MAAM,QAAQ,mBAAmB;AAC1C,OAAOC,QAAQ,WAAW;AAC1B,SAASC,MAAM,QAAQ,YAAY;AACnC,SAASC,MAAM,QAAQ,aAAa;AACpC,SAASC,aAAa,QAAQ,iBAAiB;AAE/C,MAAMC,SAAS,IAAIL,OAAO;IACzBM,QAAQC,QAAQC,GAAG,CAACC,QAAQ,KAAK;AAClC;AAEA,IAAIC,aAAaP,OAAOQ,UAAU,CAAC,EAAE;AACrC,IAAIV,GAAGW,cAAc,CAACF,aAAa;IAClCA,aAAaX,KAAKc,OAAO,CAACH;AAC3B,OAAO;IACNL,OAAOS,kBAAkB,CAAC;QAAC,CAAC,OAAO,EAAEJ,WAAW,gBAAgB,CAAC;KAAC,EAAE;AACrE;AAEA,IAAIP,OAAOY,KAAK,CAACC,IAAI,EAAE;IACtB,8CAA8C;IAC9Cb,OAAOY,KAAK,CAACE,KAAK,GAAG;IACrB,4BAA4B;IAC5Bd,OAAOY,KAAK,CAACG,IAAI,GAAGd;AACrB;AAEA,MAAMe,SAAS,IAAIjB,OAAO;IACzB,GAAGC,OAAOY,KAAK;IACfhB,MAAMW;AACP;AAEA,MAAMS,OAAOC,KAAK"}
1
+ {"version":3,"sources":["../src/search.ts"],"sourcesContent":["#!/usr/bin/env node\n/* v8 ignore start */\n\nimport path from \"node:path\";\nimport { Logger } from \"@node-cli/logger\";\nimport fs from \"fs-extra\";\nimport { Search } from \"./core.js\";\nimport { config } from \"./parse.js\";\nimport { STR_TYPE_FILE } from \"./utilities.js\";\n\nconst logger = new Logger({\n\tboring: process.env.NODE_ENV === \"test\",\n});\n\nlet customPath = config.parameters[0];\nif (fs.pathExistsSync(customPath)) {\n\tcustomPath = path.resolve(customPath);\n} else {\n\tlogger.printErrorsAndExit([`Folder ${customPath} does not exist!`], 0);\n}\n\nif (config.flags.grep) {\n\t// forcing simplified display if grep is true.\n\tconfig.flags.short = true;\n\t// And forcing type to files\n\tconfig.flags.type = STR_TYPE_FILE;\n}\n\nconst search = new Search({\n\t...config.flags,\n\tpath: customPath,\n});\n\nawait search.start();\n/* v8 ignore stop */\n"],"names":["path","Logger","fs","Search","config","STR_TYPE_FILE","logger","boring","process","env","NODE_ENV","customPath","parameters","pathExistsSync","resolve","printErrorsAndExit","flags","grep","short","type","search","start"],"mappings":";AACA,mBAAmB,GAEnB,OAAOA,UAAU,YAAY;AAC7B,SAASC,MAAM,QAAQ,mBAAmB;AAC1C,OAAOC,QAAQ,WAAW;AAC1B,SAASC,MAAM,QAAQ,YAAY;AACnC,SAASC,MAAM,QAAQ,aAAa;AACpC,SAASC,aAAa,QAAQ,iBAAiB;AAE/C,MAAMC,SAAS,IAAIL,OAAO;IACzBM,QAAQC,QAAQC,GAAG,CAACC,QAAQ,KAAK;AAClC;AAEA,IAAIC,aAAaP,OAAOQ,UAAU,CAAC,EAAE;AACrC,IAAIV,GAAGW,cAAc,CAACF,aAAa;IAClCA,aAAaX,KAAKc,OAAO,CAACH;AAC3B,OAAO;IACNL,OAAOS,kBAAkB,CAAC;QAAC,CAAC,OAAO,EAAEJ,WAAW,gBAAgB,CAAC;KAAC,EAAE;AACrE;AAEA,IAAIP,OAAOY,KAAK,CAACC,IAAI,EAAE;IACtB,8CAA8C;IAC9Cb,OAAOY,KAAK,CAACE,KAAK,GAAG;IACrB,4BAA4B;IAC5Bd,OAAOY,KAAK,CAACG,IAAI,GAAGd;AACrB;AAEA,MAAMe,SAAS,IAAIjB,OAAO;IACzB,GAAGC,OAAOY,KAAK;IACfhB,MAAMW;AACP;AAEA,MAAMS,OAAOC,KAAK,IAClB,kBAAkB"}
@@ -1,6 +1,7 @@
1
1
  export declare const STR_TYPE_DIRECTORY = "d";
2
2
  export declare const STR_TYPE_FILE = "f";
3
3
  export declare const STR_TYPE_BOTH = "both";
4
+ export declare const getFileExtension: (filename: string) => string;
4
5
  export declare const extractMode: (mode: number) => string;
5
6
  export declare const convertSize: (bytes: number) => string;
6
7
  export declare const convertDate: (mtime: Date) => string;
@@ -34,3 +35,4 @@ export type RunGrepOnNode = {
34
35
  totalMatchingLines: number;
35
36
  };
36
37
  export declare const runGrepOnNode: (node?: string, rePattern?: RegExp) => Promise<RunGrepOnNode>;
38
+ export declare function isBinaryFileExtension(filePath: string): boolean;
package/dist/utilities.js CHANGED
@@ -1,6 +1,7 @@
1
- import { run } from "@node-cli/run";
2
1
  import fs from "node:fs";
2
+ import { extname } from "node:path";
3
3
  import { Logger } from "@node-cli/logger";
4
+ import { run } from "@node-cli/run";
4
5
  import kleur from "kleur";
5
6
  import prettyMilliseconds from "pretty-ms";
6
7
  const BYTE_CHUNKS = 1000;
@@ -17,6 +18,62 @@ const PERMISSIONS_PREFIX = {
17
18
  [STR_TYPE_DIRECTORY]: "d",
18
19
  [STR_TYPE_FILE]: "-"
19
20
  };
21
+ const BINARY_EXTENSIONS = [
22
+ // Executables and compiled code
23
+ "exe",
24
+ "dll",
25
+ "so",
26
+ "dylib",
27
+ "bin",
28
+ "obj",
29
+ "o",
30
+ // Compressed files
31
+ "zip",
32
+ "tar",
33
+ "gz",
34
+ "rar",
35
+ "7z",
36
+ "jar",
37
+ "war",
38
+ // Media files
39
+ "jpg",
40
+ "jpeg",
41
+ "png",
42
+ "gif",
43
+ "bmp",
44
+ "ico",
45
+ "tif",
46
+ "tiff",
47
+ "mp3",
48
+ "mp4",
49
+ "avi",
50
+ "mov",
51
+ "wmv",
52
+ "flv",
53
+ "wav",
54
+ "ogg",
55
+ // Document formats
56
+ "pdf",
57
+ "doc",
58
+ "docx",
59
+ "xls",
60
+ "xlsx",
61
+ "ppt",
62
+ "pptx",
63
+ // Database files
64
+ "db",
65
+ "sqlite",
66
+ "mdb",
67
+ // Other binary formats
68
+ "class",
69
+ "pyc",
70
+ "pyd",
71
+ "pyo",
72
+ "woff",
73
+ "woff2",
74
+ "ttf",
75
+ "otf"
76
+ ];
20
77
  const ownerNames = {
21
78
  0: "root"
22
79
  };
@@ -37,6 +94,9 @@ const MONTHS = {
37
94
  const logger = new Logger({
38
95
  boring: process.env.NODE_ENV === "test"
39
96
  });
97
+ export const getFileExtension = (filename)=>{
98
+ return extname(filename).toLowerCase().replace(/^\./, "");
99
+ };
40
100
  export const extractMode = (mode)=>{
41
101
  const modeDec = Number.parseInt(mode.toString(OCTAL), DECIMAL).toString().slice(LAST_THREE_ENTRIES);
42
102
  const modeOwner = modeDec.charAt(MODE_OWNER_POS);
@@ -82,7 +142,7 @@ export const convertDate = (mtime)=>{
82
142
  };
83
143
  export const getOwnerNameFromId = async (uid)=>{
84
144
  let result;
85
- /* istanbul ignore else */ if (ownerNames[uid]) {
145
+ /* v8 ignore next */ if (ownerNames[uid]) {
86
146
  return ownerNames[uid];
87
147
  } else {
88
148
  try {
@@ -169,8 +229,16 @@ export const runGrepOnNode = async (node, rePattern)=>{
169
229
  totalMatchingLines
170
230
  };
171
231
  } catch (error) {
172
- /* istanbul ignore next */ logger.error(error);
232
+ /* v8 ignore next */ logger.error(error);
173
233
  }
174
234
  };
235
+ export function isBinaryFileExtension(filePath) {
236
+ const ext = getFileExtension(filePath);
237
+ // If there's no extension, assume it's binary
238
+ if (!ext) {
239
+ return true;
240
+ }
241
+ return BINARY_EXTENSIONS.includes(ext);
242
+ }
175
243
 
176
244
  //# sourceMappingURL=utilities.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utilities.ts"],"sourcesContent":["import { RunResult, run } from \"@node-cli/run\";\n\nimport fs from \"node:fs\";\nimport { Logger } from \"@node-cli/logger\";\nimport kleur from \"kleur\";\nimport prettyMilliseconds from \"pretty-ms\";\n\nconst BYTE_CHUNKS = 1000;\nconst DECIMAL = 10;\nconst LAST_THREE_ENTRIES = -3;\nconst MODE_GROUP_POS = 1;\nconst MODE_OWNER_POS = 0;\nconst MODE_WORD_POS = 2;\nconst OCTAL = 8;\nexport const STR_TYPE_DIRECTORY = \"d\";\nexport const STR_TYPE_FILE = \"f\";\nexport const STR_TYPE_BOTH = \"both\";\nconst PERMISSIONS_PREFIX = {\n\t[STR_TYPE_DIRECTORY]: \"d\",\n\t[STR_TYPE_FILE]: \"-\",\n};\n\nconst ownerNames = {\n\t0: \"root\",\n};\n\nconst MONTHS = {\n\t0: \"Jan\",\n\t1: \"Feb\",\n\t2: \"Mar\",\n\t3: \"Apr\",\n\t4: \"May\",\n\t5: \"Jun\",\n\t6: \"Jul\",\n\t7: \"Aug\",\n\t8: \"Sep\",\n\t9: \"Oct\",\n\t10: \"Nov\",\n\t11: \"Dec\",\n};\n\nconst logger = new Logger({\n\tboring: process.env.NODE_ENV === \"test\",\n});\n\nexport const extractMode = (mode: number): string => {\n\tconst modeDec = Number.parseInt(mode.toString(OCTAL), DECIMAL)\n\t\t.toString()\n\t\t.slice(LAST_THREE_ENTRIES);\n\tconst modeOwner = modeDec.charAt(MODE_OWNER_POS);\n\tconst modeGroup = modeDec.charAt(MODE_GROUP_POS);\n\tconst modeWorld = modeDec.charAt(MODE_WORD_POS);\n\tconst modes = {\n\t\t0: \"---\",\n\t\t1: \"--x\",\n\t\t2: \"-w-\",\n\t\t3: \"-wx\",\n\t\t4: \"r--\",\n\t\t5: \"r-x\",\n\t\t6: \"rw-\",\n\t\t7: \"rwx\",\n\t};\n\treturn modes[modeOwner] + modes[modeGroup] + modes[modeWorld];\n};\n\nexport const convertSize = (bytes: number): string => {\n\tconst sizes = [\"B\", \"K\", \"M\", \"G\", \"T\"];\n\tconst length = 5;\n\tlet posttxt = 0;\n\n\twhile (bytes >= BYTE_CHUNKS) {\n\t\tposttxt = posttxt + 1;\n\t\tbytes = bytes / BYTE_CHUNKS;\n\t}\n\tconst string_ =\n\t\tNumber.parseInt(bytes.toString(), DECIMAL).toFixed(0) + sizes[posttxt];\n\treturn (\n\t\tArray.from({ length: length + 1 - string_.length }).join(\" \") + string_\n\t);\n};\n\nexport const convertDate = (mtime: Date): string => {\n\tconst month = MONTHS[mtime.getMonth()];\n\tconst date = `${mtime.getDate()}`.padStart(2, \"0\");\n\tconst hours = `${mtime.getHours()}`.padStart(2, \"0\");\n\tconst minutes = `${mtime.getMinutes()}`.padStart(2, \"0\");\n\treturn `${month} ${date} ${hours}:${minutes}`;\n};\n\nexport const getOwnerNameFromId = async (\n\tuid: string | number,\n): Promise<string | number> => {\n\tlet result: RunResult;\n\n\t/* istanbul ignore else */\n\tif (ownerNames[uid]) {\n\t\treturn ownerNames[uid];\n\t} else {\n\t\ttry {\n\t\t\tresult = await run(`id -nu ${uid}`);\n\t\t\townerNames[uid] = result.stdout;\n\t\t\treturn result.stdout;\n\t\t} catch {\n\t\t\t// nothing to declare officer\n\t\t\treturn `${uid}`;\n\t\t}\n\t}\n};\n\nexport const formatLongListings = async (\n\tstat: { mtime: Date; mode: number; uid: string | number; size: number },\n\ttype: string,\n): Promise<{\n\tmdate: string;\n\tmode: string;\n\towner: string;\n\tsize: string;\n}> => ({\n\tmdate: `${convertDate(stat.mtime)}`,\n\tmode: PERMISSIONS_PREFIX[type] + extractMode(stat.mode),\n\towner: `${await getOwnerNameFromId(stat.uid)}`,\n\tsize: `${convertSize(stat.size)}`,\n});\n\nexport type Statistics = {\n\tduration?: number;\n\ttotalDirScanned?: number;\n\ttotalDirsFound?: number;\n\ttotalFileScanned?: number;\n\ttotalFilesFound?: number;\n\ttype?: string;\n\tpattern?: boolean | RegExp;\n\tgrep?: boolean | RegExp | string;\n};\nexport const printStatistics = ({\n\tduration,\n\ttotalDirScanned,\n\ttotalDirsFound,\n\ttotalFileScanned,\n\ttotalFilesFound,\n\ttype,\n\tpattern,\n\tgrep,\n}: Statistics) => {\n\tlet message = `Total folders scanned: ${kleur.yellow(totalDirScanned)}\\n`;\n\tmessage += `Total files scanned: ${kleur.yellow(totalFileScanned)}\\n`;\n\tswitch (type) {\n\t\tcase STR_TYPE_DIRECTORY: {\n\t\t\tmessage += `Total folders matching: ${kleur.green(totalDirsFound)}\\n`;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase STR_TYPE_FILE: {\n\t\t\tmessage += `Total files matching: ${kleur.green(totalFilesFound)}\\n`;\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault: {\n\t\t\tif (pattern) {\n\t\t\t\tmessage += `Total folders matching: ${kleur.green(totalDirsFound)}\\n`;\n\t\t\t\tmessage += `Total files matching: ${kleur.green(totalFilesFound)}\\n`;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tmessage += `Duration: ${kleur.yellow(`${prettyMilliseconds(duration)}`)}`;\n\tif (!grep) {\n\t\tlogger.log();\n\t}\n\tlogger.printBox(message);\n};\n\nexport const checkPattern = (\n\trePattern: RegExp | undefined,\n\tstring_: string,\n): boolean | RegExpExecArray => {\n\tif (rePattern) {\n\t\trePattern.lastIndex = 0;\n\t\treturn rePattern.exec(string_);\n\t}\n\treturn true;\n};\n\nexport const runCommandOnNode = async (node: string, command: string) => {\n\ttry {\n\t\tconst { stdout } = await run(`${command} ${node}`);\n\t\tif (stdout) {\n\t\t\tlogger.log(stdout);\n\t\t}\n\t} catch {\n\t\t// nothing to declare officer\n\t}\n};\n\nexport type RunGrepOnNode = {\n\tresults: (string | number)[];\n\ttotalMatchingLines: number;\n};\nexport const runGrepOnNode = async (\n\tnode?: string,\n\trePattern?: RegExp,\n): Promise<RunGrepOnNode> => {\n\ttry {\n\t\tconst lines = [];\n\t\tlet totalMatchingLines = 0;\n\t\tconst buffer = fs.readFileSync(node, \"utf8\").split(\"\\n\");\n\n\t\tfor (const [lineNumber, line] of buffer.entries()) {\n\t\t\trePattern.lastIndex = 0;\n\t\t\tconst result: (string | number)[] = rePattern.exec(line);\n\t\t\tif (!result) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ttotalMatchingLines++;\n\t\t\tif (lineNumber > 0) {\n\t\t\t\tlines.push(`${lineNumber}: ${kleur.grey(buffer[lineNumber - 1])}`);\n\t\t\t}\n\t\t\tlines.push(\n\t\t\t\t`${lineNumber + 1}: ${kleur.grey(\n\t\t\t\t\tline.replace(rePattern, kleur.black().bgYellow(result[0])),\n\t\t\t\t)}`,\n\t\t\t\t`${lineNumber + 2}: ${kleur.grey(buffer[lineNumber + 1])}`,\n\t\t\t\t\"\",\n\t\t\t);\n\t\t}\n\t\treturn {\n\t\t\tresults: lines.length > 0 ? lines : [],\n\t\t\ttotalMatchingLines,\n\t\t};\n\t} catch (error) {\n\t\t/* istanbul ignore next */\n\t\tlogger.error(error);\n\t}\n};\n"],"names":["run","fs","Logger","kleur","prettyMilliseconds","BYTE_CHUNKS","DECIMAL","LAST_THREE_ENTRIES","MODE_GROUP_POS","MODE_OWNER_POS","MODE_WORD_POS","OCTAL","STR_TYPE_DIRECTORY","STR_TYPE_FILE","STR_TYPE_BOTH","PERMISSIONS_PREFIX","ownerNames","MONTHS","logger","boring","process","env","NODE_ENV","extractMode","mode","modeDec","Number","parseInt","toString","slice","modeOwner","charAt","modeGroup","modeWorld","modes","convertSize","bytes","sizes","length","posttxt","string_","toFixed","Array","from","join","convertDate","mtime","month","getMonth","date","getDate","padStart","hours","getHours","minutes","getMinutes","getOwnerNameFromId","uid","result","stdout","formatLongListings","stat","type","mdate","owner","size","printStatistics","duration","totalDirScanned","totalDirsFound","totalFileScanned","totalFilesFound","pattern","grep","message","yellow","green","log","printBox","checkPattern","rePattern","lastIndex","exec","runCommandOnNode","node","command","runGrepOnNode","lines","totalMatchingLines","buffer","readFileSync","split","lineNumber","line","entries","push","grey","replace","black","bgYellow","results","error"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/utilities.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport { extname } from \"node:path\";\nimport { Logger } from \"@node-cli/logger\";\nimport { RunResult, run } from \"@node-cli/run\";\nimport kleur from \"kleur\";\nimport prettyMilliseconds from \"pretty-ms\";\n\nconst BYTE_CHUNKS = 1000;\nconst DECIMAL = 10;\nconst LAST_THREE_ENTRIES = -3;\nconst MODE_GROUP_POS = 1;\nconst MODE_OWNER_POS = 0;\nconst MODE_WORD_POS = 2;\nconst OCTAL = 8;\nexport const STR_TYPE_DIRECTORY = \"d\";\nexport const STR_TYPE_FILE = \"f\";\nexport const STR_TYPE_BOTH = \"both\";\nconst PERMISSIONS_PREFIX = {\n\t[STR_TYPE_DIRECTORY]: \"d\",\n\t[STR_TYPE_FILE]: \"-\",\n};\nconst BINARY_EXTENSIONS = [\n\t// Executables and compiled code\n\t\"exe\",\n\t\"dll\",\n\t\"so\",\n\t\"dylib\",\n\t\"bin\",\n\t\"obj\",\n\t\"o\",\n\t// Compressed files\n\t\"zip\",\n\t\"tar\",\n\t\"gz\",\n\t\"rar\",\n\t\"7z\",\n\t\"jar\",\n\t\"war\",\n\t// Media files\n\t\"jpg\",\n\t\"jpeg\",\n\t\"png\",\n\t\"gif\",\n\t\"bmp\",\n\t\"ico\",\n\t\"tif\",\n\t\"tiff\",\n\t\"mp3\",\n\t\"mp4\",\n\t\"avi\",\n\t\"mov\",\n\t\"wmv\",\n\t\"flv\",\n\t\"wav\",\n\t\"ogg\",\n\t// Document formats\n\t\"pdf\",\n\t\"doc\",\n\t\"docx\",\n\t\"xls\",\n\t\"xlsx\",\n\t\"ppt\",\n\t\"pptx\",\n\t// Database files\n\t\"db\",\n\t\"sqlite\",\n\t\"mdb\",\n\t// Other binary formats\n\t\"class\",\n\t\"pyc\",\n\t\"pyd\",\n\t\"pyo\",\n\t\"woff\",\n\t\"woff2\",\n\t\"ttf\",\n\t\"otf\",\n];\n\nconst ownerNames = {\n\t0: \"root\",\n};\n\nconst MONTHS = {\n\t0: \"Jan\",\n\t1: \"Feb\",\n\t2: \"Mar\",\n\t3: \"Apr\",\n\t4: \"May\",\n\t5: \"Jun\",\n\t6: \"Jul\",\n\t7: \"Aug\",\n\t8: \"Sep\",\n\t9: \"Oct\",\n\t10: \"Nov\",\n\t11: \"Dec\",\n};\n\nconst logger = new Logger({\n\tboring: process.env.NODE_ENV === \"test\",\n});\n\nexport const getFileExtension = (filename: string): string => {\n\treturn extname(filename).toLowerCase().replace(/^\\./, \"\");\n};\n\nexport const extractMode = (mode: number): string => {\n\tconst modeDec = Number.parseInt(mode.toString(OCTAL), DECIMAL)\n\t\t.toString()\n\t\t.slice(LAST_THREE_ENTRIES);\n\tconst modeOwner = modeDec.charAt(MODE_OWNER_POS);\n\tconst modeGroup = modeDec.charAt(MODE_GROUP_POS);\n\tconst modeWorld = modeDec.charAt(MODE_WORD_POS);\n\tconst modes = {\n\t\t0: \"---\",\n\t\t1: \"--x\",\n\t\t2: \"-w-\",\n\t\t3: \"-wx\",\n\t\t4: \"r--\",\n\t\t5: \"r-x\",\n\t\t6: \"rw-\",\n\t\t7: \"rwx\",\n\t};\n\treturn modes[modeOwner] + modes[modeGroup] + modes[modeWorld];\n};\n\nexport const convertSize = (bytes: number): string => {\n\tconst sizes = [\"B\", \"K\", \"M\", \"G\", \"T\"];\n\tconst length = 5;\n\tlet posttxt = 0;\n\n\twhile (bytes >= BYTE_CHUNKS) {\n\t\tposttxt = posttxt + 1;\n\t\tbytes = bytes / BYTE_CHUNKS;\n\t}\n\tconst string_ =\n\t\tNumber.parseInt(bytes.toString(), DECIMAL).toFixed(0) + sizes[posttxt];\n\treturn (\n\t\tArray.from({ length: length + 1 - string_.length }).join(\" \") + string_\n\t);\n};\n\nexport const convertDate = (mtime: Date): string => {\n\tconst month = MONTHS[mtime.getMonth()];\n\tconst date = `${mtime.getDate()}`.padStart(2, \"0\");\n\tconst hours = `${mtime.getHours()}`.padStart(2, \"0\");\n\tconst minutes = `${mtime.getMinutes()}`.padStart(2, \"0\");\n\treturn `${month} ${date} ${hours}:${minutes}`;\n};\n\nexport const getOwnerNameFromId = async (\n\tuid: string | number,\n): Promise<string | number> => {\n\tlet result: RunResult;\n\n\t/* v8 ignore next */\n\tif (ownerNames[uid]) {\n\t\treturn ownerNames[uid];\n\t} else {\n\t\ttry {\n\t\t\tresult = await run(`id -nu ${uid}`);\n\t\t\townerNames[uid] = result.stdout;\n\t\t\treturn result.stdout;\n\t\t} catch {\n\t\t\t// nothing to declare officer\n\t\t\treturn `${uid}`;\n\t\t}\n\t}\n};\n\nexport const formatLongListings = async (\n\tstat: { mtime: Date; mode: number; uid: string | number; size: number },\n\ttype: string,\n): Promise<{\n\tmdate: string;\n\tmode: string;\n\towner: string;\n\tsize: string;\n}> => ({\n\tmdate: `${convertDate(stat.mtime)}`,\n\tmode: PERMISSIONS_PREFIX[type] + extractMode(stat.mode),\n\towner: `${await getOwnerNameFromId(stat.uid)}`,\n\tsize: `${convertSize(stat.size)}`,\n});\n\nexport type Statistics = {\n\tduration?: number;\n\ttotalDirScanned?: number;\n\ttotalDirsFound?: number;\n\ttotalFileScanned?: number;\n\ttotalFilesFound?: number;\n\ttype?: string;\n\tpattern?: boolean | RegExp;\n\tgrep?: boolean | RegExp | string;\n};\nexport const printStatistics = ({\n\tduration,\n\ttotalDirScanned,\n\ttotalDirsFound,\n\ttotalFileScanned,\n\ttotalFilesFound,\n\ttype,\n\tpattern,\n\tgrep,\n}: Statistics) => {\n\tlet message = `Total folders scanned: ${kleur.yellow(totalDirScanned)}\\n`;\n\tmessage += `Total files scanned: ${kleur.yellow(totalFileScanned)}\\n`;\n\tswitch (type) {\n\t\tcase STR_TYPE_DIRECTORY: {\n\t\t\tmessage += `Total folders matching: ${kleur.green(totalDirsFound)}\\n`;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase STR_TYPE_FILE: {\n\t\t\tmessage += `Total files matching: ${kleur.green(totalFilesFound)}\\n`;\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault: {\n\t\t\tif (pattern) {\n\t\t\t\tmessage += `Total folders matching: ${kleur.green(totalDirsFound)}\\n`;\n\t\t\t\tmessage += `Total files matching: ${kleur.green(totalFilesFound)}\\n`;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tmessage += `Duration: ${kleur.yellow(`${prettyMilliseconds(duration)}`)}`;\n\tif (!grep) {\n\t\tlogger.log();\n\t}\n\tlogger.printBox(message);\n};\n\nexport const checkPattern = (\n\trePattern: RegExp | undefined,\n\tstring_: string,\n): boolean | RegExpExecArray => {\n\tif (rePattern) {\n\t\trePattern.lastIndex = 0;\n\t\treturn rePattern.exec(string_);\n\t}\n\treturn true;\n};\n\nexport const runCommandOnNode = async (node: string, command: string) => {\n\ttry {\n\t\tconst { stdout } = await run(`${command} ${node}`);\n\t\tif (stdout) {\n\t\t\tlogger.log(stdout);\n\t\t}\n\t} catch {\n\t\t// nothing to declare officer\n\t}\n};\n\nexport type RunGrepOnNode = {\n\tresults: (string | number)[];\n\ttotalMatchingLines: number;\n};\nexport const runGrepOnNode = async (\n\tnode?: string,\n\trePattern?: RegExp,\n): Promise<RunGrepOnNode> => {\n\ttry {\n\t\tconst lines = [];\n\t\tlet totalMatchingLines = 0;\n\t\tconst buffer = fs.readFileSync(node, \"utf8\").split(\"\\n\");\n\n\t\tfor (const [lineNumber, line] of buffer.entries()) {\n\t\t\trePattern.lastIndex = 0;\n\t\t\tconst result: (string | number)[] = rePattern.exec(line);\n\t\t\tif (!result) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ttotalMatchingLines++;\n\t\t\tif (lineNumber > 0) {\n\t\t\t\tlines.push(`${lineNumber}: ${kleur.grey(buffer[lineNumber - 1])}`);\n\t\t\t}\n\t\t\tlines.push(\n\t\t\t\t`${lineNumber + 1}: ${kleur.grey(\n\t\t\t\t\tline.replace(rePattern, kleur.black().bgYellow(result[0])),\n\t\t\t\t)}`,\n\t\t\t\t`${lineNumber + 2}: ${kleur.grey(buffer[lineNumber + 1])}`,\n\t\t\t\t\"\",\n\t\t\t);\n\t\t}\n\t\treturn {\n\t\t\tresults: lines.length > 0 ? lines : [],\n\t\t\ttotalMatchingLines,\n\t\t};\n\t} catch (error) {\n\t\t/* v8 ignore next */\n\t\tlogger.error(error);\n\t}\n};\n\nexport function isBinaryFileExtension(filePath: string): boolean {\n\tconst ext = getFileExtension(filePath);\n\t// If there's no extension, assume it's binary\n\tif (!ext) {\n\t\treturn true;\n\t}\n\treturn BINARY_EXTENSIONS.includes(ext);\n}\n"],"names":["fs","extname","Logger","run","kleur","prettyMilliseconds","BYTE_CHUNKS","DECIMAL","LAST_THREE_ENTRIES","MODE_GROUP_POS","MODE_OWNER_POS","MODE_WORD_POS","OCTAL","STR_TYPE_DIRECTORY","STR_TYPE_FILE","STR_TYPE_BOTH","PERMISSIONS_PREFIX","BINARY_EXTENSIONS","ownerNames","MONTHS","logger","boring","process","env","NODE_ENV","getFileExtension","filename","toLowerCase","replace","extractMode","mode","modeDec","Number","parseInt","toString","slice","modeOwner","charAt","modeGroup","modeWorld","modes","convertSize","bytes","sizes","length","posttxt","string_","toFixed","Array","from","join","convertDate","mtime","month","getMonth","date","getDate","padStart","hours","getHours","minutes","getMinutes","getOwnerNameFromId","uid","result","stdout","formatLongListings","stat","type","mdate","owner","size","printStatistics","duration","totalDirScanned","totalDirsFound","totalFileScanned","totalFilesFound","pattern","grep","message","yellow","green","log","printBox","checkPattern","rePattern","lastIndex","exec","runCommandOnNode","node","command","runGrepOnNode","lines","totalMatchingLines","buffer","readFileSync","split","lineNumber","line","entries","push","grey","black","bgYellow","results","error","isBinaryFileExtension","filePath","ext","includes"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node-cli/search",
3
- "version": "3.0.1",
3
+ "version": "3.1.1",
4
4
  "license": "MIT",
5
5
  "author": "Arno Versini",
6
6
  "description": "Search for files in a directory",
@@ -19,24 +19,29 @@
19
19
  "build:types": "tsc",
20
20
  "clean": "rimraf dist types coverage",
21
21
  "lint": "biome lint src",
22
- "test": "cross-env-shell NODE_OPTIONS=--experimental-vm-modules TZ=UTC jest",
23
- "test:coverage": "npm run test -- --coverage",
22
+ "test": "vitest run --globals",
23
+ "test:coverage": "vitest run --coverage --globals",
24
24
  "test:watch": "npm run test -- --watch",
25
25
  "watch": "swc --strip-leading-paths --watch --out-dir dist src"
26
26
  },
27
27
  "dependencies": {
28
- "@node-cli/logger": "1.3.0",
29
- "@node-cli/parser": "2.4.0",
30
- "@node-cli/perf": "1.0.6",
31
- "@node-cli/run": "1.1.2",
28
+ "@node-cli/logger": "1.3.1",
29
+ "@node-cli/parser": "2.4.1",
30
+ "@node-cli/perf": "1.0.7",
31
+ "@node-cli/run": "1.1.3",
32
32
  "fs-extra": "11.3.0",
33
33
  "kleur": "4.1.5",
34
34
  "micromatch": "4.0.8",
35
35
  "plur": "5.1.0",
36
- "pretty-ms": "9.2.0"
36
+ "pretty-ms": "9.2.0",
37
+ "uuid": "11.1.0"
37
38
  },
38
39
  "publishConfig": {
39
40
  "access": "public"
40
41
  },
41
- "gitHead": "e2e960f6c779f5069efaf294bb8067de1e325dc1"
42
+ "devDependencies": {
43
+ "@vitest/coverage-v8": "3.2.4",
44
+ "vitest": "3.2.4"
45
+ },
46
+ "gitHead": "2cef8f88aa5316a1789caad2bd7327ca908ccb9f"
42
47
  }