@node-cli/search 3.1.1 → 3.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/core.js CHANGED
@@ -7,7 +7,7 @@ import kleur from "kleur";
7
7
  import plur from "plur";
8
8
  import { GitIgnoreHandler } from "./gitIgnoreHandler.js";
9
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
+ import { checkPattern, formatLongListings, getFileExtension, isBinaryFileExtension, printStatistics, runCommandOnNode, runGrepOnNode, STR_TYPE_BOTH, STR_TYPE_DIRECTORY, STR_TYPE_FILE } from "./utilities.js";
11
11
  const lstatAsync = promisify(fs.lstat);
12
12
  const readdirAsync = promisify(fs.readdir);
13
13
  const readFileAsync = promisify(fs.readFile);
@@ -71,34 +71,34 @@ export class Search {
71
71
  }
72
72
  shouldIgnoreFolder(directory) {
73
73
  const folderName = basename(directory);
74
- // Check for exact folder name match
74
+ // Check for exact folder name match.
75
75
  if (this.ignoreFolders && this.ignoreFolders.includes(folderName)) {
76
76
  return true;
77
77
  }
78
78
  return false;
79
79
  }
80
80
  shouldIgnoreFile(filePath) {
81
- // First check if the file is in the ignoreFiles list
81
+ // First check if the file is in the ignoreFiles list.
82
82
  const filename = basename(filePath);
83
83
  if (this.ignoreFiles && this.ignoreFiles.includes(filename)) {
84
84
  return true;
85
85
  }
86
- // Then check if the extension should be ignored
86
+ // Then check if the extension should be ignored.
87
87
  if (!this.ignoreExtensions || this.ignoreExtensions.length === 0) {
88
88
  return false;
89
89
  }
90
90
  const extension = getFileExtension(filePath);
91
- // Check for exact extension match
91
+ // Check for exact extension match.
92
92
  if (this.ignoreExtensions.includes(extension)) {
93
93
  return true;
94
94
  }
95
- // Check for complex patterns like "min.js"
95
+ // Check for complex patterns like "min.js".
96
96
  for (const pattern of this.ignoreExtensions){
97
- // Skip patterns that don't contain a dot
97
+ // Skip patterns that don't contain a dot.
98
98
  if (!pattern.includes(".")) {
99
99
  continue;
100
100
  }
101
- // Check if the filename ends with the pattern
101
+ // Check if the filename ends with the pattern.
102
102
  if (filename.toLowerCase().endsWith(`.${pattern}`)) {
103
103
  return true;
104
104
  }
@@ -144,7 +144,7 @@ export class Search {
144
144
  }
145
145
  const isDirectory = stat && stat.isDirectory();
146
146
  const isFile = stat && stat.isFile();
147
- // Add this check to respect .gitignore patterns
147
+ // Add this check to respect .gitignore patterns.
148
148
  if (await this.shouldIgnoreByGitIgnore(node, isDirectory)) {
149
149
  continue;
150
150
  }
@@ -167,10 +167,10 @@ export class Search {
167
167
  return join(node, file);
168
168
  }));
169
169
  } catch {
170
- // nothing to declare
170
+ // nothing to declare.
171
171
  }
