@ngcompass/scanner 0.1.1-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/index.cjs +4 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +260 -0
- package/dist/index.d.ts +260 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ngcompass
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
'use strict';var promises=require('fs/promises'),p=require('path'),common=require('@ngcompass/common'),tinyglobby=require('tinyglobby'),minimatch=require('minimatch'),I=require('ignore'),child_process=require('child_process'),util=require('util');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var p__default=/*#__PURE__*/_interopDefault(p);var I__default=/*#__PURE__*/_interopDefault(I);var le=["**/*.ts","**/*.html","**/*.scss","**/*.css","**/*.sass","**/*.less"],S=e=>({rootDir:p__default.default.resolve(e.rootDir),include:e.include.length>0?e.include:le,exclude:e.exclude,ignorePatterns:e.ignorePatterns??[],respectGitignore:e.respectGitignore??true,followSymlinks:e.followSymlinks??false,dot:e.dot??false}),se=e=>{let r=[];return e.rootDir&&e.rootDir.trim()!==""||r.push("rootDir cannot be empty"),e.include&&e.include.length!==0||r.push("No include patterns specified (will use defaults)"),r};var F=e=>e.replace(/\\/g,"/"),P=e=>({include:e.include.map(F),ignore:[...e.exclude.map(F),...e.ignorePatterns.map(F)]}),H=e=>!(e.trim()===""||e.includes("***")),ce=e=>{let r=[],t=[];for(let i of e)H(i)?r.push(i):t.push(`Invalid pattern: "${i}"`);return [r,t]};var A=async(e,r,t)=>{try{let i=await tinyglobby.glob([...e.include],{cwd:r,ignore:[...e.ignore],absolute:!0,followSymbolicLinks:t.followSymlinks,onlyFiles:!0,dot:t.dot});return common.Ok({files:i})}catch(i){return common.Err(Error(`Glob execution failed: ${i.message}`))}};var me=async e=>{let r=p__default.default.join(e,".gitignore");try{return await promises.readFile(r,"utf-8")}catch{return common.debug("scanner",`Failed to load .gitignore from ${e}`),null}},pe=e=>{let r=I__default.default().add(e);return (t,i)=>{let o=p__default.default.relative(i,t);return !r.ignores(o)}},M=()=>()=>true;var O=async(e,r)=>{try{let t=new Set;for(let o of(t.add(e),r)){let n=p__default.default.dirname(o);for(;n.startsWith(e)&&n!==p__default.default.dirname(e)&&(t.add(n),n!==e);)n=p__default.default.dirname(n);}let i=[];for(let o of t){let n=await me(o);n&&i.push({dir:o,ig:I__default.default().add(n)});}return i.length===0?common.Ok(M()):common.Ok(o=>{for(let{dir:n,ig:a}of i){let c=p__default.default.relative(n,o).replace(/\\/g,"/");if(!c.startsWith("..")&&!p__default.default.isAbsolute(c)&&a.ignores(c))return !1}return !0})}catch(t){return common.Err(Error(`Failed to load gitignore filters: ${t.message}`))}};var U=e=>Array.from(new Set(e)),ye=(e,r,t)=>e.filter(i=>t(i,r)),J=async(e,r)=>{try{let t=e.files,i=t.length;if(r.respectGitignore){let o=await O(r.rootDir,t);if(!o.ok)return o;t=ye(t,r.rootDir,o.data);}return t=U(t),common.Ok({files:t,filtered:i-t.length})}catch(t){return common.Err(Error(`Filtering failed: ${t.message}`))}},he=(e,r)=>{let t=new Set(r);return e.filter(i=>{let o=i.substring(i.lastIndexOf("."));return t.has(o)})},we=(e,r)=>e.filter(t=>r.test(t)),K=(e,r,t,i)=>e.filter(o=>{let n=p__default.default.relative(i,o).replace(/\\/g,"/");return !(!r.some(a=>minimatch.minimatch(n,a,{dot:true}))||t.some(a=>minimatch.minimatch(n,a,{dot:true})))});var ve=async(e,r)=>{let t=Array(e.length),i=0,o=async()=>{for(;i<e.length;){let n=i++;try{t[n]={status:"fulfilled",value:await e[n]()};}catch(a){t[n]={status:"rejected",reason:a};}}};return await Promise.all(Array.from({length:Math.min(r,e.length)},o)),t},Fe=async e=>{let r=e.map(t=>()=>promises.stat(t));return (await ve(r,128)).reduce((t,i)=>t+(i.status==="fulfilled"?i.value.size:0),0)},D=async(e,r,t=false)=>{let i=e.reduce((a,c)=>{let f=p__default.default.extname(c)||".no-extension",g=a.get(f)??0;return a.set(f,g+1),a},new Map),o=await Fe(e),n=performance.now()-r;return {totalFiles:e.length,byExtension:i,totalSize:o,scanTime:n,cacheHit:t}};var z=util.promisify(child_process.exec),_=async e=>{try{return await z("git rev-parse --is-inside-work-tree",{cwd:e}),!0}catch{return false}},q=async e=>new Promise(r=>{try{let t=child_process.spawn("git",["ls-files","-c","-o","--exclude-standard"],{cwd:e}),i=[];t.stdout.setEncoding("utf8"),t.stdout.on("data",o=>{i.push(o);}),t.on("close",o=>{if(o!==0){common.debug("scanner",`git ls-files exited with code ${o}`),r([]);return}let n=i.join("").split(`
|
|
2
|
+
`).filter(a=>a.trim().length>0).map(a=>p__default.default.resolve(e,a));r(n);}),t.on("error",o=>{common.debug("scanner",`Git discovery failed: ${o.message}`),r([]);});}catch(t){common.debug("scanner",`Git discovery failed: ${t.message}`),r([]);}}),Q=async e=>{try{let{stdout:r}=await z("git rev-parse HEAD",{cwd:e});try{let{stdout:t}=await z("git rev-parse --show-toplevel",{cwd:e}),i=p__default.default.join(t.trim(),".git","index"),o=await promises.stat(i);return `${r.trim()}-${o.mtime.getTime()}`}catch{return r.trim()}}catch(r){return common.debug("scanner",`Failed to get repo fingerprint: ${r instanceof Error?r.message:String(r)}`),""}},X=async e=>{try{let r=await promises.readdir(e,{withFileTypes:!0}),t=await Promise.allSettled(r.map(a=>promises.stat(p__default.default.join(e,a.name)))),i=0,o=0,n=0;for(let a of t)a.status==="fulfilled"&&(i+=a.value.size,a.value.mtimeMs>o&&(o=a.value.mtimeMs),n++);return `dir-${r.length}-${n}-${i}-${o}`}catch(r){return common.debug("scanner",`Failed to get directory fingerprint: ${r instanceof Error?r.message:String(r)}`),""}};var Ae=async e=>{var r,t,i,o,n,a,c,f,g;let j;common.time("file-scan");let L=performance.now(),y=e.onProgress??(()=>{});r=e,common.debug("scanner",`Starting file discovery in: ${r.rootDir}`),common.debug("scanner",`Include patterns: ${r.include.join(", ")}`),common.debug("scanner",`Exclude patterns: ${r.exclude.join(", ")}`),y("normalizing",0);let ee=performance.now(),d=S(e),h=P(d),te=performance.now()-ee;if(t=d,i=h,common.debug("scanner",`Normalized rootDir: ${t.rootDir}`),common.debug("scanner",`Expanded to ${i.include.length} include patterns, ${i.ignore.length} ignore patterns`),e.tsConfigPath){let m=await je(e.tsConfigPath,d.rootDir);m&&(o=h,h={include:(n=m).include.length>0?[...o.include,...n.include]:o.include,ignore:n.exclude.length>0?[...o.ignore,...n.exclude]:o.ignore},common.debug("scanner",`tsconfig patterns merged: +${m.include.length} include, +${m.exclude.length} exclude`));}try{await promises.access(d.rootDir);}catch{return common.timeEnd("file-scan"),common.Err(Error(`rootDir does not exist or is not accessible: ${d.rootDir}`))}let G=await _(d.rootDir),b=await ze(d,h,G,e);if(b)return y("complete",b.length),await Te(b,L);y("discovering",0);let re=performance.now(),v=await Oe(d,h,G);if(!v.ok)return Y("Scan",v.error),v;let N=v.data,ie=performance.now()-re;y("filtering",N.length);let oe=performance.now(),x=await J({files:N},d);if(!x.ok)return Y("Filter",x.error),x;let w=x.data.files,ne=performance.now()-oe;a=w.length,c=x.data.filtered,common.debug("scanner",`After filters: ${a} files (${c} filtered out)`),y("calculating-stats",w.length),await Ce(d,h,w,G,e);let B=await D(w,L,false),R=common.timeEnd("file-scan");return f=B,g=R,common.debug("scanner",`Scan complete: ${f.totalFiles} files in ${g.toFixed(1)}ms`),j=Array.from(f.byExtension.entries()).sort(([,m],[,E])=>E-m).slice(0,5).map(([m,E])=>`${m}:${E}`).join(", "),common.debug("scanner",`Breakdown: ${j}`),f.totalFiles===0&&common.debug("scanner","No files found matching patterns. Check your include/exclude configuration."),y("complete",w.length),common.Ok({files:w,stats:B,timestamp:Date.now(),timings:{normalization:te,discovery:ie,filtering:ne,total:R}})};async function Oe(e,r,t){if(t){common.debug("scanner","Git repository detected. Using fast Git discovery...");let o=await q(e.rootDir);if(o.length===0){common.debug("scanner","Git discovery returned 0 files \u2014 this may indicate a git command failure. Falling back to glob-based scanning.");let a=await A(r,e.rootDir,{followSymlinks:e.followSymlinks,dot:e.dot});return a.ok&&common.debug("scanner",`Glob fallback found ${a.data.files.length} files`),a.ok?common.Ok(a.data.files):a}let n=K(o,r.include,r.ignore,e.rootDir);return common.debug("scanner",`Git discovery found ${n.length} files (after glob filtering)`),common.Ok(n)}common.debug("scanner","Not a Git repository. Falling back to standard globbing...");let i=await A(r,e.rootDir,{followSymlinks:e.followSymlinks,dot:e.dot});return i.ok&&common.debug("scanner",`Glob found ${i.data.files.length} files`),i.ok?common.Ok(i.data.files):i}async function Z(e,r,t,i){if(!i.cache)return null;let o=t?await Q(e.rootDir):await X(e.rootDir);return o?i.cache.computeHash([e.rootDir,JSON.stringify(r),o,"v1"].join("|")):null}async function ze(e,r,t,i){let o=await Z(e,r,t,i);if(!o||!i.cache)return null;let n=await i.cache.files.get(o);return n?(common.debug("scanner",`Cache HIT. Loaded ${n.files.length} files.`),n.files):null}async function Ce(e,r,t,i,o){if(!o.cache||t.length===0)return;let n=await Z(e,r,i,o);n&&(await o.cache.files.set(n,t),common.debug("scanner","File list cached."));}async function Te(e,r){let t=await D(e,r,true),i=performance.now()-r;return common.Ok({files:e,stats:t,timestamp:Date.now(),timings:{normalization:0,discovery:i,filtering:0,total:i}})}function Y(e,r){let t=common.timeEnd("file-scan");common.debug("scanner",`${e} failed after ${t.toFixed(1)}ms: ${r.message}`);}async function je(e,r){try{let t=(await promises.readFile(e,"utf-8")).replace(/\/\/[^\n]*/g,"").replace(/\/\*[\s\S]*?\*\//g,""),i=JSON.parse(t),o=p__default.default.dirname(p__default.default.resolve(e)),n=f=>{let g=p__default.default.resolve(o,f);return p__default.default.relative(r,g).replace(/\\/g,"/")},a=[],c=[];return Array.isArray(i.include)&&a.push(...i.include.map(n)),Array.isArray(i.files)&&a.push(...i.files.map(n)),Array.isArray(i.exclude)&&c.push(...i.exclude.map(n)),{include:a,exclude:c}}catch(t){return common.debug("scanner",`Failed to load tsconfig patterns from ${e}: ${t instanceof Error?t.message:String(t)}`),null}}
|
|
3
|
+
Object.defineProperty(exports,"Err",{enumerable:true,get:function(){return common.Err}});Object.defineProperty(exports,"Ok",{enumerable:true,get:function(){return common.Ok}});exports.calculateStats=D;exports.createGitignoreFilter=pe;exports.createPassThroughFilter=M;exports.deduplicateFiles=U;exports.expandPatterns=P;exports.filterByExtension=he;exports.filterByPattern=we;exports.isValidPattern=H;exports.loadAllGitignoreFilters=O;exports.normalizeOptions=S;exports.normalizePattern=F;exports.scan=Ae;exports.validateOptions=se;exports.validatePatterns=ce;//# sourceMappingURL=index.cjs.map
|
|
4
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/normalize.ts","../src/patterns.ts","../src/glob.ts","../src/gitignore.ts","../src/filters.ts","../src/stats.ts","../src/git.ts","../src/scan.ts"],"names":["DEFAULT_INCLUDE","normalizeOptions","options","rootDir","path","resolve","include","length","exclude","ignorePatterns","respectGitignore","followSymlinks","dot","validateOptions","errors","trim","push","normalizePattern","pattern","replace","expandPatterns","map","ignore","isValidPattern","includes","validatePatterns","patterns","valid","executeGlob","files","glob","cwd","absolute","followSymbolicLinks","onlyFiles","Ok","error","Err","Error","message","loadGitignore","gitignorePath","join","readFile","debug","createGitignoreFilter","gitignoreContent","ig","add","file","relative","ignores","createPassThroughFilter","loadAllGitignoreFilters","filePaths","dirsToCheck","Set","filePath","current","dirname","startsWith","dirFilters","dir","content","rel","isAbsolute","deduplicateFiles","Array","from","applyGitignoreFilter","filter","applyFilters","rawFiles","startCount","filterResult","ok","data","filtered","filterByExtension","extensions","extSet","ext","substring","lastIndexOf","has","filterByPattern","test","filterByGlob","relativePath","some","p","minimatch","runWithLimit","tasks","concurrency","results","cursor","worker","i","status","value","reason","Promise","all","Math","min","calculateTotalSize","f","stat","reduce","sum","result","size","calculateStats","startTime","cacheHit","byExtension","extname","count","get","set","Map","totalSize","scanTime","performance","now","totalFiles","execAsync","promisify","exec","isGitRepo","executeGitDiscovery","child","spawn","chunks","stdout","setEncoding","on","chunk","code","split","line","err","getRepoFingerprint","head","root","indexPath","fileStats","mtime","getTime","String","getDirectoryFingerprint","entries","readdir","withFileTypes","statResults","allSettled","entry","name","latestMtime","statSuccessCount","mtimeMs","scan","normalized","tsPatterns","fileCount","filteredCount","stats","breakdown","time","progress","onProgress","t0","normalizationTime","tsConfigPath","loadTsConfigPatterns","access","timeEnd","isGit","cacheResult","tryLoadFromCache","buildCachedResult","t1","discoveryResult","discoverFiles","logAndReturnError","discoveryTime","t2","finalFiles","filteringTime","saveToCache","totalTime","toFixed","sort","a","b","slice","timestamp","Date","timings","normalization","discovery","filtering","total","gitFiles","getCacheKey","cache","fingerprint","computeHash","JSON","stringify","key","cached","phase","stripped","config","parse","configDir","toRootRelative","abs","isArray"],"mappings":"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","file":"index.cjs","sourcesContent":["import e from 'node:path';\nlet DEFAULT_INCLUDE = [\n '**/*.ts',\n '**/*.html',\n '**/*.scss',\n '**/*.css',\n '**/*.sass',\n '**/*.less'\n];\nexport const normalizeOptions = (t)=>({\n rootDir: e.resolve(t.rootDir),\n include: t.include.length > 0 ? t.include : DEFAULT_INCLUDE,\n exclude: t.exclude,\n ignorePatterns: t.ignorePatterns ?? [],\n respectGitignore: t.respectGitignore ?? !0,\n followSymlinks: t.followSymlinks ?? !1,\n dot: t.dot ?? !1\n });\nexport const validateOptions = (e)=>{\n let t = [];\n return e.rootDir && '' !== e.rootDir.trim() || t.push('rootDir cannot be empty'), e.include && 0 !== e.include.length || t.push('No include patterns specified (will use defaults)'), t;\n};\n","export const normalizePattern = (t)=>t.replace(/\\\\/g, '/');\nexport const expandPatterns = (t)=>({\n include: t.include.map(normalizePattern),\n ignore: [\n ...t.exclude.map(normalizePattern),\n ...t.ignorePatterns.map(normalizePattern)\n ]\n });\nexport const isValidPattern = (t)=>!('' === t.trim() || t.includes('***'));\nexport const validatePatterns = (t)=>{\n let e = [], n = [];\n for (let r of t)isValidPattern(r) ? e.push(r) : n.push(`Invalid pattern: \"${r}\"`);\n return [\n e,\n n\n ];\n};\n","import { glob as e } from 'tinyglobby';\nimport { Ok as t, Err as o } from './types.js';\nexport const executeGlob = async (r, l, i)=>{\n try {\n let o = await e([\n ...r.include\n ], {\n cwd: l,\n ignore: [\n ...r.ignore\n ],\n absolute: !0,\n followSymbolicLinks: i.followSymlinks,\n onlyFiles: !0,\n dot: i.dot\n });\n return t({\n files: o\n });\n } catch (e) {\n return o(Error(`Glob execution failed: ${e.message}`));\n }\n};\nexport const patternsLikelyHaveMatches = (e)=>!(0 === e.include.length || e.include.every((e)=>e.startsWith('!')));\n","import r from 'ignore';\nimport { readFile as e } from 'node:fs/promises';\nimport t from 'node:path';\nimport { Ok as o, Err as i } from './types.js';\nimport { debug as a } from '@ngcompass/common';\nexport const loadGitignore = async (r)=>{\n let o = t.join(r, '.gitignore');\n try {\n return await e(o, 'utf-8');\n } catch (e) {\n return a('scanner', `Failed to load .gitignore from ${r}`), null;\n }\n};\nexport const createGitignoreFilter = (e)=>{\n let o = r().add(e);\n return (r, e)=>{\n let i = t.relative(e, r);\n return !o.ignores(i);\n };\n};\nexport const createPassThroughFilter = ()=>()=>!0;\nexport const loadAndCreateGitignoreFilter = async (r)=>{\n try {\n let e = await loadGitignore(r);\n if (!e) return o(createPassThroughFilter());\n let t = createGitignoreFilter(e);\n return o(t);\n } catch (r) {\n return i(Error(`Failed to load .gitignore: ${r.message}`));\n }\n};\nexport const loadAllGitignoreFilters = async (e, a)=>{\n try {\n let i = new Set();\n for (let r of (i.add(e), a)){\n let o = t.dirname(r);\n for(; o.startsWith(e) && o !== t.dirname(e) && (i.add(o), o !== e);)o = t.dirname(o);\n }\n let n = [];\n for (let e of i){\n let t = await loadGitignore(e);\n t && n.push({\n dir: e,\n ig: r().add(t)\n });\n }\n if (0 === n.length) return o(createPassThroughFilter());\n return o((r)=>{\n for (let { dir: e, ig: o } of n){\n let i = t.relative(e, r).replace(/\\\\/g, '/');\n if (!i.startsWith('..') && !t.isAbsolute(i) && o.ignores(i)) return !1;\n }\n return !0;\n });\n } catch (r) {\n return i(Error(`Failed to load gitignore filters: ${r.message}`));\n }\n};\n","import t from 'node:path';\nimport { minimatch as e } from 'minimatch';\nimport { Ok as r, Err as i } from './types.js';\nimport { loadAllGitignoreFilters as o } from './gitignore.js';\nexport const deduplicateFiles = (t)=>Array.from(new Set(t));\nexport const applyGitignoreFilter = (t, e, r)=>t.filter((t)=>r(t, e));\nexport const applyFilters = async (t, e)=>{\n try {\n let i = t.files, l = i.length;\n if (e.respectGitignore) {\n let t = await o(e.rootDir, i);\n if (!t.ok) return t;\n i = applyGitignoreFilter(i, e.rootDir, t.data);\n }\n return i = deduplicateFiles(i), r({\n files: i,\n filtered: l - i.length\n });\n } catch (t) {\n return i(Error(`Filtering failed: ${t.message}`));\n }\n};\nexport const filterByExtension = (t, e)=>{\n let r = new Set(e);\n return t.filter((t)=>{\n let e = t.substring(t.lastIndexOf('.'));\n return r.has(e);\n });\n};\nexport const filterByPattern = (t, e)=>t.filter((t)=>e.test(t));\nexport const filterByGlob = (r, i, o, l)=>r.filter((r)=>{\n let n = t.relative(l, r).replace(/\\\\/g, '/');\n return !(!i.some((t)=>e(n, t, {\n dot: !0\n })) || o.some((t)=>e(n, t, {\n dot: !0\n })));\n });\n","import t from 'node:path';\nimport { stat as e } from 'node:fs/promises';\nlet runWithLimit = async (t, e)=>{\n let a = Array(t.length), l = 0, r = async ()=>{\n for(; l < t.length;){\n let e = l++;\n try {\n a[e] = {\n status: 'fulfilled',\n value: await t[e]()\n };\n } catch (t) {\n a[e] = {\n status: 'rejected',\n reason: t\n };\n }\n }\n };\n return await Promise.all(Array.from({\n length: Math.min(e, t.length)\n }, r)), a;\n}, calculateTotalSize = async (t)=>{\n let a = t.map((t)=>()=>e(t));\n return (await runWithLimit(a, 128)).reduce((t, e)=>t + ('fulfilled' === e.status ? e.value.size : 0), 0);\n};\nexport const calculateStats = async (e, a, l = !1)=>{\n let r = e.reduce((e, a)=>{\n let l = t.extname(a) || '.no-extension', r = e.get(l) ?? 0;\n return e.set(l, r + 1), e;\n }, new Map()), n = await calculateTotalSize(e), i = performance.now() - a;\n return {\n totalFiles: e.length,\n byExtension: r,\n totalSize: n,\n scanTime: i,\n cacheHit: l\n };\n};\n","import { exec as e, spawn as t } from 'node:child_process';\nimport { promisify as r } from 'node:util';\nimport i from 'node:path';\nimport { stat as o, readdir as n } from 'node:fs/promises';\nimport { debug as s } from '@ngcompass/common';\nlet execAsync = r(e);\nexport const isGitRepo = async (e)=>{\n try {\n return await execAsync('git rev-parse --is-inside-work-tree', {\n cwd: e\n }), !0;\n } catch {\n return !1;\n }\n};\nexport const executeGitDiscovery = async (e)=>new Promise((r)=>{\n try {\n let o = t('git', [\n 'ls-files',\n '-c',\n '-o',\n '--exclude-standard'\n ], {\n cwd: e\n }), n = [];\n o.stdout.setEncoding('utf8'), o.stdout.on('data', (e)=>{\n n.push(e);\n }), o.on('close', (t)=>{\n if (0 !== t) {\n s('scanner', `git ls-files exited with code ${t}`), r([]);\n return;\n }\n let o = n.join('').split('\\n').filter((e)=>e.trim().length > 0).map((t)=>i.resolve(e, t));\n r(o);\n }), o.on('error', (e)=>{\n s('scanner', `Git discovery failed: ${e.message}`), r([]);\n });\n } catch (e) {\n s('scanner', `Git discovery failed: ${e.message}`), r([]);\n }\n });\nexport const getRepoFingerprint = async (e)=>{\n try {\n let { stdout: t } = await execAsync('git rev-parse HEAD', {\n cwd: e\n });\n try {\n let { stdout: r } = await execAsync('git rev-parse --show-toplevel', {\n cwd: e\n }), n = i.join(r.trim(), '.git', 'index'), s = await o(n);\n return `${t.trim()}-${s.mtime.getTime()}`;\n } catch {\n return t.trim();\n }\n } catch (e) {\n return s('scanner', `Failed to get repo fingerprint: ${e instanceof Error ? e.message : String(e)}`), '';\n }\n};\nexport const getDirectoryFingerprint = async (e)=>{\n try {\n let t = await n(e, {\n withFileTypes: !0\n }), r = await Promise.allSettled(t.map((t)=>o(i.join(e, t.name)))), s = 0, a = 0, c = 0;\n for (let e of r)'fulfilled' === e.status && (s += e.value.size, e.value.mtimeMs > a && (a = e.value.mtimeMs), c++);\n return `dir-${t.length}-${c}-${s}-${a}`;\n } catch (e) {\n return s('scanner', `Failed to get directory fingerprint: ${e instanceof Error ? e.message : String(e)}`), '';\n }\n};\n","import { access as e, readFile as t } from 'node:fs/promises';\nimport r from 'node:path';\nimport { debug as n, time as i, timeEnd as a } from '@ngcompass/common';\nimport { Ok as o, Err as l } from './types.js';\nimport { normalizeOptions as s } from './normalize.js';\nimport { expandPatterns as c } from './patterns.js';\nimport { executeGlob as f } from './glob.js';\nimport { applyFilters as d, filterByGlob as u } from './filters.js';\nimport { calculateStats as g } from './stats.js';\nimport { isGitRepo as m, executeGitDiscovery as p, getRepoFingerprint as h, getDirectoryFingerprint as y } from './git.js';\nexport const scan = async (t)=>{\n var r, f, u, p, h, y, w, $, v;\n let D;\n i('file-scan');\n let b = performance.now(), k = t.onProgress ?? (()=>void 0);\n r = t, n('scanner', `Starting file discovery in: ${r.rootDir}`), n('scanner', `Include patterns: ${r.include.join(', ')}`), n('scanner', `Exclude patterns: ${r.exclude.join(', ')}`), k('normalizing', 0);\n let x = performance.now(), C = s(t), F = c(C), j = performance.now() - x;\n if (f = C, u = F, n('scanner', `Normalized rootDir: ${f.rootDir}`), n('scanner', `Expanded to ${u.include.length} include patterns, ${u.ignore.length} ignore patterns`), t.tsConfigPath) {\n let e = await loadTsConfigPatterns(t.tsConfigPath, C.rootDir);\n e && (p = F, F = {\n include: (h = e).include.length > 0 ? [\n ...p.include,\n ...h.include\n ] : p.include,\n ignore: h.exclude.length > 0 ? [\n ...p.ignore,\n ...h.exclude\n ] : p.ignore\n }, n('scanner', `tsconfig patterns merged: +${e.include.length} include, +${e.exclude.length} exclude`));\n }\n try {\n await e(C.rootDir);\n } catch {\n return a('file-scan'), l(Error(`rootDir does not exist or is not accessible: ${C.rootDir}`));\n }\n let A = await m(C.rootDir), S = await tryLoadFromCache(C, F, A, t);\n if (S) return k('complete', S.length), await buildCachedResult(S, b);\n k('discovering', 0);\n let E = performance.now(), G = await discoverFiles(C, F, A);\n if (!G.ok) return logAndReturnError('Scan', G.error), G;\n let z = G.data, N = performance.now() - E;\n k('filtering', z.length);\n let P = performance.now(), R = await d({\n files: z\n }, C);\n if (!R.ok) return logAndReturnError('Filter', R.error), R;\n let T = R.data.files, K = performance.now() - P;\n y = T.length, w = R.data.filtered, n('scanner', `After filters: ${y} files (${w} filtered out)`), k('calculating-stats', T.length), await saveToCache(C, F, T, A, t);\n let L = await g(T, b, !1), H = a('file-scan');\n return $ = L, v = H, n('scanner', `Scan complete: ${$.totalFiles} files in ${v.toFixed(1)}ms`), D = Array.from($.byExtension.entries()).sort(([, e], [, t])=>t - e).slice(0, 5).map(([e, t])=>`${e}:${t}`).join(', '), n('scanner', `Breakdown: ${D}`), 0 === $.totalFiles && n('scanner', 'No files found matching patterns. Check your include/exclude configuration.'), k('complete', T.length), o({\n files: T,\n stats: L,\n timestamp: Date.now(),\n timings: {\n normalization: j,\n discovery: N,\n filtering: K,\n total: H\n }\n });\n};\nasync function discoverFiles(e, t, r) {\n if (r) {\n n('scanner', 'Git repository detected. Using fast Git discovery...');\n let r = await p(e.rootDir);\n if (0 === r.length) {\n n('scanner', 'Git discovery returned 0 files — this may indicate a git command failure. Falling back to glob-based scanning.');\n let r = await f(t, e.rootDir, {\n followSymlinks: e.followSymlinks,\n dot: e.dot\n });\n return r.ok && n('scanner', `Glob fallback found ${r.data.files.length} files`), r.ok ? o(r.data.files) : r;\n }\n let i = u(r, t.include, t.ignore, e.rootDir);\n return n('scanner', `Git discovery found ${i.length} files (after glob filtering)`), o(i);\n }\n n('scanner', 'Not a Git repository. Falling back to standard globbing...');\n let i = await f(t, e.rootDir, {\n followSymlinks: e.followSymlinks,\n dot: e.dot\n });\n return i.ok && n('scanner', `Glob found ${i.data.files.length} files`), i.ok ? o(i.data.files) : i;\n}\nasync function getCacheKey(e, t, r, n) {\n if (!n.cache) return null;\n let i = r ? await h(e.rootDir) : await y(e.rootDir);\n return i ? n.cache.computeHash([\n e.rootDir,\n JSON.stringify(t),\n i,\n 'v1'\n ].join('|')) : null;\n}\nasync function tryLoadFromCache(e, t, r, i) {\n let a = await getCacheKey(e, t, r, i);\n if (!a || !i.cache) return null;\n let o = await i.cache.files.get(a);\n return o ? (n('scanner', `Cache HIT. Loaded ${o.files.length} files.`), o.files) : null;\n}\nasync function saveToCache(e, t, r, i, a) {\n if (!a.cache || 0 === r.length) return;\n let o = await getCacheKey(e, t, i, a);\n o && (await a.cache.files.set(o, r), n('scanner', 'File list cached.'));\n}\nasync function buildCachedResult(e, t) {\n let r = await g(e, t, !0), n = performance.now() - t;\n return o({\n files: e,\n stats: r,\n timestamp: Date.now(),\n timings: {\n normalization: 0,\n discovery: n,\n filtering: 0,\n total: n\n }\n });\n}\nfunction logAndReturnError(e, t) {\n let r = a('file-scan');\n n('scanner', `${e} failed after ${r.toFixed(1)}ms: ${t.message}`);\n}\nasync function loadTsConfigPatterns(e, i) {\n try {\n let n = (await t(e, 'utf-8')).replace(/\\/\\/[^\\n]*/g, '').replace(/\\/\\*[\\s\\S]*?\\*\\//g, ''), a = JSON.parse(n), o = r.dirname(r.resolve(e)), l = (e)=>{\n let t = r.resolve(o, e);\n return r.relative(i, t).replace(/\\\\/g, '/');\n }, s = [], c = [];\n return Array.isArray(a.include) && s.push(...a.include.map(l)), Array.isArray(a.files) && s.push(...a.files.map(l)), Array.isArray(a.exclude) && c.push(...a.exclude.map(l)), {\n include: s,\n exclude: c\n };\n } catch (t) {\n return n('scanner', `Failed to load tsconfig patterns from ${e}: ${t instanceof Error ? t.message : String(t)}`), null;\n }\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { CacheContext } from '@ngcompass/cache';
|
|
2
|
+
import { Result } from '@ngcompass/common';
|
|
3
|
+
export { Err, Ok, Result } from '@ngcompass/common';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @fileoverview
|
|
7
|
+
* Definitional contracts and primitive types for the @ngcompass/scanner package.
|
|
8
|
+
*
|
|
9
|
+
* Adheres to functional programming principles by ensuring type immutability
|
|
10
|
+
* and providing explicit structures for configuration, results, and progress reporting.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Represents a value that may be present, null, or undefined.
|
|
15
|
+
*/
|
|
16
|
+
type Option<T> = T | null | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Defines the input configuration options for a scanner operation.
|
|
19
|
+
*/
|
|
20
|
+
interface ScanOptions {
|
|
21
|
+
readonly rootDir: string;
|
|
22
|
+
readonly include: ReadonlyArray<string>;
|
|
23
|
+
readonly exclude: ReadonlyArray<string>;
|
|
24
|
+
readonly ignorePatterns?: ReadonlyArray<string>;
|
|
25
|
+
readonly respectGitignore?: boolean;
|
|
26
|
+
readonly followSymlinks?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Whether to match dotfiles and dot-directories (e.g. `.angular/`, `.nx/`).
|
|
29
|
+
* Corresponds to tinyglobby's `dot` option.
|
|
30
|
+
* @default false
|
|
31
|
+
*/
|
|
32
|
+
readonly dot?: boolean;
|
|
33
|
+
readonly debug?: boolean;
|
|
34
|
+
readonly cache?: CacheContext;
|
|
35
|
+
/**
|
|
36
|
+
* Optional progress callback invoked at key phases of the scan.
|
|
37
|
+
* Receives the current phase name and the file count known at that point.
|
|
38
|
+
*/
|
|
39
|
+
readonly onProgress?: OnProgressCallback;
|
|
40
|
+
/**
|
|
41
|
+
* Optional path to a `tsconfig.json` file. When provided, the scanner
|
|
42
|
+
* narrows discovered files to those the TypeScript compiler would include
|
|
43
|
+
* by merging the tsconfig's `include` / `exclude` / `files` arrays with
|
|
44
|
+
* the scan options.
|
|
45
|
+
*
|
|
46
|
+
* Relative paths inside the tsconfig are resolved against the tsconfig's
|
|
47
|
+
* directory, not `rootDir`.
|
|
48
|
+
*/
|
|
49
|
+
readonly tsConfigPath?: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Represents scanner configuration options after the application of project defaults.
|
|
53
|
+
*/
|
|
54
|
+
interface NormalizedOptions {
|
|
55
|
+
readonly rootDir: string;
|
|
56
|
+
readonly include: ReadonlyArray<string>;
|
|
57
|
+
readonly exclude: ReadonlyArray<string>;
|
|
58
|
+
readonly ignorePatterns: ReadonlyArray<string>;
|
|
59
|
+
readonly respectGitignore: boolean;
|
|
60
|
+
readonly followSymlinks: boolean;
|
|
61
|
+
/** Resolved value of ScanOptions.dot β€” always a boolean after normalization. */
|
|
62
|
+
readonly dot: boolean;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Represents a set of inclusion and exclusion glob patterns.
|
|
66
|
+
*/
|
|
67
|
+
interface ExpandedPatterns {
|
|
68
|
+
readonly include: ReadonlyArray<string>;
|
|
69
|
+
readonly ignore: ReadonlyArray<string>;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Encapsulates statistical metadata for a completed scan operation.
|
|
73
|
+
*/
|
|
74
|
+
interface ScanStatistics {
|
|
75
|
+
readonly totalFiles: number;
|
|
76
|
+
readonly byExtension: ReadonlyMap<string, number>;
|
|
77
|
+
readonly totalSize: number;
|
|
78
|
+
readonly scanTime: number;
|
|
79
|
+
readonly cacheHit: boolean;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Encapsulates high-resolution timing data for various scan phases.
|
|
83
|
+
*/
|
|
84
|
+
interface ScanTimings {
|
|
85
|
+
readonly normalization: number;
|
|
86
|
+
readonly discovery: number;
|
|
87
|
+
readonly filtering: number;
|
|
88
|
+
readonly total: number;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Encapsulates the consolidated results and metadata of a scan operation.
|
|
92
|
+
*/
|
|
93
|
+
interface ScanResult {
|
|
94
|
+
readonly files: ReadonlyArray<string>;
|
|
95
|
+
readonly stats: ScanStatistics;
|
|
96
|
+
readonly timestamp: number;
|
|
97
|
+
readonly timings?: ScanTimings;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Gitignore filter function type
|
|
101
|
+
*/
|
|
102
|
+
type GitignoreFilter = (file: string, rootDir: string) => boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Represents the distinct phases of an active scan operation.
|
|
105
|
+
*/
|
|
106
|
+
type ScanPhase = 'normalizing' | 'discovering' | 'filtering' | 'calculating-stats' | 'complete';
|
|
107
|
+
/**
|
|
108
|
+
* Callback invoked at each scan phase transition with the current file count.
|
|
109
|
+
* Useful for driving progress bars or log output in CLI consumers.
|
|
110
|
+
*
|
|
111
|
+
* @param phase - The phase that just started (or completed for 'complete').
|
|
112
|
+
* @param count - Number of files known at this point in the scan.
|
|
113
|
+
*/
|
|
114
|
+
type OnProgressCallback = (phase: ScanPhase, count: number) => void;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Executes a comprehensive file scan based on the provided configuration.
|
|
118
|
+
*
|
|
119
|
+
* Discovers files using optimized Git utilities or standard globbing, applies
|
|
120
|
+
* hierarchical ignore filters, and computes project-level statistics.
|
|
121
|
+
*
|
|
122
|
+
* @param options - The configuration settings for the scan operation.
|
|
123
|
+
* @returns A promise resolving to a Result containing the discovered files and scan metadata.
|
|
124
|
+
*/
|
|
125
|
+
declare const scan: (options: ScanOptions) => Promise<Result<ScanResult>>;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Normalizes scanner options by applying defaults and resolving paths.
|
|
129
|
+
*
|
|
130
|
+
* @param options - The raw configuration options provided by the caller.
|
|
131
|
+
* @returns A new object containing fully normalized scanner options.
|
|
132
|
+
*/
|
|
133
|
+
declare const normalizeOptions: (options: ScanOptions) => NormalizedOptions;
|
|
134
|
+
/**
|
|
135
|
+
* Validates the structural integrity of the provided scanner options.
|
|
136
|
+
*
|
|
137
|
+
* @param options - The options to evaluate.
|
|
138
|
+
* @returns A read-only collection of validation error messages, if any.
|
|
139
|
+
*/
|
|
140
|
+
declare const validateOptions: (options: ScanOptions) => ReadonlyArray<string>;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @fileoverview
|
|
144
|
+
* Provides utilities for the expansion and normalization of glob patterns.
|
|
145
|
+
*
|
|
146
|
+
* Implements deterministic transformations to ensure cross-platform compatibility
|
|
147
|
+
* and validates pattern syntax before scanner execution.
|
|
148
|
+
*/
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Normalizes a glob pattern by ensuring the use of forward slashes.
|
|
152
|
+
*
|
|
153
|
+
* @param pattern - The pattern to normalize.
|
|
154
|
+
* @returns The normalized pattern string.
|
|
155
|
+
*/
|
|
156
|
+
declare const normalizePattern: (pattern: string) => string;
|
|
157
|
+
/**
|
|
158
|
+
* Expands configuration options into normalized inclusion and exclusion patterns.
|
|
159
|
+
*
|
|
160
|
+
* @param options - The normalized scanner options.
|
|
161
|
+
* @returns An object containing expanded include and ignore pattern collections.
|
|
162
|
+
*/
|
|
163
|
+
declare const expandPatterns: (options: NormalizedOptions) => ExpandedPatterns;
|
|
164
|
+
/**
|
|
165
|
+
* Evaluates whether a glob pattern adheres to supported syntax rules.
|
|
166
|
+
*
|
|
167
|
+
* @param pattern - The pattern to validate.
|
|
168
|
+
* @returns True if the pattern is structurally valid.
|
|
169
|
+
*/
|
|
170
|
+
declare const isValidPattern: (pattern: string) => boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Validates a collection of patterns, segregating them into valid and erroneous sets.
|
|
173
|
+
*
|
|
174
|
+
* @param patterns - The patterns to evaluate.
|
|
175
|
+
* @returns A tuple containing the valid patterns and a collection of error messages.
|
|
176
|
+
*/
|
|
177
|
+
declare const validatePatterns: (patterns: ReadonlyArray<string>) => readonly [ReadonlyArray<string>, ReadonlyArray<string>];
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* @fileoverview
|
|
181
|
+
* Provides high-performance file filtering utilities for the scanner.
|
|
182
|
+
*
|
|
183
|
+
* Implements functional primitives for deduplication, gitignore evaluation,
|
|
184
|
+
* extension filtering, and glob-based inclusion/exclusion logic. All operations
|
|
185
|
+
* prioritize immutability and predictable outcomes.
|
|
186
|
+
*/
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Deduplicates a collection of file paths.
|
|
190
|
+
*
|
|
191
|
+
* @param files - A collection of file paths, potentially containing duplicates.
|
|
192
|
+
* @returns A new read-only collection with duplicate entries removed.
|
|
193
|
+
*/
|
|
194
|
+
declare const deduplicateFiles: (files: ReadonlyArray<string>) => ReadonlyArray<string>;
|
|
195
|
+
/**
|
|
196
|
+
* Filters a collection of files based on their file extensions.
|
|
197
|
+
*
|
|
198
|
+
* @param files - The files to evaluate.
|
|
199
|
+
* @param extensions - A collection of allowed file extensions (e.g., ['.ts', '.html']).
|
|
200
|
+
* @returns A collection of files matching the specified extensions.
|
|
201
|
+
*/
|
|
202
|
+
declare const filterByExtension: (files: ReadonlyArray<string>, extensions: ReadonlyArray<string>) => ReadonlyArray<string>;
|
|
203
|
+
/**
|
|
204
|
+
* Filters a collection of files using regular expression pattern matching.
|
|
205
|
+
*
|
|
206
|
+
* @param files - The files to evaluate.
|
|
207
|
+
* @param pattern - The regular expression pattern to apply.
|
|
208
|
+
* @returns A collection of files that satisfy the pattern.
|
|
209
|
+
*/
|
|
210
|
+
declare const filterByPattern: (files: ReadonlyArray<string>, pattern: RegExp) => ReadonlyArray<string>;
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* @fileoverview
|
|
214
|
+
* Provides utilities for calculating and formatting file scan statistics.
|
|
215
|
+
*
|
|
216
|
+
* Implements high-performance aggregation logic, including asynchronous file size
|
|
217
|
+
* summation with concurrency control and extension-based grouping.
|
|
218
|
+
*/
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Generates comprehensive scan statistics for a collection of discovered files.
|
|
222
|
+
*
|
|
223
|
+
* @param files - The collection of discovered file paths.
|
|
224
|
+
* @param startTime - The high-resolution start time of the scan operation.
|
|
225
|
+
* @param cacheHit - Indicates whether the results were retrieved from a cache.
|
|
226
|
+
* @returns A promise resolving to the computed scan statistics.
|
|
227
|
+
*/
|
|
228
|
+
declare const calculateStats: (files: ReadonlyArray<string>, startTime: number, cacheHit?: boolean) => Promise<ScanStatistics>;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Constructs a gitignore evaluator function from raw ignore patterns.
|
|
232
|
+
*
|
|
233
|
+
* @param gitignoreContent - The raw content of a .gitignore configuration.
|
|
234
|
+
* @returns An evaluator function that determines if a file path is ignored.
|
|
235
|
+
*/
|
|
236
|
+
declare const createGitignoreFilter: (gitignoreContent: string) => GitignoreFilter;
|
|
237
|
+
/**
|
|
238
|
+
* Constructs a pass-through filter that accepts all file paths.
|
|
239
|
+
*
|
|
240
|
+
* @returns An evaluator function that invariably returns true.
|
|
241
|
+
*/
|
|
242
|
+
declare const createPassThroughFilter: () => GitignoreFilter;
|
|
243
|
+
/**
|
|
244
|
+
* Builds a composite gitignore filter by collecting every `.gitignore` file
|
|
245
|
+
* that lies between `rootDir` and the directories of the supplied file paths.
|
|
246
|
+
*
|
|
247
|
+
* Each `.gitignore` file is applied relative to its own directory β€” exactly
|
|
248
|
+
* as Git itself does β€” so a pattern `dist/` inside `src/.gitignore` only
|
|
249
|
+
* ignores `src/dist/`, not the repo root `dist/`.
|
|
250
|
+
*
|
|
251
|
+
* This is more correct than loading only the root `.gitignore` for projects
|
|
252
|
+
* that use per-package or per-directory ignore rules (monorepos, etc.).
|
|
253
|
+
*
|
|
254
|
+
* @param rootDir - Scan root directory (absolute path)
|
|
255
|
+
* @param filePaths - File paths discovered so far (used to find relevant dirs)
|
|
256
|
+
* @returns Composite filter or a pass-through if no `.gitignore` files found
|
|
257
|
+
*/
|
|
258
|
+
declare const loadAllGitignoreFilters: (rootDir: string, filePaths: ReadonlyArray<string>) => Promise<Result<GitignoreFilter>>;
|
|
259
|
+
|
|
260
|
+
export { type ExpandedPatterns, type GitignoreFilter, type NormalizedOptions, type OnProgressCallback, type Option, type ScanOptions, type ScanPhase, type ScanResult, type ScanStatistics, calculateStats, createGitignoreFilter, createPassThroughFilter, deduplicateFiles, expandPatterns, filterByExtension, filterByPattern, isValidPattern, loadAllGitignoreFilters, normalizeOptions, normalizePattern, scan, validateOptions, validatePatterns };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { CacheContext } from '@ngcompass/cache';
|
|
2
|
+
import { Result } from '@ngcompass/common';
|
|
3
|
+
export { Err, Ok, Result } from '@ngcompass/common';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @fileoverview
|
|
7
|
+
* Definitional contracts and primitive types for the @ngcompass/scanner package.
|
|
8
|
+
*
|
|
9
|
+
* Adheres to functional programming principles by ensuring type immutability
|
|
10
|
+
* and providing explicit structures for configuration, results, and progress reporting.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Represents a value that may be present, null, or undefined.
|
|
15
|
+
*/
|
|
16
|
+
type Option<T> = T | null | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Defines the input configuration options for a scanner operation.
|
|
19
|
+
*/
|
|
20
|
+
interface ScanOptions {
|
|
21
|
+
readonly rootDir: string;
|
|
22
|
+
readonly include: ReadonlyArray<string>;
|
|
23
|
+
readonly exclude: ReadonlyArray<string>;
|
|
24
|
+
readonly ignorePatterns?: ReadonlyArray<string>;
|
|
25
|
+
readonly respectGitignore?: boolean;
|
|
26
|
+
readonly followSymlinks?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Whether to match dotfiles and dot-directories (e.g. `.angular/`, `.nx/`).
|
|
29
|
+
* Corresponds to tinyglobby's `dot` option.
|
|
30
|
+
* @default false
|
|
31
|
+
*/
|
|
32
|
+
readonly dot?: boolean;
|
|
33
|
+
readonly debug?: boolean;
|
|
34
|
+
readonly cache?: CacheContext;
|
|
35
|
+
/**
|
|
36
|
+
* Optional progress callback invoked at key phases of the scan.
|
|
37
|
+
* Receives the current phase name and the file count known at that point.
|
|
38
|
+
*/
|
|
39
|
+
readonly onProgress?: OnProgressCallback;
|
|
40
|
+
/**
|
|
41
|
+
* Optional path to a `tsconfig.json` file. When provided, the scanner
|
|
42
|
+
* narrows discovered files to those the TypeScript compiler would include
|
|
43
|
+
* by merging the tsconfig's `include` / `exclude` / `files` arrays with
|
|
44
|
+
* the scan options.
|
|
45
|
+
*
|
|
46
|
+
* Relative paths inside the tsconfig are resolved against the tsconfig's
|
|
47
|
+
* directory, not `rootDir`.
|
|
48
|
+
*/
|
|
49
|
+
readonly tsConfigPath?: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Represents scanner configuration options after the application of project defaults.
|
|
53
|
+
*/
|
|
54
|
+
interface NormalizedOptions {
|
|
55
|
+
readonly rootDir: string;
|
|
56
|
+
readonly include: ReadonlyArray<string>;
|
|
57
|
+
readonly exclude: ReadonlyArray<string>;
|
|
58
|
+
readonly ignorePatterns: ReadonlyArray<string>;
|
|
59
|
+
readonly respectGitignore: boolean;
|
|
60
|
+
readonly followSymlinks: boolean;
|
|
61
|
+
/** Resolved value of ScanOptions.dot β€” always a boolean after normalization. */
|
|
62
|
+
readonly dot: boolean;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Represents a set of inclusion and exclusion glob patterns.
|
|
66
|
+
*/
|
|
67
|
+
interface ExpandedPatterns {
|
|
68
|
+
readonly include: ReadonlyArray<string>;
|
|
69
|
+
readonly ignore: ReadonlyArray<string>;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Encapsulates statistical metadata for a completed scan operation.
|
|
73
|
+
*/
|
|
74
|
+
interface ScanStatistics {
|
|
75
|
+
readonly totalFiles: number;
|
|
76
|
+
readonly byExtension: ReadonlyMap<string, number>;
|
|
77
|
+
readonly totalSize: number;
|
|
78
|
+
readonly scanTime: number;
|
|
79
|
+
readonly cacheHit: boolean;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Encapsulates high-resolution timing data for various scan phases.
|
|
83
|
+
*/
|
|
84
|
+
interface ScanTimings {
|
|
85
|
+
readonly normalization: number;
|
|
86
|
+
readonly discovery: number;
|
|
87
|
+
readonly filtering: number;
|
|
88
|
+
readonly total: number;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Encapsulates the consolidated results and metadata of a scan operation.
|
|
92
|
+
*/
|
|
93
|
+
interface ScanResult {
|
|
94
|
+
readonly files: ReadonlyArray<string>;
|
|
95
|
+
readonly stats: ScanStatistics;
|
|
96
|
+
readonly timestamp: number;
|
|
97
|
+
readonly timings?: ScanTimings;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Gitignore filter function type
|
|
101
|
+
*/
|
|
102
|
+
type GitignoreFilter = (file: string, rootDir: string) => boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Represents the distinct phases of an active scan operation.
|
|
105
|
+
*/
|
|
106
|
+
type ScanPhase = 'normalizing' | 'discovering' | 'filtering' | 'calculating-stats' | 'complete';
|
|
107
|
+
/**
|
|
108
|
+
* Callback invoked at each scan phase transition with the current file count.
|
|
109
|
+
* Useful for driving progress bars or log output in CLI consumers.
|
|
110
|
+
*
|
|
111
|
+
* @param phase - The phase that just started (or completed for 'complete').
|
|
112
|
+
* @param count - Number of files known at this point in the scan.
|
|
113
|
+
*/
|
|
114
|
+
type OnProgressCallback = (phase: ScanPhase, count: number) => void;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Executes a comprehensive file scan based on the provided configuration.
|
|
118
|
+
*
|
|
119
|
+
* Discovers files using optimized Git utilities or standard globbing, applies
|
|
120
|
+
* hierarchical ignore filters, and computes project-level statistics.
|
|
121
|
+
*
|
|
122
|
+
* @param options - The configuration settings for the scan operation.
|
|
123
|
+
* @returns A promise resolving to a Result containing the discovered files and scan metadata.
|
|
124
|
+
*/
|
|
125
|
+
declare const scan: (options: ScanOptions) => Promise<Result<ScanResult>>;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Normalizes scanner options by applying defaults and resolving paths.
|
|
129
|
+
*
|
|
130
|
+
* @param options - The raw configuration options provided by the caller.
|
|
131
|
+
* @returns A new object containing fully normalized scanner options.
|
|
132
|
+
*/
|
|
133
|
+
declare const normalizeOptions: (options: ScanOptions) => NormalizedOptions;
|
|
134
|
+
/**
|
|
135
|
+
* Validates the structural integrity of the provided scanner options.
|
|
136
|
+
*
|
|
137
|
+
* @param options - The options to evaluate.
|
|
138
|
+
* @returns A read-only collection of validation error messages, if any.
|
|
139
|
+
*/
|
|
140
|
+
declare const validateOptions: (options: ScanOptions) => ReadonlyArray<string>;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @fileoverview
|
|
144
|
+
* Provides utilities for the expansion and normalization of glob patterns.
|
|
145
|
+
*
|
|
146
|
+
* Implements deterministic transformations to ensure cross-platform compatibility
|
|
147
|
+
* and validates pattern syntax before scanner execution.
|
|
148
|
+
*/
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Normalizes a glob pattern by ensuring the use of forward slashes.
|
|
152
|
+
*
|
|
153
|
+
* @param pattern - The pattern to normalize.
|
|
154
|
+
* @returns The normalized pattern string.
|
|
155
|
+
*/
|
|
156
|
+
declare const normalizePattern: (pattern: string) => string;
|
|
157
|
+
/**
|
|
158
|
+
* Expands configuration options into normalized inclusion and exclusion patterns.
|
|
159
|
+
*
|
|
160
|
+
* @param options - The normalized scanner options.
|
|
161
|
+
* @returns An object containing expanded include and ignore pattern collections.
|
|
162
|
+
*/
|
|
163
|
+
declare const expandPatterns: (options: NormalizedOptions) => ExpandedPatterns;
|
|
164
|
+
/**
|
|
165
|
+
* Evaluates whether a glob pattern adheres to supported syntax rules.
|
|
166
|
+
*
|
|
167
|
+
* @param pattern - The pattern to validate.
|
|
168
|
+
* @returns True if the pattern is structurally valid.
|
|
169
|
+
*/
|
|
170
|
+
declare const isValidPattern: (pattern: string) => boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Validates a collection of patterns, segregating them into valid and erroneous sets.
|
|
173
|
+
*
|
|
174
|
+
* @param patterns - The patterns to evaluate.
|
|
175
|
+
* @returns A tuple containing the valid patterns and a collection of error messages.
|
|
176
|
+
*/
|
|
177
|
+
declare const validatePatterns: (patterns: ReadonlyArray<string>) => readonly [ReadonlyArray<string>, ReadonlyArray<string>];
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* @fileoverview
|
|
181
|
+
* Provides high-performance file filtering utilities for the scanner.
|
|
182
|
+
*
|
|
183
|
+
* Implements functional primitives for deduplication, gitignore evaluation,
|
|
184
|
+
* extension filtering, and glob-based inclusion/exclusion logic. All operations
|
|
185
|
+
* prioritize immutability and predictable outcomes.
|
|
186
|
+
*/
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Deduplicates a collection of file paths.
|
|
190
|
+
*
|
|
191
|
+
* @param files - A collection of file paths, potentially containing duplicates.
|
|
192
|
+
* @returns A new read-only collection with duplicate entries removed.
|
|
193
|
+
*/
|
|
194
|
+
declare const deduplicateFiles: (files: ReadonlyArray<string>) => ReadonlyArray<string>;
|
|
195
|
+
/**
|
|
196
|
+
* Filters a collection of files based on their file extensions.
|
|
197
|
+
*
|
|
198
|
+
* @param files - The files to evaluate.
|
|
199
|
+
* @param extensions - A collection of allowed file extensions (e.g., ['.ts', '.html']).
|
|
200
|
+
* @returns A collection of files matching the specified extensions.
|
|
201
|
+
*/
|
|
202
|
+
declare const filterByExtension: (files: ReadonlyArray<string>, extensions: ReadonlyArray<string>) => ReadonlyArray<string>;
|
|
203
|
+
/**
|
|
204
|
+
* Filters a collection of files using regular expression pattern matching.
|
|
205
|
+
*
|
|
206
|
+
* @param files - The files to evaluate.
|
|
207
|
+
* @param pattern - The regular expression pattern to apply.
|
|
208
|
+
* @returns A collection of files that satisfy the pattern.
|
|
209
|
+
*/
|
|
210
|
+
declare const filterByPattern: (files: ReadonlyArray<string>, pattern: RegExp) => ReadonlyArray<string>;
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* @fileoverview
|
|
214
|
+
* Provides utilities for calculating and formatting file scan statistics.
|
|
215
|
+
*
|
|
216
|
+
* Implements high-performance aggregation logic, including asynchronous file size
|
|
217
|
+
* summation with concurrency control and extension-based grouping.
|
|
218
|
+
*/
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Generates comprehensive scan statistics for a collection of discovered files.
|
|
222
|
+
*
|
|
223
|
+
* @param files - The collection of discovered file paths.
|
|
224
|
+
* @param startTime - The high-resolution start time of the scan operation.
|
|
225
|
+
* @param cacheHit - Indicates whether the results were retrieved from a cache.
|
|
226
|
+
* @returns A promise resolving to the computed scan statistics.
|
|
227
|
+
*/
|
|
228
|
+
declare const calculateStats: (files: ReadonlyArray<string>, startTime: number, cacheHit?: boolean) => Promise<ScanStatistics>;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Constructs a gitignore evaluator function from raw ignore patterns.
|
|
232
|
+
*
|
|
233
|
+
* @param gitignoreContent - The raw content of a .gitignore configuration.
|
|
234
|
+
* @returns An evaluator function that determines if a file path is ignored.
|
|
235
|
+
*/
|
|
236
|
+
declare const createGitignoreFilter: (gitignoreContent: string) => GitignoreFilter;
|
|
237
|
+
/**
|
|
238
|
+
* Constructs a pass-through filter that accepts all file paths.
|
|
239
|
+
*
|
|
240
|
+
* @returns An evaluator function that invariably returns true.
|
|
241
|
+
*/
|
|
242
|
+
declare const createPassThroughFilter: () => GitignoreFilter;
|
|
243
|
+
/**
|
|
244
|
+
* Builds a composite gitignore filter by collecting every `.gitignore` file
|
|
245
|
+
* that lies between `rootDir` and the directories of the supplied file paths.
|
|
246
|
+
*
|
|
247
|
+
* Each `.gitignore` file is applied relative to its own directory β€” exactly
|
|
248
|
+
* as Git itself does β€” so a pattern `dist/` inside `src/.gitignore` only
|
|
249
|
+
* ignores `src/dist/`, not the repo root `dist/`.
|
|
250
|
+
*
|
|
251
|
+
* This is more correct than loading only the root `.gitignore` for projects
|
|
252
|
+
* that use per-package or per-directory ignore rules (monorepos, etc.).
|
|
253
|
+
*
|
|
254
|
+
* @param rootDir - Scan root directory (absolute path)
|
|
255
|
+
* @param filePaths - File paths discovered so far (used to find relevant dirs)
|
|
256
|
+
* @returns Composite filter or a pass-through if no `.gitignore` files found
|
|
257
|
+
*/
|
|
258
|
+
declare const loadAllGitignoreFilters: (rootDir: string, filePaths: ReadonlyArray<string>) => Promise<Result<GitignoreFilter>>;
|
|
259
|
+
|
|
260
|
+
export { type ExpandedPatterns, type GitignoreFilter, type NormalizedOptions, type OnProgressCallback, type Option, type ScanOptions, type ScanPhase, type ScanResult, type ScanStatistics, calculateStats, createGitignoreFilter, createPassThroughFilter, deduplicateFiles, expandPatterns, filterByExtension, filterByPattern, isValidPattern, loadAllGitignoreFilters, normalizeOptions, normalizePattern, scan, validateOptions, validatePatterns };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import {access,readFile,stat,readdir}from'fs/promises';import p from'path';import {Ok,Err,time,debug,timeEnd}from'@ngcompass/common';export{Err,Ok}from'@ngcompass/common';import {glob}from'tinyglobby';import {minimatch}from'minimatch';import I from'ignore';import {exec,spawn}from'child_process';import {promisify}from'util';var le=["**/*.ts","**/*.html","**/*.scss","**/*.css","**/*.sass","**/*.less"],S=e=>({rootDir:p.resolve(e.rootDir),include:e.include.length>0?e.include:le,exclude:e.exclude,ignorePatterns:e.ignorePatterns??[],respectGitignore:e.respectGitignore??true,followSymlinks:e.followSymlinks??false,dot:e.dot??false}),se=e=>{let r=[];return e.rootDir&&e.rootDir.trim()!==""||r.push("rootDir cannot be empty"),e.include&&e.include.length!==0||r.push("No include patterns specified (will use defaults)"),r};var F=e=>e.replace(/\\/g,"/"),P=e=>({include:e.include.map(F),ignore:[...e.exclude.map(F),...e.ignorePatterns.map(F)]}),H=e=>!(e.trim()===""||e.includes("***")),ce=e=>{let r=[],t=[];for(let i of e)H(i)?r.push(i):t.push(`Invalid pattern: "${i}"`);return [r,t]};var A=async(e,r,t)=>{try{let i=await glob([...e.include],{cwd:r,ignore:[...e.ignore],absolute:!0,followSymbolicLinks:t.followSymlinks,onlyFiles:!0,dot:t.dot});return Ok({files:i})}catch(i){return Err(Error(`Glob execution failed: ${i.message}`))}};var me=async e=>{let r=p.join(e,".gitignore");try{return await readFile(r,"utf-8")}catch{return debug("scanner",`Failed to load .gitignore from ${e}`),null}},pe=e=>{let r=I().add(e);return (t,i)=>{let o=p.relative(i,t);return !r.ignores(o)}},M=()=>()=>true;var O=async(e,r)=>{try{let t=new Set;for(let o of(t.add(e),r)){let n=p.dirname(o);for(;n.startsWith(e)&&n!==p.dirname(e)&&(t.add(n),n!==e);)n=p.dirname(n);}let i=[];for(let o of t){let n=await me(o);n&&i.push({dir:o,ig:I().add(n)});}return i.length===0?Ok(M()):Ok(o=>{for(let{dir:n,ig:a}of i){let c=p.relative(n,o).replace(/\\/g,"/");if(!c.startsWith("..")&&!p.isAbsolute(c)&&a.ignores(c))return !1}return !0})}catch(t){return Err(Error(`Failed to load gitignore filters: ${t.message}`))}};var U=e=>Array.from(new Set(e)),ye=(e,r,t)=>e.filter(i=>t(i,r)),J=async(e,r)=>{try{let t=e.files,i=t.length;if(r.respectGitignore){let o=await O(r.rootDir,t);if(!o.ok)return o;t=ye(t,r.rootDir,o.data);}return t=U(t),Ok({files:t,filtered:i-t.length})}catch(t){return Err(Error(`Filtering failed: ${t.message}`))}},he=(e,r)=>{let t=new Set(r);return e.filter(i=>{let o=i.substring(i.lastIndexOf("."));return t.has(o)})},we=(e,r)=>e.filter(t=>r.test(t)),K=(e,r,t,i)=>e.filter(o=>{let n=p.relative(i,o).replace(/\\/g,"/");return !(!r.some(a=>minimatch(n,a,{dot:true}))||t.some(a=>minimatch(n,a,{dot:true})))});var ve=async(e,r)=>{let t=Array(e.length),i=0,o=async()=>{for(;i<e.length;){let n=i++;try{t[n]={status:"fulfilled",value:await e[n]()};}catch(a){t[n]={status:"rejected",reason:a};}}};return await Promise.all(Array.from({length:Math.min(r,e.length)},o)),t},Fe=async e=>{let r=e.map(t=>()=>stat(t));return (await ve(r,128)).reduce((t,i)=>t+(i.status==="fulfilled"?i.value.size:0),0)},D=async(e,r,t=false)=>{let i=e.reduce((a,c)=>{let f=p.extname(c)||".no-extension",g=a.get(f)??0;return a.set(f,g+1),a},new Map),o=await Fe(e),n=performance.now()-r;return {totalFiles:e.length,byExtension:i,totalSize:o,scanTime:n,cacheHit:t}};var z=promisify(exec),_=async e=>{try{return await z("git rev-parse --is-inside-work-tree",{cwd:e}),!0}catch{return false}},q=async e=>new Promise(r=>{try{let t=spawn("git",["ls-files","-c","-o","--exclude-standard"],{cwd:e}),i=[];t.stdout.setEncoding("utf8"),t.stdout.on("data",o=>{i.push(o);}),t.on("close",o=>{if(o!==0){debug("scanner",`git ls-files exited with code ${o}`),r([]);return}let n=i.join("").split(`
|
|
2
|
+
`).filter(a=>a.trim().length>0).map(a=>p.resolve(e,a));r(n);}),t.on("error",o=>{debug("scanner",`Git discovery failed: ${o.message}`),r([]);});}catch(t){debug("scanner",`Git discovery failed: ${t.message}`),r([]);}}),Q=async e=>{try{let{stdout:r}=await z("git rev-parse HEAD",{cwd:e});try{let{stdout:t}=await z("git rev-parse --show-toplevel",{cwd:e}),i=p.join(t.trim(),".git","index"),o=await stat(i);return `${r.trim()}-${o.mtime.getTime()}`}catch{return r.trim()}}catch(r){return debug("scanner",`Failed to get repo fingerprint: ${r instanceof Error?r.message:String(r)}`),""}},X=async e=>{try{let r=await readdir(e,{withFileTypes:!0}),t=await Promise.allSettled(r.map(a=>stat(p.join(e,a.name)))),i=0,o=0,n=0;for(let a of t)a.status==="fulfilled"&&(i+=a.value.size,a.value.mtimeMs>o&&(o=a.value.mtimeMs),n++);return `dir-${r.length}-${n}-${i}-${o}`}catch(r){return debug("scanner",`Failed to get directory fingerprint: ${r instanceof Error?r.message:String(r)}`),""}};var Ae=async e=>{var r,t,i,o,n,a,c,f,g;let j;time("file-scan");let L=performance.now(),y=e.onProgress??(()=>{});r=e,debug("scanner",`Starting file discovery in: ${r.rootDir}`),debug("scanner",`Include patterns: ${r.include.join(", ")}`),debug("scanner",`Exclude patterns: ${r.exclude.join(", ")}`),y("normalizing",0);let ee=performance.now(),d=S(e),h=P(d),te=performance.now()-ee;if(t=d,i=h,debug("scanner",`Normalized rootDir: ${t.rootDir}`),debug("scanner",`Expanded to ${i.include.length} include patterns, ${i.ignore.length} ignore patterns`),e.tsConfigPath){let m=await je(e.tsConfigPath,d.rootDir);m&&(o=h,h={include:(n=m).include.length>0?[...o.include,...n.include]:o.include,ignore:n.exclude.length>0?[...o.ignore,...n.exclude]:o.ignore},debug("scanner",`tsconfig patterns merged: +${m.include.length} include, +${m.exclude.length} exclude`));}try{await access(d.rootDir);}catch{return timeEnd("file-scan"),Err(Error(`rootDir does not exist or is not accessible: ${d.rootDir}`))}let G=await _(d.rootDir),b=await ze(d,h,G,e);if(b)return y("complete",b.length),await Te(b,L);y("discovering",0);let re=performance.now(),v=await Oe(d,h,G);if(!v.ok)return Y("Scan",v.error),v;let N=v.data,ie=performance.now()-re;y("filtering",N.length);let oe=performance.now(),x=await J({files:N},d);if(!x.ok)return Y("Filter",x.error),x;let w=x.data.files,ne=performance.now()-oe;a=w.length,c=x.data.filtered,debug("scanner",`After filters: ${a} files (${c} filtered out)`),y("calculating-stats",w.length),await Ce(d,h,w,G,e);let B=await D(w,L,false),R=timeEnd("file-scan");return f=B,g=R,debug("scanner",`Scan complete: ${f.totalFiles} files in ${g.toFixed(1)}ms`),j=Array.from(f.byExtension.entries()).sort(([,m],[,E])=>E-m).slice(0,5).map(([m,E])=>`${m}:${E}`).join(", "),debug("scanner",`Breakdown: ${j}`),f.totalFiles===0&&debug("scanner","No files found matching patterns. Check your include/exclude configuration."),y("complete",w.length),Ok({files:w,stats:B,timestamp:Date.now(),timings:{normalization:te,discovery:ie,filtering:ne,total:R}})};async function Oe(e,r,t){if(t){debug("scanner","Git repository detected. Using fast Git discovery...");let o=await q(e.rootDir);if(o.length===0){debug("scanner","Git discovery returned 0 files \u2014 this may indicate a git command failure. Falling back to glob-based scanning.");let a=await A(r,e.rootDir,{followSymlinks:e.followSymlinks,dot:e.dot});return a.ok&&debug("scanner",`Glob fallback found ${a.data.files.length} files`),a.ok?Ok(a.data.files):a}let n=K(o,r.include,r.ignore,e.rootDir);return debug("scanner",`Git discovery found ${n.length} files (after glob filtering)`),Ok(n)}debug("scanner","Not a Git repository. Falling back to standard globbing...");let i=await A(r,e.rootDir,{followSymlinks:e.followSymlinks,dot:e.dot});return i.ok&&debug("scanner",`Glob found ${i.data.files.length} files`),i.ok?Ok(i.data.files):i}async function Z(e,r,t,i){if(!i.cache)return null;let o=t?await Q(e.rootDir):await X(e.rootDir);return o?i.cache.computeHash([e.rootDir,JSON.stringify(r),o,"v1"].join("|")):null}async function ze(e,r,t,i){let o=await Z(e,r,t,i);if(!o||!i.cache)return null;let n=await i.cache.files.get(o);return n?(debug("scanner",`Cache HIT. Loaded ${n.files.length} files.`),n.files):null}async function Ce(e,r,t,i,o){if(!o.cache||t.length===0)return;let n=await Z(e,r,i,o);n&&(await o.cache.files.set(n,t),debug("scanner","File list cached."));}async function Te(e,r){let t=await D(e,r,true),i=performance.now()-r;return Ok({files:e,stats:t,timestamp:Date.now(),timings:{normalization:0,discovery:i,filtering:0,total:i}})}function Y(e,r){let t=timeEnd("file-scan");debug("scanner",`${e} failed after ${t.toFixed(1)}ms: ${r.message}`);}async function je(e,r){try{let t=(await readFile(e,"utf-8")).replace(/\/\/[^\n]*/g,"").replace(/\/\*[\s\S]*?\*\//g,""),i=JSON.parse(t),o=p.dirname(p.resolve(e)),n=f=>{let g=p.resolve(o,f);return p.relative(r,g).replace(/\\/g,"/")},a=[],c=[];return Array.isArray(i.include)&&a.push(...i.include.map(n)),Array.isArray(i.files)&&a.push(...i.files.map(n)),Array.isArray(i.exclude)&&c.push(...i.exclude.map(n)),{include:a,exclude:c}}catch(t){return debug("scanner",`Failed to load tsconfig patterns from ${e}: ${t instanceof Error?t.message:String(t)}`),null}}
|
|
3
|
+
export{D as calculateStats,pe as createGitignoreFilter,M as createPassThroughFilter,U as deduplicateFiles,P as expandPatterns,he as filterByExtension,we as filterByPattern,H as isValidPattern,O as loadAllGitignoreFilters,S as normalizeOptions,F as normalizePattern,Ae as scan,se as validateOptions,ce as validatePatterns};//# sourceMappingURL=index.js.map
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/normalize.ts","../src/patterns.ts","../src/glob.ts","../src/gitignore.ts","../src/filters.ts","../src/stats.ts","../src/git.ts","../src/scan.ts"],"names":["DEFAULT_INCLUDE","normalizeOptions","options","rootDir","path","resolve","include","length","exclude","ignorePatterns","respectGitignore","followSymlinks","dot","validateOptions","errors","trim","push","normalizePattern","pattern","replace","expandPatterns","map","ignore","isValidPattern","includes","validatePatterns","patterns","valid","executeGlob","files","glob","cwd","absolute","followSymbolicLinks","onlyFiles","Ok","error","Err","Error","message","loadGitignore","gitignorePath","join","readFile","debug","createGitignoreFilter","gitignoreContent","ig","add","file","relative","ignores","createPassThroughFilter","loadAllGitignoreFilters","filePaths","dirsToCheck","Set","filePath","current","dirname","startsWith","dirFilters","dir","content","rel","isAbsolute","deduplicateFiles","Array","from","applyGitignoreFilter","filter","applyFilters","rawFiles","startCount","filterResult","ok","data","filtered","filterByExtension","extensions","extSet","ext","substring","lastIndexOf","has","filterByPattern","test","filterByGlob","relativePath","some","p","minimatch","runWithLimit","tasks","concurrency","results","cursor","worker","i","status","value","reason","Promise","all","Math","min","calculateTotalSize","f","stat","reduce","sum","result","size","calculateStats","startTime","cacheHit","byExtension","extname","count","get","set","Map","totalSize","scanTime","performance","now","totalFiles","execAsync","promisify","exec","isGitRepo","executeGitDiscovery","child","spawn","chunks","stdout","setEncoding","on","chunk","code","split","line","err","getRepoFingerprint","head","root","indexPath","fileStats","mtime","getTime","String","getDirectoryFingerprint","entries","readdir","withFileTypes","statResults","allSettled","entry","name","latestMtime","statSuccessCount","mtimeMs","scan","normalized","tsPatterns","fileCount","filteredCount","stats","breakdown","time","progress","onProgress","t0","normalizationTime","tsConfigPath","loadTsConfigPatterns","access","timeEnd","isGit","cacheResult","tryLoadFromCache","buildCachedResult","t1","discoveryResult","discoverFiles","logAndReturnError","discoveryTime","t2","finalFiles","filteringTime","saveToCache","totalTime","toFixed","sort","a","b","slice","timestamp","Date","timings","normalization","discovery","filtering","total","gitFiles","getCacheKey","cache","fingerprint","computeHash","JSON","stringify","key","cached","phase","stripped","config","parse","configDir","toRootRelative","abs","isArray"],"mappings":"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","file":"index.js","sourcesContent":["import e from 'node:path';\nlet DEFAULT_INCLUDE = [\n '**/*.ts',\n '**/*.html',\n '**/*.scss',\n '**/*.css',\n '**/*.sass',\n '**/*.less'\n];\nexport const normalizeOptions = (t)=>({\n rootDir: e.resolve(t.rootDir),\n include: t.include.length > 0 ? t.include : DEFAULT_INCLUDE,\n exclude: t.exclude,\n ignorePatterns: t.ignorePatterns ?? [],\n respectGitignore: t.respectGitignore ?? !0,\n followSymlinks: t.followSymlinks ?? !1,\n dot: t.dot ?? !1\n });\nexport const validateOptions = (e)=>{\n let t = [];\n return e.rootDir && '' !== e.rootDir.trim() || t.push('rootDir cannot be empty'), e.include && 0 !== e.include.length || t.push('No include patterns specified (will use defaults)'), t;\n};\n","export const normalizePattern = (t)=>t.replace(/\\\\/g, '/');\nexport const expandPatterns = (t)=>({\n include: t.include.map(normalizePattern),\n ignore: [\n ...t.exclude.map(normalizePattern),\n ...t.ignorePatterns.map(normalizePattern)\n ]\n });\nexport const isValidPattern = (t)=>!('' === t.trim() || t.includes('***'));\nexport const validatePatterns = (t)=>{\n let e = [], n = [];\n for (let r of t)isValidPattern(r) ? e.push(r) : n.push(`Invalid pattern: \"${r}\"`);\n return [\n e,\n n\n ];\n};\n","import { glob as e } from 'tinyglobby';\nimport { Ok as t, Err as o } from './types.js';\nexport const executeGlob = async (r, l, i)=>{\n try {\n let o = await e([\n ...r.include\n ], {\n cwd: l,\n ignore: [\n ...r.ignore\n ],\n absolute: !0,\n followSymbolicLinks: i.followSymlinks,\n onlyFiles: !0,\n dot: i.dot\n });\n return t({\n files: o\n });\n } catch (e) {\n return o(Error(`Glob execution failed: ${e.message}`));\n }\n};\nexport const patternsLikelyHaveMatches = (e)=>!(0 === e.include.length || e.include.every((e)=>e.startsWith('!')));\n","import r from 'ignore';\nimport { readFile as e } from 'node:fs/promises';\nimport t from 'node:path';\nimport { Ok as o, Err as i } from './types.js';\nimport { debug as a } from '@ngcompass/common';\nexport const loadGitignore = async (r)=>{\n let o = t.join(r, '.gitignore');\n try {\n return await e(o, 'utf-8');\n } catch (e) {\n return a('scanner', `Failed to load .gitignore from ${r}`), null;\n }\n};\nexport const createGitignoreFilter = (e)=>{\n let o = r().add(e);\n return (r, e)=>{\n let i = t.relative(e, r);\n return !o.ignores(i);\n };\n};\nexport const createPassThroughFilter = ()=>()=>!0;\nexport const loadAndCreateGitignoreFilter = async (r)=>{\n try {\n let e = await loadGitignore(r);\n if (!e) return o(createPassThroughFilter());\n let t = createGitignoreFilter(e);\n return o(t);\n } catch (r) {\n return i(Error(`Failed to load .gitignore: ${r.message}`));\n }\n};\nexport const loadAllGitignoreFilters = async (e, a)=>{\n try {\n let i = new Set();\n for (let r of (i.add(e), a)){\n let o = t.dirname(r);\n for(; o.startsWith(e) && o !== t.dirname(e) && (i.add(o), o !== e);)o = t.dirname(o);\n }\n let n = [];\n for (let e of i){\n let t = await loadGitignore(e);\n t && n.push({\n dir: e,\n ig: r().add(t)\n });\n }\n if (0 === n.length) return o(createPassThroughFilter());\n return o((r)=>{\n for (let { dir: e, ig: o } of n){\n let i = t.relative(e, r).replace(/\\\\/g, '/');\n if (!i.startsWith('..') && !t.isAbsolute(i) && o.ignores(i)) return !1;\n }\n return !0;\n });\n } catch (r) {\n return i(Error(`Failed to load gitignore filters: ${r.message}`));\n }\n};\n","import t from 'node:path';\nimport { minimatch as e } from 'minimatch';\nimport { Ok as r, Err as i } from './types.js';\nimport { loadAllGitignoreFilters as o } from './gitignore.js';\nexport const deduplicateFiles = (t)=>Array.from(new Set(t));\nexport const applyGitignoreFilter = (t, e, r)=>t.filter((t)=>r(t, e));\nexport const applyFilters = async (t, e)=>{\n try {\n let i = t.files, l = i.length;\n if (e.respectGitignore) {\n let t = await o(e.rootDir, i);\n if (!t.ok) return t;\n i = applyGitignoreFilter(i, e.rootDir, t.data);\n }\n return i = deduplicateFiles(i), r({\n files: i,\n filtered: l - i.length\n });\n } catch (t) {\n return i(Error(`Filtering failed: ${t.message}`));\n }\n};\nexport const filterByExtension = (t, e)=>{\n let r = new Set(e);\n return t.filter((t)=>{\n let e = t.substring(t.lastIndexOf('.'));\n return r.has(e);\n });\n};\nexport const filterByPattern = (t, e)=>t.filter((t)=>e.test(t));\nexport const filterByGlob = (r, i, o, l)=>r.filter((r)=>{\n let n = t.relative(l, r).replace(/\\\\/g, '/');\n return !(!i.some((t)=>e(n, t, {\n dot: !0\n })) || o.some((t)=>e(n, t, {\n dot: !0\n })));\n });\n","import t from 'node:path';\nimport { stat as e } from 'node:fs/promises';\nlet runWithLimit = async (t, e)=>{\n let a = Array(t.length), l = 0, r = async ()=>{\n for(; l < t.length;){\n let e = l++;\n try {\n a[e] = {\n status: 'fulfilled',\n value: await t[e]()\n };\n } catch (t) {\n a[e] = {\n status: 'rejected',\n reason: t\n };\n }\n }\n };\n return await Promise.all(Array.from({\n length: Math.min(e, t.length)\n }, r)), a;\n}, calculateTotalSize = async (t)=>{\n let a = t.map((t)=>()=>e(t));\n return (await runWithLimit(a, 128)).reduce((t, e)=>t + ('fulfilled' === e.status ? e.value.size : 0), 0);\n};\nexport const calculateStats = async (e, a, l = !1)=>{\n let r = e.reduce((e, a)=>{\n let l = t.extname(a) || '.no-extension', r = e.get(l) ?? 0;\n return e.set(l, r + 1), e;\n }, new Map()), n = await calculateTotalSize(e), i = performance.now() - a;\n return {\n totalFiles: e.length,\n byExtension: r,\n totalSize: n,\n scanTime: i,\n cacheHit: l\n };\n};\n","import { exec as e, spawn as t } from 'node:child_process';\nimport { promisify as r } from 'node:util';\nimport i from 'node:path';\nimport { stat as o, readdir as n } from 'node:fs/promises';\nimport { debug as s } from '@ngcompass/common';\nlet execAsync = r(e);\nexport const isGitRepo = async (e)=>{\n try {\n return await execAsync('git rev-parse --is-inside-work-tree', {\n cwd: e\n }), !0;\n } catch {\n return !1;\n }\n};\nexport const executeGitDiscovery = async (e)=>new Promise((r)=>{\n try {\n let o = t('git', [\n 'ls-files',\n '-c',\n '-o',\n '--exclude-standard'\n ], {\n cwd: e\n }), n = [];\n o.stdout.setEncoding('utf8'), o.stdout.on('data', (e)=>{\n n.push(e);\n }), o.on('close', (t)=>{\n if (0 !== t) {\n s('scanner', `git ls-files exited with code ${t}`), r([]);\n return;\n }\n let o = n.join('').split('\\n').filter((e)=>e.trim().length > 0).map((t)=>i.resolve(e, t));\n r(o);\n }), o.on('error', (e)=>{\n s('scanner', `Git discovery failed: ${e.message}`), r([]);\n });\n } catch (e) {\n s('scanner', `Git discovery failed: ${e.message}`), r([]);\n }\n });\nexport const getRepoFingerprint = async (e)=>{\n try {\n let { stdout: t } = await execAsync('git rev-parse HEAD', {\n cwd: e\n });\n try {\n let { stdout: r } = await execAsync('git rev-parse --show-toplevel', {\n cwd: e\n }), n = i.join(r.trim(), '.git', 'index'), s = await o(n);\n return `${t.trim()}-${s.mtime.getTime()}`;\n } catch {\n return t.trim();\n }\n } catch (e) {\n return s('scanner', `Failed to get repo fingerprint: ${e instanceof Error ? e.message : String(e)}`), '';\n }\n};\nexport const getDirectoryFingerprint = async (e)=>{\n try {\n let t = await n(e, {\n withFileTypes: !0\n }), r = await Promise.allSettled(t.map((t)=>o(i.join(e, t.name)))), s = 0, a = 0, c = 0;\n for (let e of r)'fulfilled' === e.status && (s += e.value.size, e.value.mtimeMs > a && (a = e.value.mtimeMs), c++);\n return `dir-${t.length}-${c}-${s}-${a}`;\n } catch (e) {\n return s('scanner', `Failed to get directory fingerprint: ${e instanceof Error ? e.message : String(e)}`), '';\n }\n};\n","import { access as e, readFile as t } from 'node:fs/promises';\nimport r from 'node:path';\nimport { debug as n, time as i, timeEnd as a } from '@ngcompass/common';\nimport { Ok as o, Err as l } from './types.js';\nimport { normalizeOptions as s } from './normalize.js';\nimport { expandPatterns as c } from './patterns.js';\nimport { executeGlob as f } from './glob.js';\nimport { applyFilters as d, filterByGlob as u } from './filters.js';\nimport { calculateStats as g } from './stats.js';\nimport { isGitRepo as m, executeGitDiscovery as p, getRepoFingerprint as h, getDirectoryFingerprint as y } from './git.js';\nexport const scan = async (t)=>{\n var r, f, u, p, h, y, w, $, v;\n let D;\n i('file-scan');\n let b = performance.now(), k = t.onProgress ?? (()=>void 0);\n r = t, n('scanner', `Starting file discovery in: ${r.rootDir}`), n('scanner', `Include patterns: ${r.include.join(', ')}`), n('scanner', `Exclude patterns: ${r.exclude.join(', ')}`), k('normalizing', 0);\n let x = performance.now(), C = s(t), F = c(C), j = performance.now() - x;\n if (f = C, u = F, n('scanner', `Normalized rootDir: ${f.rootDir}`), n('scanner', `Expanded to ${u.include.length} include patterns, ${u.ignore.length} ignore patterns`), t.tsConfigPath) {\n let e = await loadTsConfigPatterns(t.tsConfigPath, C.rootDir);\n e && (p = F, F = {\n include: (h = e).include.length > 0 ? [\n ...p.include,\n ...h.include\n ] : p.include,\n ignore: h.exclude.length > 0 ? [\n ...p.ignore,\n ...h.exclude\n ] : p.ignore\n }, n('scanner', `tsconfig patterns merged: +${e.include.length} include, +${e.exclude.length} exclude`));\n }\n try {\n await e(C.rootDir);\n } catch {\n return a('file-scan'), l(Error(`rootDir does not exist or is not accessible: ${C.rootDir}`));\n }\n let A = await m(C.rootDir), S = await tryLoadFromCache(C, F, A, t);\n if (S) return k('complete', S.length), await buildCachedResult(S, b);\n k('discovering', 0);\n let E = performance.now(), G = await discoverFiles(C, F, A);\n if (!G.ok) return logAndReturnError('Scan', G.error), G;\n let z = G.data, N = performance.now() - E;\n k('filtering', z.length);\n let P = performance.now(), R = await d({\n files: z\n }, C);\n if (!R.ok) return logAndReturnError('Filter', R.error), R;\n let T = R.data.files, K = performance.now() - P;\n y = T.length, w = R.data.filtered, n('scanner', `After filters: ${y} files (${w} filtered out)`), k('calculating-stats', T.length), await saveToCache(C, F, T, A, t);\n let L = await g(T, b, !1), H = a('file-scan');\n return $ = L, v = H, n('scanner', `Scan complete: ${$.totalFiles} files in ${v.toFixed(1)}ms`), D = Array.from($.byExtension.entries()).sort(([, e], [, t])=>t - e).slice(0, 5).map(([e, t])=>`${e}:${t}`).join(', '), n('scanner', `Breakdown: ${D}`), 0 === $.totalFiles && n('scanner', 'No files found matching patterns. Check your include/exclude configuration.'), k('complete', T.length), o({\n files: T,\n stats: L,\n timestamp: Date.now(),\n timings: {\n normalization: j,\n discovery: N,\n filtering: K,\n total: H\n }\n });\n};\nasync function discoverFiles(e, t, r) {\n if (r) {\n n('scanner', 'Git repository detected. Using fast Git discovery...');\n let r = await p(e.rootDir);\n if (0 === r.length) {\n n('scanner', 'Git discovery returned 0 files — this may indicate a git command failure. Falling back to glob-based scanning.');\n let r = await f(t, e.rootDir, {\n followSymlinks: e.followSymlinks,\n dot: e.dot\n });\n return r.ok && n('scanner', `Glob fallback found ${r.data.files.length} files`), r.ok ? o(r.data.files) : r;\n }\n let i = u(r, t.include, t.ignore, e.rootDir);\n return n('scanner', `Git discovery found ${i.length} files (after glob filtering)`), o(i);\n }\n n('scanner', 'Not a Git repository. Falling back to standard globbing...');\n let i = await f(t, e.rootDir, {\n followSymlinks: e.followSymlinks,\n dot: e.dot\n });\n return i.ok && n('scanner', `Glob found ${i.data.files.length} files`), i.ok ? o(i.data.files) : i;\n}\nasync function getCacheKey(e, t, r, n) {\n if (!n.cache) return null;\n let i = r ? await h(e.rootDir) : await y(e.rootDir);\n return i ? n.cache.computeHash([\n e.rootDir,\n JSON.stringify(t),\n i,\n 'v1'\n ].join('|')) : null;\n}\nasync function tryLoadFromCache(e, t, r, i) {\n let a = await getCacheKey(e, t, r, i);\n if (!a || !i.cache) return null;\n let o = await i.cache.files.get(a);\n return o ? (n('scanner', `Cache HIT. Loaded ${o.files.length} files.`), o.files) : null;\n}\nasync function saveToCache(e, t, r, i, a) {\n if (!a.cache || 0 === r.length) return;\n let o = await getCacheKey(e, t, i, a);\n o && (await a.cache.files.set(o, r), n('scanner', 'File list cached.'));\n}\nasync function buildCachedResult(e, t) {\n let r = await g(e, t, !0), n = performance.now() - t;\n return o({\n files: e,\n stats: r,\n timestamp: Date.now(),\n timings: {\n normalization: 0,\n discovery: n,\n filtering: 0,\n total: n\n }\n });\n}\nfunction logAndReturnError(e, t) {\n let r = a('file-scan');\n n('scanner', `${e} failed after ${r.toFixed(1)}ms: ${t.message}`);\n}\nasync function loadTsConfigPatterns(e, i) {\n try {\n let n = (await t(e, 'utf-8')).replace(/\\/\\/[^\\n]*/g, '').replace(/\\/\\*[\\s\\S]*?\\*\\//g, ''), a = JSON.parse(n), o = r.dirname(r.resolve(e)), l = (e)=>{\n let t = r.resolve(o, e);\n return r.relative(i, t).replace(/\\\\/g, '/');\n }, s = [], c = [];\n return Array.isArray(a.include) && s.push(...a.include.map(l)), Array.isArray(a.files) && s.push(...a.files.map(l)), Array.isArray(a.exclude) && c.push(...a.exclude.map(l)), {\n include: s,\n exclude: c\n };\n } catch (t) {\n return n('scanner', `Failed to load tsconfig patterns from ${e}: ${t instanceof Error ? t.message : String(t)}`), null;\n }\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ngcompass/scanner",
|
|
3
|
+
"version": "0.1.1-beta",
|
|
4
|
+
"description": "File system scanning (glob, git, gitignore) for ngcompass",
|
|
5
|
+
"sideEffects": false,
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"type": "module",
|
|
10
|
+
"engines": {
|
|
11
|
+
"node": "^20.19.0 || >=22.12.0"
|
|
12
|
+
},
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js",
|
|
17
|
+
"require": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"ignore": "^7.0.3",
|
|
25
|
+
"minimatch": "^10.2.4",
|
|
26
|
+
"tinyglobby": "^0.2.15",
|
|
27
|
+
"@ngcompass/cache": "0.1.1-beta",
|
|
28
|
+
"@ngcompass/common": "0.1.1-beta"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"typescript": "5.9.3"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^25.1.0"
|
|
35
|
+
},
|
|
36
|
+
"keywords": [
|
|
37
|
+
"angular",
|
|
38
|
+
"scanner",
|
|
39
|
+
"glob",
|
|
40
|
+
"ngcompass"
|
|
41
|
+
],
|
|
42
|
+
"author": "ngcompass",
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsup",
|
|
49
|
+
"build:prod": "tsup --minify",
|
|
50
|
+
"dev": "tsup --watch",
|
|
51
|
+
"test": "vitest run --passWithNoTests",
|
|
52
|
+
"test:watch": "vitest --passWithNoTests",
|
|
53
|
+
"typecheck": "tsc --noEmit",
|
|
54
|
+
"clean": "rimraf dist .turbo"
|
|
55
|
+
}
|
|
56
|
+
}
|