172
172
  } else if (isFile) {
173
- // Skip files with ignored extensions
173
+ // Skip files with ignored extensions.
174
174
  if (this.shouldIgnoreFile(node)) {
175
175
  continue;
176
176
  }
@@ -192,7 +192,7 @@ export class Search {
192
192
  }
193
193
  async readFileContent(filePath) {
194
194
  try {
195
- // Check if it's a known binary extension
195
+ // Check if it's a known binary extension.
196
196
  /* v8 ignore next */ if (isBinaryFileExtension(filePath)) {
197
197
  return null;
198
198
  }
@@ -218,7 +218,7 @@ export class Search {
218
218
  } else {
219
219
  logger.log(content);
220
220
  }
221
- // adding a new line after each file content except the last one
221
+ // adding a new line after each file content except the last one.
222
222
  if (node !== fileNodes[fileNodes.length - 1]) {
223
223
  if (returnResults) {
224
224
  loggerInMemory.log("");
@@ -274,12 +274,11 @@ export class Search {
274
274
  async postProcessResults(returnResults) {
275
275
  if (this.grep) {
276
276
  /**
277
- * Resetting the number of files found, since we want to
278
- * show how many matched the grep, not how many matched the
279
- * pattern (in the file name).
277
+ * Resetting the number of files found, since we want to show how many
278
+ * matched the grep, not how many matched the pattern (in the file name).
280
279
  */ this.totalFileFound = 0;
281
280
  }
282
- // If printMode is enabled, handle file content printing and return
281
+ // If printMode is enabled, handle file content printing and return.
283
282
  if (this.printMode && [
284
283
  "simple",
285
284
  "xml"
package/dist/core.js.map CHANGED
@@ -1 +1 @@
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":"AAAA,SAASA,QAAQ,EAAWC,IAAI,EAAEC,QAAQ,QAAQ,YAAY;AAC9D,SAASC,SAAS,QAAQ,YAAY;AACtC,SAASC,MAAM,QAAQ,mBAAmB;AAC1C,SAASC,WAAW,QAAQ,iBAAiB;AAC7C,OAAOC,QAAQ,WAAW;AAC1B,OAAOC,WAAW,QAAQ;AAC1B,OAAOC,UAAU,OAAO;AAExB,SAASC,gBAAgB,QAAQ,wBAAwB;AACzD,SAAoBC,iBAAiB,QAAkB,iBAAiB;AACxE,SACCC,aAAa,EACbC,kBAAkB,EAClBC,aAAa,EACbC,YAAY,EACZC,kBAAkB,EAClBC,gBAAgB,EAChBC,qBAAqB,EACrBC,eAAe,EACfC,gBAAgB,EAChBC,aAAa,QACP,iBAAiB;AAExB,MAAMC,aAAalB,UAAUG,GAAGgB,KAAK;AACrC,MAAMC,eAAepB,UAAUG,GAAGkB,OAAO;AACzC,MAAMC,gBAAgBtB,UAAUG,GAAGoB,QAAQ;AAC3C,MAAMC,OAAO,IAAItB;AACjB,MAAMuB,SAAS,IAAIxB,OAAO;IACzByB,QAAQC,QAAQC,GAAG,CAACC,QAAQ,KAAK;AAClC;AACA,MAAMC,iBAAiB,IAAI7B,OAAO;IACjC8B,UAAU;AACX;AAEA,OAAO,MAAMC;IACZN,OAAiB;IACjBO,QAAiB;IACjBC,6BAAuC;IACvCC,mBAA6B;IAC7BC,aAAuB;IACvBC,KAAc;IACdC,UAAkB;IAClBC,KAAc;IACdC,UAAmB;IACnBC,cAAuB;IACvBC,gBAAyB;IACzBC,eAAwB;IACxBC,iBAA0B;IAC1BC,KAAc;IACdC,iBAA4B;IAC5BC,YAAuB;IACvBC,cAAyB;IACzBC,UAAmB;IACnBC,iBAAmC;IACnCC,gBAA0B;IAC1BC,aAAuB;IAEvBC,YAAY,EACX3B,MAAM,EACNO,OAAO,EACPqB,GAAG,EACHjB,IAAI,EACJkB,UAAU,EACVC,KAAK,EACLjB,IAAI,EACJkB,OAAO,EACPC,KAAK,EACLb,IAAI,EACJc,eAAe,EACfC,UAAU,EACVC,YAAY,EACZZ,SAAS,EACTE,eAAe,EACfC,YAAY,EAkBZ,CAAE;QACF,IAAI,CAACb,IAAI,GAAGA;QACZ,IAAI,CAACC,SAAS,GAAGiB,UACd,IAAIK,OAAOL,SAASF,aAAa,MAAM,MACvCQ;QACH,IAAI,CAAClB,IAAI,GAAGA,QAAQrC;QACpB,IAAI,CAACkB,MAAM,GAAGA;QACdtB,MAAM4D,OAAO,GAAG,CAACtC;QACjB,IAAI,CAACS,kBAAkB,GAAG,CAACqB;QAC3B,IAAI,CAACpB,YAAY,GAAGsB;QACpB,IAAI,CAACxB,4BAA4B,GAAGoB;QACpC,IAAI,CAAChB,SAAS,GAAG,EAAE;QACnB,IAAI,CAACI,eAAe,GAAG;QACvB,IAAI,CAACE,gBAAgB,GAAG;QACxB,IAAI,CAACH,aAAa,GAAG;QACrB,IAAI,CAACE,cAAc,GAAG;QACtB,IAAI,CAACV,OAAO,GAAGA,UAAUA,QAAQgC,IAAI,KAAKF;QAC1C,IAAI,CAACjB,gBAAgB,GACpB,AAACa,mBAAmBA,gBAAgBO,GAAG,CAAC,CAACC,MAAQA,IAAIC,WAAW,OAChE,EAAE;QACH,IAAI,CAACrB,WAAW,GAAGa,cAAc,EAAE;QACnC,IAAI,CAACZ,aAAa,GAAGa,gBAAgB,EAAE;QACvC,IAAI,CAACZ,SAAS,GAAGA;QACjB,IAAI,CAACE,eAAe,GAAGA;QACvB,IAAI,CAACC,YAAY,GAAGA;QACpB,IAAI,CAACF,gBAAgB,GAAG,IAAI5C;QAC5B,IAAI;YACH,IAAI,CAAC+B,IAAI,GAAGA,OAAO,IAAIyB,OAAOzB,MAAMkB,aAAa,OAAO,OAAOQ;QAChE,EAAE,OAAOM,OAAO;YACf5C,OAAO4C,KAAK,CAACA;YACb1C,QAAQ2C,IAAI,CAAC;QACd;IACD;IAEAC,mBAAmBC,SAAiB,EAAE;QACrC,MAAMC,aAAa5E,SAAS2E;QAC5B,oCAAoC;QACpC,IAAI,IAAI,CAACxB,aAAa,IAAI,IAAI,CAACA,aAAa,CAAC0B,QAAQ,CAACD,aAAa;YAClE,OAAO;QACR;QACA,OAAO;IACR;IAEAE,iBAAiBC,QAAgB,EAAE;QAClC,qDAAqD;QACrD,MAAMC,WAAWhF,SAAS+E;QAC1B,IAAI,IAAI,CAAC7B,WAAW,IAAI,IAAI,CAACA,WAAW,CAAC2B,QAAQ,CAACG,WAAW;YAC5D,OAAO;QACR;QAEA,gDAAgD;QAChD,IAAI,CAAC,IAAI,CAAC/B,gBAAgB,IAAI,IAAI,CAACA,gBAAgB,CAACgC,MAAM,KAAK,GAAG;YACjE,OAAO;QACR;QAEA,MAAMC,YAAYlE,iBAAiB+D;QAEnC,kCAAkC;QAClC,IAAI,IAAI,CAAC9B,gBAAgB,CAAC4B,QAAQ,CAACK,YAAY;YAC9C,OAAO;QACR;QAEA,2CAA2C;QAC3C,KAAK,MAAMtB,WAAW,IAAI,CAACX,gBAAgB,CAAE;YAC5C,yCAAyC;YACzC,IAAI,CAACW,QAAQiB,QAAQ,CAAC,MAAM;gBAC3B;YACD;YAEA,8CAA8C;YAC9C,IAAIG,SAAST,WAAW,GAAGY,QAAQ,CAAC,CAAC,CAAC,EAAEvB,SAAS,GAAG;gBACnD,OAAO;YACR;QACD;QAEA,OAAO;IACR;IAEAwB,aAAaC,KAAwB,EAAE;QACtC,IAAI,IAAI,CAAChD,4BAA4B,EAAE;YACtC,OAAO;QACR;QACA,OAAOgD,KAAK,CAAC,EAAE,KAAK;IACrB;IAEA,MAAMC,MAAMC,gBAAgB,KAAK,EAAE;QAClC,IAAI,IAAI,CAAChD,YAAY,EAAE;YACtBZ,KAAK2D,KAAK;QACX;QACA,MAAM,IAAI,CAACE,cAAc,CAAC;YAAC,IAAI,CAAC9C,IAAI;SAAC;QACrC,MAAM+C,UAAU,MAAM,IAAI,CAACC,kBAAkB,CAACH;QAE9C,IAAI,IAAI,CAAChD,YAAY,EAAE;YACtBZ,KAAKgE,IAAI;YACTzE,gBAAgB;gBACf0E,UAAUjE,KAAK8D,OAAO,CAACG,QAAQ;gBAC/BpD,MAAM,IAAI,CAACA,IAAI;gBACfoB,SAAS,IAAI,CAACjB,SAAS;gBACvBE,iBAAiB,IAAI,CAACA,eAAe;gBACrCgD,gBAAgB,IAAI,CAACjD,aAAa;gBAClCG,kBAAkB,IAAI,CAACA,gBAAgB;gBACvC+C,iBAAiB,IAAI,CAAChD,cAAc;gBACpCE,MAAM,IAAI,CAACA,IAAI;YAChB;QACD;QACA,OAAOuC,gBAAgBE,UAAUvB;IAClC;IAEA,MAAMsB,eAAeO,KAAe,EAAE;QACrC,KAAK,MAAMC,QAAQD,MAAO;YACzB,IAAIE,QACHC,OACAC,WACAC;YACD,IAAI;gBACHA,OAAO,MAAM/E,WAAW2E;YACzB,EAAE,OAAM;YACP,mDAAmD;YACpD;YAEA,MAAMK,cAAcD,QAAQA,KAAKC,WAAW;YAC5C,MAAMC,SAASF,QAAQA,KAAKE,MAAM;YAElC,gDAAgD;YAChD,IAAI,MAAM,IAAI,CAACC,uBAAuB,CAACP,MAAMK,cAAc;gBAC1D;YACD;YAEA,IAAIA,eAAe,CAAC,IAAI,CAAC3B,kBAAkB,CAACsB,OAAO;gBAClD,IAAI,CAACnD,eAAe;gBAEpBoD,SAASnF,aAAa,IAAI,CAAC6B,SAAS,EAAEqD;gBACtC,IAAIC,QAAQ;oBACX,IAAI,CAACrD,aAAa;oBAClB,IAAI,CAACH,SAAS,CAAC+D,IAAI,CAAC;wBACnBpE,SAAS,IAAI,CAACA,OAAO;wBACrBqE,OAAOR;wBACPS,MAAMV;wBACNI;wBACApD,MAAMpC;oBACP;gBACD;gBAEA,IAAI;oBACHsF,QAAQ,MAAM3E,aAAayE;oBAC3B,MAAM,IAAI,CAACR,cAAc,CACxBU,MACES,MAAM,CAAC,CAACC,UAAY,IAAI,CAACxB,YAAY,CAACwB,UACtCvC,GAAG,CAAC,SAAUwC,IAAI;wBAClB,OAAO5G,KAAK+F,MAAMa;oBACnB;gBAEH,EAAE,OAAM;gBACP,qBAAqB;gBACtB;YACD,OAAO,IAAIP,QAAQ;gBAClB,qCAAqC;gBACrC,IAAI,IAAI,CAACxB,gBAAgB,CAACkB,OAAO;oBAChC;gBACD;gBAEA,IAAI,CAACjD,gBAAgB;gBACrBoD,YAAYnG,SAASgG;gBACrB,MAAMc,gBAAgBhG,aAAa,IAAI,CAAC6B,SAAS,EAAEwD;gBACnD,IAAIW,eAAe;oBAClB,IAAI,CAAChE,cAAc;oBACnB,IAAI,CAACL,SAAS,CAAC+D,IAAI,CAAC;wBACnBpE,SAAS,IAAI,CAACA,OAAO;wBACrBqE,OAAOK,aAAa,CAAC,EAAE;wBACvBJ,MAAMV;wBACNI;wBACApD,MAAMnC;oBACP;gBACD;YACD;QACD;IACD;IAEA,MAAMkG,gBAAgBhC,QAAgB,EAAmB;QACxD,IAAI;YACH,yCAAyC;YACzC,kBAAkB,GAClB,IAAI9D,sBAAsB8D,WAAW;gBACpC,OAAO;YACR;YACA,MAAMiC,UAAU,MAAMvF,cAAcsD,UAAU;YAC9C,OAAO,IAAI,CAACxB,YAAY,GACrB,MAAM7C,kBAAkBqE,UAAUiC,WAClCA;QACJ,EAAE,OAAOC,QAAQ;YAChB,kBAAkB,GAClB,OAAO;QACR;IACD;IAEA,MAAMC,kBAAkB3B,aAAsB,EAAE;QAC/C,MAAM4B,YAAY,IAAI,CAAC1E,SAAS,CAACkE,MAAM,CACtC,CAACX,OAASA,KAAKhD,IAAI,KAAKnC;QAGzB,IAAI,IAAI,CAACuC,SAAS,KAAK,UAAU;YAChC,KAAK,MAAM4C,QAAQmB,UAAW;gBAC7B,MAAMC,eAAelH,SAAS,IAAI,CAACwC,IAAI,EAAEsD,KAAKU,IAAI;gBAClD,IAAInB,eAAe;oBAClBtD,eAAeoF,GAAG,CAAC,CAAC,OAAO,EAAED,aAAa,KAAK,CAAC;gBACjD,OAAO;oBACNxF,OAAOyF,GAAG,CAAC,CAAC,OAAO,EAAED,aAAa,KAAK,CAAC;gBACzC;gBACA,MAAMJ,UAAU,MAAM,IAAI,CAACD,eAAe,CAACf,KAAKU,IAAI;gBACpD,IAAInB,eAAe;oBAClBtD,eAAeoF,GAAG,CAACL;gBACpB,OAAO;oBACNpF,OAAOyF,GAAG,CAACL;gBACZ;gBACA,gEAAgE;gBAChE,IAAIhB,SAASmB,SAAS,CAACA,UAAUlC,MAAM,GAAG,EAAE,EAAE;oBAC7C,IAAIM,eAAe;wBAClBtD,eAAeoF,GAAG,CAAC;oBACpB,OAAO;wBACNzF,OAAOyF,GAAG,CAAC;oBACZ;gBACD;YACD;QACD,OAAO,IAAI,IAAI,CAACjE,SAAS,KAAK,OAAO;YACpC,IAAImC,eAAe;gBAClBtD,eAAeoF,GAAG,CAAC;YACpB,OAAO;gBACNzF,OAAOyF,GAAG,CAAC;YACZ;YAEA,IAAK,IAAIC,IAAI,GAAGA,IAAIH,UAAUlC,MAAM,EAAEqC,IAAK;gBAC1C,MAAMtB,OAAOmB,SAAS,CAACG,EAAE;gBACzB,MAAMF,eAAelH,SAAS,IAAI,CAACwC,IAAI,EAAEsD,KAAKU,IAAI;gBAClD,MAAMM,UAAU,MAAM,IAAI,CAACD,eAAe,CAACf,KAAKU,IAAI;gBAEpD,IAAInB,eAAe;oBAClB,IAAIyB,SAAS;wBACZ/E,eAAeoF,GAAG,CAAC,CAAC,iBAAiB,EAAEC,IAAI,EAAE,EAAE,CAAC;wBAChDrF,eAAeoF,GAAG,CAAC,CAAC,UAAU,EAAED,aAAa,SAAS,CAAC;wBACvDnF,eAAeoF,GAAG,CAAC;wBACnBpF,eAAeoF,GAAG,CAACL;wBACnB/E,eAAeoF,GAAG,CAAC;wBACnBpF,eAAeoF,GAAG,CAAC;oBACpB;gBACD,OAAO,IAAIL,SAAS;oBACnBpF,OAAOyF,GAAG,CAAC,CAAC,iBAAiB,EAAEC,IAAI,EAAE,EAAE,CAAC;oBACxC1F,OAAOyF,GAAG,CAAC,CAAC,UAAU,EAAED,aAAa,SAAS,CAAC;oBAC/CxF,OAAOyF,GAAG,CAAC;oBACXzF,OAAOyF,GAAG,CAACL;oBACXpF,OAAOyF,GAAG,CAAC;oBACXzF,OAAOyF,GAAG,CAAC;gBACZ;YACD;YAEA,IAAI9B,eAAe;gBAClBtD,eAAeoF,GAAG,CAAC;YACpB,OAAO;gBACNzF,OAAOyF,GAAG,CAAC;YACZ;QACD;QACA,MAAM5B,UAAUF,gBAAgBtD,eAAesF,aAAa,KAAKrD;QACjEjC,eAAeuF,eAAe;QAC9B,OAAO/B;IACR;IAEA,MAAMc,wBACLkB,QAAgB,EAChBpB,WAAoB,EACD;QACnB,IAAI,IAAI,CAAC/C,eAAe,EAAE;YACzB,OAAO;QACR;QACA,OAAO,IAAI,CAACD,gBAAgB,CAACqE,SAAS,CAACD,UAAUpB;IAClD;IAEA,MAAMX,mBAAmBH,aAAsB,EAAE;QAChD,IAAI,IAAI,CAAC/C,IAAI,EAAE;YACd;;;;IAIC,GACD,IAAI,CAACM,cAAc,GAAG;QACvB;QAEA,mEAAmE;QACnE,IAAI,IAAI,CAACM,SAAS,IAAI;YAAC;YAAU;SAAM,CAACyB,QAAQ,CAAC,IAAI,CAACzB,SAAS,GAAG;YACjE,OAAO,MAAM,IAAI,CAAC8D,iBAAiB,CAAC3B;QACrC;QAEA,kBAAkB,GAClB,IAAI,CAAC,IAAI,CAAC1D,MAAM,EAAE;YACjBD,OAAOyF,GAAG;QACX;QAEA,KAAK,MAAMrB,QAAQ,IAAI,CAACvD,SAAS,CAAE;YAClC,IACC,AAAC,IAAI,CAACO,IAAI,KAAKnC,iBAAiBmF,KAAKhD,IAAI,KAAKnC,iBAC7C,IAAI,CAACmC,IAAI,KAAKpC,sBACdoF,KAAKhD,IAAI,KAAKpC,sBACf,IAAI,CAACoC,IAAI,KAAKrC,eACb;gBACD,IAAIgH,OAMC;oBACHC,OAAO;oBACPC,OAAO;oBACPC,MAAM;oBACNC,OAAO;oBACPC,MAAM;gBACP,GACAtB,MACAuB,YAAoB;gBAErB,kBAAkB,GAClB,IAAI,IAAI,CAAC3F,kBAAkB,EAAE;oBAC5BqF,OAAO,MAAM5G,mBAAmBiF,KAAKI,IAAI,EAAEJ,KAAKhD,IAAI;oBACpDiF,YAAY;gBACb;gBAEA,MAAMC,QAAQlC,KAAKhD,IAAI,KAAKnC,gBAAgBN,MAAM4H,IAAI,GAAG5H,MAAM6H,IAAI;gBACnE1B,OAAOxG,SAAS,IAAI,CAACwC,IAAI,EAAEsD,KAAKU,IAAI;gBAEpC,IAAIV,KAAKS,KAAK,EAAE;oBACf,MAAM4B,WAAWC,OAAOtC,KAAKS,KAAK,GAAG,2BAA2B;oBAChE,MAAMA,QAAQ,IAAIxC,OAAOoE,UAAU;oBACnC,MAAME,mBAAmBhI,MAAMiI,KAAK,GAAGC,QAAQ,CAACJ;oBAChD3B,OAAOwB,MAAMxB,KAAKgC,OAAO,CAACjC,OAAO8B;gBAClC,OAAO;oBACN7B,OAAOwB,MAAMxB;gBACd;gBAEA,IAAI,IAAI,CAAClE,IAAI,IAAIwD,KAAKhD,IAAI,KAAKnC,eAAe;oBAC7C,MAAM,EAAE8H,kBAAkB,EAAElD,OAAO,EAAE,GAAG,MAAMrE,cAC7C4E,KAAKU,IAAI,EACT,IAAI,CAAClE,IAAI;oBAEV,kBAAkB,GAClB,IAAImG,oBAAoB;wBACvB,IAAI,CAAC7F,cAAc;wBACnB,MAAM8F,cAAcpI,KAAK,cAAcmI;wBAEvC/G,OAAOyF,GAAG,CACT,CAAC,GAAG,EAAEY,UAAU,EAAE,EAAEA,UAAU,EAAE,EAAEA,UAAU,EAAE,EAAEA,UAAU,EAAE,CAAC,EAC7DN,KAAKG,IAAI,CAAC1D,IAAI,IACduD,KAAKI,KAAK,CAAC3D,IAAI,IACfuD,KAAKK,IAAI,CAAC5D,IAAI,IACduD,KAAKE,KAAK,EACVnB,MACA,CAAC,CAAC,EAAEnG,MAAMsI,KAAK,CAACF,oBAAoB,CAAC,EAAEC,YAAY,CAAC,CAAC;wBAEtDhH,OAAOyF,GAAG,CAAC,GAAG5B,QAAQxF,IAAI,CAAC,MAAM,EAAE,CAAC;oBACrC;gBACD,OAAO;oBACN,kBAAkB,GAClB,IAAI,CAAC,IAAI,CAACuC,IAAI,EAAE;wBACfZ,OAAOyF,GAAG,CACT,CAAC,GAAG,EAAEY,UAAU,EAAE,EAAEA,UAAU,EAAE,EAAEA,UAAU,EAAE,EAAEA,UAAU,EAAE,CAAC,EAC7DN,KAAKG,IAAI,CAAC1D,IAAI,IACduD,KAAKI,KAAK,CAAC3D,IAAI,IACfuD,KAAKK,IAAI,CAAC5D,IAAI,IACduD,KAAKE,KAAK,EACVnB;wBAED,IAAIV,KAAK5D,OAAO,EAAE;4BACjB,MAAMjB,iBAAiB6E,KAAKU,IAAI,EAAEV,KAAK5D,OAAO;wBAC/C;oBACD;gBACD;YACD;QACD;IACD;AACD"}
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\tcheckPattern,\n\tformatLongListings,\n\tgetFileExtension,\n\tisBinaryFileExtension,\n\tprintStatistics,\n\trunCommandOnNode,\n\trunGrepOnNode,\n\tSTR_TYPE_BOTH,\n\tSTR_TYPE_DIRECTORY,\n\tSTR_TYPE_FILE,\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 show how many\n\t\t\t * matched the grep, not how many matched the 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","checkPattern","formatLongListings","getFileExtension","isBinaryFileExtension","printStatistics","runCommandOnNode","runGrepOnNode","STR_TYPE_BOTH","STR_TYPE_DIRECTORY","STR_TYPE_FILE","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","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,43 +1,53 @@
1
1
  /**
2
- * Represents a pattern from a .gitignore file
2
+ * Represents a pattern from a .gitignore file.
3
3
  */
4
4
  interface GitIgnorePattern {
5
- /** The actual pattern string */
5
+ /**
6
+ * The actual pattern string.
7
+ */
6
8
  pattern: string;
7
- /** Whether this is a negated pattern (starts with !) */
9
+ /**
10
+ * Whether this is a negated pattern (starts with !)
11
+ */
8
12
  isNegated: boolean;
9
- /** Whether this pattern is specific to directories (ends with /) */
13
+ /**
14
+ * Whether this pattern is specific to directories (ends with /).
15
+ */
10
16
  isDirectory: boolean;
11
17
  }
12
18
  /**
13
- * Handles parsing and matching of .gitignore patterns
19
+ * Handles parsing and matching of .gitignore patterns.
14
20
  */
15
21
  export declare class GitIgnoreHandler {
16
- /** Map to store ignore patterns by directory */
22
+ /**
23
+ * Map to store ignore patterns by directory.
24
+ */
17
25
  private ignorePatterns;
18
- /** Cache to store already processed paths */
26
+ /**
27
+ * Cache to store already processed paths.
28
+ */
19
29
  private ignoredPathsCache;
20
30
  constructor();
21
31
  /**
22
- * Parse a .gitignore file and return the patterns
32
+ * Parse a .gitignore file and return the patterns.
23
33
  * @param filePath Path to the .gitignore file
24
34
  * @returns Array of parsed patterns
25
35
  */
26
36
  parseGitIgnoreFile(filePath: string): Promise<GitIgnorePattern[]>;
27
37
  /**
28
- * Load .gitignore files from a directory and its parents
38
+ * Load .gitignore files from a directory and its parents.
29
39
  * @param directory Directory to load .gitignore from
30
40
  */
31
41
  loadGitIgnorePatterns(directory: string): Promise<void>;
32
42
  /**
33
- * Check if a path should be ignored based on .gitignore rules
43
+ * Check if a path should be ignored based on .gitignore rules.
34
44
  * @param path Path to check
35
45
  * @param isDirectory Whether the path is a directory
36
46
  * @returns True if the path should be ignored, false otherwise
37
47
  */
38
48
  isIgnored(path: string, isDirectory?: boolean): Promise<boolean>;
39
49
  /**
40
- * Clear the cache of ignored paths
50
+ * Clear the cache of ignored paths.
41
51
  */
42
52
  clearCache(): void;
43
53
  }
@@ -4,33 +4,37 @@ import fs from "fs-extra";
4
4
  import micromatch from "micromatch";
5
5
  const readFileAsync = promisify(fs.readFile);
6
6
  /**
7
- * Handles parsing and matching of .gitignore patterns
7
+ * Handles parsing and matching of .gitignore patterns.
8
8
  */ export class GitIgnoreHandler {
9
- /** Map to store ignore patterns by directory */ ignorePatterns;
10
- /** Cache to store already processed paths */ ignoredPathsCache;
9
+ /**
10
+ * Map to store ignore patterns by directory.
11
+ */ ignorePatterns;
12
+ /**
13
+ * Cache to store already processed paths.
14
+ */ ignoredPathsCache;
11
15
  constructor(){
12
16
  this.ignorePatterns = new Map();
13
17
  this.ignoredPathsCache = new Map();
14
18
  }
15
19
  /**
16
- * Parse a .gitignore file and return the patterns
20
+ * Parse a .gitignore file and return the patterns.
17
21
  * @param filePath Path to the .gitignore file
18
22
  * @returns Array of parsed patterns
19
23
  */ async parseGitIgnoreFile(filePath) {
20
24
  try {
21
25
  const content = await readFileAsync(filePath, "utf8");
22
26
  return content.split("\n").filter((line)=>{
23
- // Remove comments and empty lines
27
+ // Remove comments and empty lines.
24
28
  const trimmedLine = line.trim();
25
29
  return trimmedLine && !trimmedLine.startsWith("#");
26
30
  }).map((pattern)=>{
27
31
  // Handle negated patterns (those starting with !)
28
32
  const isNegated = pattern.startsWith("!");
29
- // Remove leading ! for negated patterns
33
+ // Remove leading ! for negated patterns.
30
34
  const cleanPattern = isNegated ? pattern.slice(1) : pattern;
31
- // Handle directory-specific patterns (those ending with /)
35
+ // Handle directory-specific patterns (those ending with /).
32
36
  const isDirectory = cleanPattern.endsWith("/");
33
- // Remove trailing / for directory patterns
37
+ // Remove trailing / for directory patterns.
34
38
  const finalPattern = isDirectory ? cleanPattern.slice(0, -1) : cleanPattern;
35
39
  return {
36
40
  pattern: finalPattern,
@@ -39,78 +43,78 @@ const readFileAsync = promisify(fs.readFile);
39
43
  };
40
44
  });
41
45
  } catch (_error) {
42
- // If file doesn't exist or can't be read, return empty array
46
+ // If file doesn't exist or can't be read, return empty array.
43
47
  return [];
44
48
  }
45
49
  }
46
50
  /**
47
- * Load .gitignore files from a directory and its parents
51
+ * Load .gitignore files from a directory and its parents.
48
52
  * @param directory Directory to load .gitignore from
49
53
  */ async loadGitIgnorePatterns(directory) {
50
- // If we've already loaded patterns for this directory, return
54
+ // If we've already loaded patterns for this directory, return.
51
55
  if (this.ignorePatterns.has(directory)) {
52
56
  return;
53
57
  }
54
- // Load .gitignore from current directory
58
+ // Load .gitignore from current directory.
55
59
  const gitIgnorePath = join(directory, ".gitignore");
56
60
  const patterns = await this.parseGitIgnoreFile(gitIgnorePath);
57
61
  this.ignorePatterns.set(directory, patterns);
58
- // Load patterns from parent directories (if not at root)
62
+ // Load patterns from parent directories (if not at root).
59
63
  const parentDir = dirname(directory);
60
64
  if (parentDir !== directory) {
61
65
  await this.loadGitIgnorePatterns(parentDir);
62
66
  }
63
67
  }
64
68
  /**
65
- * Check if a path should be ignored based on .gitignore rules
69
+ * Check if a path should be ignored based on .gitignore rules.
66
70
  * @param path Path to check
67
71
  * @param isDirectory Whether the path is a directory
68
72
  * @returns True if the path should be ignored, false otherwise
69
73
  */ async isIgnored(path, isDirectory = false) {
70
- // Check cache first
74
+ // Check cache first.
71
75
  const cacheKey = `${path}:${isDirectory}`;
72
76
  if (this.ignoredPathsCache.has(cacheKey)) {
73
77
  return this.ignoredPathsCache.get(cacheKey);
74
78
  }
75
- // Get the directory containing the path
79
+ // Get the directory containing the path.
76
80
  const directory = isDirectory ? path : dirname(path);
77
- // Load .gitignore patterns if not already loaded
81
+ // Load .gitignore patterns if not already loaded.
78
82
  await this.loadGitIgnorePatterns(directory);
79
- // Get the relative path from the containing directory
83
+ // Get the relative path from the containing directory.
80
84
  const filename = basename(path);
81
- // Start with not ignored
85
+ // Start with not ignored.
82
86
  let ignored = false;
83
- // Check patterns from current directory up to root
87
+ // Check patterns from current directory up to root.
84
88
  let currentDir = directory;
85
89
  while(true){
86
90
  const patterns = this.ignorePatterns.get(currentDir) || [];
87
- // Calculate relative path from this directory to the file
91
+ // Calculate relative path from this directory to the file.
88
92
  const relPath = relative(currentDir, path);
89
93
  for (const { pattern, isNegated, isDirectory: isPatternForDir } of patterns){
90
- // Skip directory-specific patterns if checking a file
94
+ // Skip directory-specific patterns if checking a file.
91
95
  if (isPatternForDir && !isDirectory) {
92
96
  continue;
93
97
  }
94
- // Check if pattern matches
98
+ // Check if pattern matches.
95
99
  const matches = micromatch.isMatch(relPath, pattern) || micromatch.isMatch(filename, pattern);
96
100
  if (matches) {
97
- // Negated patterns override previous ignores
101
+ // Negated patterns override previous ignores.
98
102
  ignored = !isNegated;
99
103
  }
100
104
  }
101
- // Move to parent directory
105
+ // Move to parent directory.
102
106
  const parentDir = dirname(currentDir);
103
107
  if (parentDir === currentDir) {
104
108
  break; // We've reached the root
105
109
  }
106
110
  currentDir = parentDir;
107
111
  }
108
- // Cache the result
112
+ // Cache the result.
109
113
  this.ignoredPathsCache.set(cacheKey, ignored);
110
114
  return ignored;
111
115
  }
112
116
  /**
113
- * Clear the cache of ignored paths
117
+ * Clear the cache of ignored paths.
114
118
  */ clearCache() {
115
119
  this.ignoredPathsCache.clear();
116
120
  }
@@ -1 +1 @@
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":"AAAA,mBAAmB,GACnB,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,EACA,kBAAkB"}
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/**\n\t * The actual pattern string.\n\t */\n\tpattern: string;\n\t/**\n\t * Whether this is a negated pattern (starts with !)\n\t */\n\tisNegated: boolean;\n\t/**\n\t * Whether this pattern is specific to directories (ends with /).\n\t */\n\tisDirectory: boolean;\n}\n\n/**\n * Handles parsing and matching of .gitignore patterns.\n */\nexport class GitIgnoreHandler {\n\t/**\n\t * Map to store ignore patterns by directory.\n\t */\n\tprivate ignorePatterns: Map<string, GitIgnorePattern[]>;\n\t/**\n\t * Cache to store already processed paths.\n\t */\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","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/minifiers.js CHANGED
@@ -2,25 +2,29 @@ import { v4 as uuidv4 } from "uuid";
2
2
  import { getFileExtension } from "./utilities.js";
3
3
  export function minifyImports(content) {
4
4
  return content.replace(/(import\s*\{)([^}]*?)(\}\s*from)/g, (_match, _importStart, importItems, _importEnd)=>{
5
- // Process the items being imported
5
+ // Process the items being imported.
6
6
  const cleanedItems = importItems.split(",").map((item)=>{
7
- // Handle 'type' keyword specifically
7
+ // Handle 'type' keyword specifically.
8
8
  return item.trim().replace(/(\btype\b)\s+/, "$1");
9
9
  }).join(",");
10
10
  return `import {${cleanedItems}} from`;
11
11
  });
12
12
  }
13
13
  export function minifyJs(content) {
14
- // Store template literals and regular expressions to protect them from minification
15
- const tokenPrefix = `__PROTECTED_${uuidv4()}_`;
14
+ /**
15
+ * Store template literals and regular expressions to protect them from
16
+ * minification.
17
+ */ const tokenPrefix = `__PROTECTED_${uuidv4()}_`;
16
18
  const protectedSegments = [];
17
- // Function to create a unique token for each protected segment
19
+ // Function to create a unique token for each protected segment.
18
20
  const createToken = (index)=>`${tokenPrefix}${index}__`;
19
- // Function to protect a segment of code with a custom handler
21
+ // Function to protect a segment of code with a custom handler.
20
22
  const protect = (pattern, handler)=>{
21
23
  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
+ /**
25
+ * If a handler is provided, use it to determine if we should protect this
26
+ * match.
27
+ */ if (handler && !handler(match)) {
24
28
  return ""; // Return empty string for JSDoc comments we don't want to keep
25
29
  }
26
30
  const index = protectedSegments.length;
@@ -28,33 +32,34 @@ export function minifyJs(content) {
28
32
  return createToken(index);
29
33
  });
30
34
  };
31
- // Protect template literals
35
+ // Protect template literals.
32
36
  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
+ /**
38
+ * Protect regular expressions This regex pattern matches JavaScript regular
39
+ * expressions while avoiding division operators.
40
+ */ protect(/(?<![a-zA-Z0-9_$])\/(?![*+?\/])(?:[^\r\n\[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*\])+\/[gimyus]*/g);
41
+ // Protect important JSDoc comments.
37
42
  protect(/\/\*\*[\s\S]*?\*\//g, (match)=>{
38
43
  return match.includes("@param") || match.includes("@returns") || match.includes("@description");
39
44
  });
40
- // Remove comments (both single-line and multi-line)
45
+ // Remove comments (both single-line and multi-line).
41
46
  content = content.replace(/\/\/.*$/gm, ""); // Remove single-line comments
42
47
  content = content.replace(/\/\*[\s\S]*?\*\//g, ""); // Remove multi-line comments
43
- // Compact import statements
48
+ // Compact import statements.
44
49
  content = minifyImports(content);
45
- // Remove extra whitespace
50
+ // Remove extra whitespace.
46
51
  content = content.replace(/^\s+/gm, ""); // Remove leading whitespace
47
52
  content = content.replace(/\s+$/gm, ""); // Remove trailing whitespace
48
53
  content = content.replace(/\s{2,}/g, " "); // Replace multiple spaces with a single space
49
- // Compact newlines ( we protected template literals before)
54
+ // Compact newlines ( we protected template literals before).
50
55
  content = content.replace(/\n+/g, " ");
51
- // Replace semicolon + space with just semicolon
56
+ // Replace semicolon + space with just semicolon.
52
57
  content = content.replace(/;\s+/g, ";");
53
- // Replace colon + space with just colon
58
+ // Replace colon + space with just colon.
54
59
  content = content.replace(/,\s+/g, ",");
55
- // Remove spaces around operators (we protected regex operators before)
60
+ // Remove spaces around operators (we protected regex operators before).
56
61
  content = content.replace(/\s+([+\-*/%=&|<>!?:;,])\s+/g, "$1");
57
- // Handle spaces around parentheses and brackets
62
+ // Handle spaces around parentheses and brackets.
58
63
  content = content.replace(/\(\s+/g, "(");
59
64
  content = content.replace(/\s+\)/g, ")");
60
65
  content = content.replace(/\[\s+/g, "[");
@@ -62,19 +67,20 @@ export function minifyJs(content) {
62
67
  // Handle spaces in all curly braces (for object literals, destructuring, etc.)
63
68
  content = content.replace(/\{\s+/g, "{");
64
69
  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 = "";
70
+ /**
71
+ * Restore protected segments We need to handle nested tokens, so we'll iterate
72
+ * until all tokens are replaced.
73
+ */ let previousContent = "";
68
74
  while(previousContent !== content){
69
75
  previousContent = content;
70
- // Sort indices in descending order to handle nested tokens correctly
76
+ // Sort indices in descending order to handle nested tokens correctly.
71
77
  const indices = Array.from({
72
78
  length: protectedSegments.length
73
79
  }, (_, i)=>i).sort((a, b)=>b - a);
74
80
  for (const index of indices){
75
81
  const token = createToken(index);
76
82
  const segment = protectedSegments[index];
77
- // Use global replacement to catch all instances
83
+ // Use global replacement to catch all instances.
78
84
  const tokenRegex = new RegExp(token.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g");
79
85
  content = content.replace(tokenRegex, ()=>segment);
80
86
  }
@@ -82,9 +88,9 @@ export function minifyJs(content) {
82
88
  return content;
83
89
  }
84
90
  export function minifyCss(content) {
85
- // Remove CSS comments
91
+ // Remove CSS comments.
86
92
  content = content.replace(/\/\*[\s\S]*?\*\//g, "");
87
- // Remove extra whitespace
93
+ // Remove extra whitespace.
88
94
  content = content.replace(/\s+/g, " ");
89
95
  content = content.replace(/\s*{\s*/g, "{");
90
96
  content = content.replace(/\s*}\s*/g, "}");
@@ -1 +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":"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"}
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/**\n\t * Store template literals and regular expressions to protect them from\n\t * minification.\n\t */\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/**\n\t\t\t * If a handler is provided, use it to determine if we should protect this\n\t\t\t * match.\n\t\t\t */\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/**\n\t * Protect regular expressions This regex pattern matches JavaScript regular\n\t * expressions while avoiding division operators.\n\t */\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/**\n\t * Restore protected segments We need to handle nested tokens, so we'll iterate\n\t * until all tokens are replaced.\n\t */\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":"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"}
package/dist/parse.js CHANGED
@@ -1,5 +1,5 @@
1
- /* v8 ignore start */ import { defaultFlags, defaultParameters } from "./defaults.js";
2
- import { parser } from "@node-cli/parser";
1
+ /* v8 ignore start */ import { parser } from "@node-cli/parser";
2
+ import { defaultFlags, defaultParameters } from "./defaults.js";
3
3
  /* v8 ignore start */ export const config = parser({
4
4
  meta: import.meta,
5
5
  examples: [
package/dist/parse.js.map CHANGED
@@ -1 +1 @@
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"}
1
+ {"version":3,"sources":["../src/parse.ts"],"sourcesContent":["/* v8 ignore start */\n\nimport { parser } from \"@node-cli/parser\";\nimport { defaultFlags, defaultParameters } from \"./defaults.js\";\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":["parser","defaultFlags","defaultParameters","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,GAEnB,SAASA,MAAM,QAAQ,mBAAmB;AAC1C,SAASC,YAAY,EAAEC,iBAAiB,QAAQ,gBAAgB;AAuBhE,mBAAmB,GACnB,OAAO,MAAMC,SAAwBH,OAAO;IAC3CI,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,SAASV,aAAaQ,MAAM;YAC5BG,aAAa;YACbC,MAAM;QACP;QACAP,SAAS;YACRI,WAAW;YACXE,aAAa;YACbC,MAAM;QACP;QACAC,KAAK;YACJH,SAASV,aAAaa,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,SAASV,aAAagB,UAAU;YAChCL,aAAa;YACbC,MAAM;QACP;QACAK,SAAS;YACRR,WAAW;YACXE,aAAa;YACbC,MAAM;QACP;QACAM,OAAO;YACNR,SAASV,aAAakB,KAAK;YAC3BP,aAAa;YACbC,MAAM;QACP;QACAO,OAAO;YACNV,WAAW;YACXC,SAASV,aAAamB,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,SAASV,aAAa0B,eAAe;YACrCd,MAAM;QACP;IACD;IACAe,YAAY;QACXC,MAAM;YACLlB,SAAS;YACTC,aAAa;QACd;IACD;IACAkB,OAAO;IACP7B;IACAC;AACD,GAAG,CACH,kBAAkB"}
package/dist/search.js CHANGED
@@ -19,7 +19,7 @@ if (fs.pathExistsSync(customPath)) {
19
19
  if (config.flags.grep) {
20
20
  // forcing simplified display if grep is true.
21
21
  config.flags.short = true;
22
- // And forcing type to files
22
+ // And forcing type to files.
23
23
  config.flags.type = STR_TYPE_FILE;
24
24
  }
25
25
  const search = new Search({
@@ -1 +1 @@
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
+ {"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,6BAA6B;IAC7Bd,OAAOY,KAAK,CAACG,IAAI,GAAGd;AACrB;AAEA,MAAMe,SAAS,IAAIjB,OAAO;IACzB,GAAGC,OAAOY,KAAK;IACfhB,MAAMW;AACP;AAEA,MAAMS,OAAOC,KAAK,IAClB,kBAAkB"}
package/dist/utilities.js CHANGED
@@ -19,7 +19,7 @@ const PERMISSIONS_PREFIX = {
19
19
  [STR_TYPE_FILE]: "-"
20
20
  };
21
21
  const BINARY_EXTENSIONS = [
22
- // Executables and compiled code
22
+ // Executables and compiled code.
23
23
  "exe",
24
24
  "dll",
25
25
  "so",
@@ -27,7 +27,7 @@ const BINARY_EXTENSIONS = [
27
27
  "bin",
28
28
  "obj",
29
29
  "o",
30
- // Compressed files
30
+ // Compressed files.
31
31
  "zip",
32
32
  "tar",
33
33
  "gz",
@@ -35,7 +35,7 @@ const BINARY_EXTENSIONS = [
35
35
  "7z",
36
36
  "jar",
37
37
  "war",
38
- // Media files
38
+ // Media files.
39
39
  "jpg",
40
40
  "jpeg",
41
41
  "png",
@@ -52,7 +52,7 @@ const BINARY_EXTENSIONS = [
52
52
  "flv",
53
53
  "wav",
54
54
  "ogg",
55
- // Document formats
55
+ // Document formats.
56
56
  "pdf",
57
57
  "doc",
58
58
  "docx",
@@ -60,11 +60,11 @@ const BINARY_EXTENSIONS = [
60
60
  "xlsx",
61
61
  "ppt",
62
62
  "pptx",
63
- // Database files
63
+ // Database files.
64
64
  "db",
65
65
  "sqlite",
66
66
  "mdb",
67
- // Other binary formats
67
+ // Other binary formats.
68
68
  "class",
69
69
  "pyc",
70
70
  "pyd",
@@ -150,7 +150,7 @@ export const getOwnerNameFromId = async (uid)=>{
150
150
  ownerNames[uid] = result.stdout;
151
151
  return result.stdout;
152
152
  } catch {
153
- // nothing to declare officer
153
+ // nothing to declare officer.
154
154
  return `${uid}`;
155
155
  }
156
156
  }
@@ -204,7 +204,7 @@ export const runCommandOnNode = async (node, command)=>{
204
204
  logger.log(stdout);
205
205
  }
206
206
  } catch {
207
- // nothing to declare officer
207
+ // nothing to declare officer.
208
208
  }
209
209
  };
210
210
  export const runGrepOnNode = async (node, rePattern)=>{
@@ -234,7 +234,7 @@ export const runGrepOnNode = async (node, rePattern)=>{
234
234
  };
235
235
  export function isBinaryFileExtension(filePath) {
236
236
  const ext = getFileExtension(filePath);
237
- // If there's no extension, assume it's binary
237
+ // If there's no extension, assume it's binary.
238
238
  if (!ext) {
239
239
  return true;
240
240
  }
@@ -1 +1 @@
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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"}
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.1.1",
3
+ "version": "3.1.3",
4
4
  "license": "MIT",
5
5
  "author": "Arno Versini",
6
6
  "description": "Search for files in a directory",
@@ -9,7 +9,8 @@
9
9
  "exports": "./dist/core.js",
10
10
  "bin": "dist/search.js",
11
11
  "files": [
12
- "dist"
12
+ "dist",
13
+ "README.md"
13
14
  ],
14
15
  "node": ">=16",
15
16
  "scripts": {
@@ -18,18 +19,20 @@
18
19
  "build:js": "swc --strip-leading-paths --source-maps --out-dir dist src",
19
20
  "build:types": "tsc",
20
21
  "clean": "rimraf dist types coverage",
22
+ "comments:fix": "comments --merge-line-comments 'src/**/*.ts'",
21
23
  "lint": "biome lint src",
24
+ "lint:fix": "biome check src --write --no-errors-on-unmatched",
22
25
  "test": "vitest run --globals",
23
26
  "test:coverage": "vitest run --coverage --globals",
24
27
  "test:watch": "npm run test -- --watch",
25
28
  "watch": "swc --strip-leading-paths --watch --out-dir dist src"
26
29
  },
27
30
  "dependencies": {
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
- "fs-extra": "11.3.0",
31
+ "@node-cli/logger": "../logger",
32
+ "@node-cli/parser": "../parser",
33
+ "@node-cli/perf": "../perf",
34
+ "@node-cli/run": "../run",
35
+ "fs-extra": "11.3.1",
33
36
  "kleur": "4.1.5",
34
37
  "micromatch": "4.0.8",
35
38
  "plur": "5.1.0",
@@ -40,8 +43,9 @@
40
43
  "access": "public"
41
44
  },
42
45
  "devDependencies": {
46
+ "@node-cli/comments": "0.2.1",
43
47
  "@vitest/coverage-v8": "3.2.4",
44
48
  "vitest": "3.2.4"
45
49
  },
46
- "gitHead": "2cef8f88aa5316a1789caad2bd7327ca908ccb9f"
50
+ "gitHead": "59f5469150f5448e0fd88f855d7a2435065ffab6"
47
51
  }