file-entry-cache
Advanced tools
+1
-1
@@ -1,1 +0,1 @@ | ||
| "use strict";var k=Object.create;var g=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var v=Object.getPrototypeOf,z=Object.prototype.hasOwnProperty;var D=(o,e)=>{for(var s in e)g(o,s,{get:e[s],enumerable:!0})},b=(o,e,s,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of w(e))!z.call(o,t)&&t!==s&&g(o,t,{get:()=>e[t],enumerable:!(i=C(e,t))||i.enumerable});return o};var p=(o,e,s)=>(s=o!=null?k(v(o)):{},b(e||!o||!o.__esModule?g(s,"default",{value:o,enumerable:!0}):s,o)),S=o=>b(g({},"__esModule",{value:!0}),o);var A={};D(A,{FileEntryCache:()=>m,create:()=>f,createFromFile:()=>_,default:()=>d});module.exports=S(A);var y=p(require("crypto"),1),u=p(require("fs"),1),n=p(require("path"),1),l=require("flat-cache");function _(o,e,s){let i=n.default.basename(o),t=n.default.dirname(o);return f(i,t,e,s)}function f(o,e,s,i){let t={useCheckSum:s,cwd:i,cache:{cacheId:o,cacheDir:e}},r=new m(t);if(e){let c=`${e}/${o}`;u.default.existsSync(c)&&(r.cache=(0,l.createFromFile)(c,t.cache))}return r}var d=class{static create=f;static createFromFile=_},m=class{_cache=new l.FlatCache({useClone:!1});_useCheckSum=!1;_hashAlgorithm="md5";_cwd=process.cwd();_strictPaths=!0;_logger;constructor(e){e?.cache&&(this._cache=new l.FlatCache(e.cache)),e?.useCheckSum&&(this._useCheckSum=e.useCheckSum),e?.hashAlgorithm&&(this._hashAlgorithm=e.hashAlgorithm),e?.cwd&&(this._cwd=e.cwd),e?.strictPaths!==void 0&&(this._strictPaths=e.strictPaths),e?.logger&&(this._logger=e.logger)}get cache(){return this._cache}set cache(e){this._cache=e}get logger(){return this._logger}set logger(e){this._logger=e}get useCheckSum(){return this._useCheckSum}set useCheckSum(e){this._useCheckSum=e}get hashAlgorithm(){return this._hashAlgorithm}set hashAlgorithm(e){this._hashAlgorithm=e}get cwd(){return this._cwd}set cwd(e){this._cwd=e}get strictPaths(){return this._strictPaths}set strictPaths(e){this._strictPaths=e}getHash(e){return y.default.createHash(this._hashAlgorithm).update(e).digest("hex")}createFileKey(e){return e}isRelativePath(e){return!n.default.isAbsolute(e)}deleteCacheFile(){return this._cache.removeCacheFile()}destroy(){this._cache.destroy()}removeEntry(e){let s=this.createFileKey(e);this._cache.removeKey(s)}reconcile(){let{items:e}=this._cache;for(let s of e)this.getFileDescriptor(s.key).notFound&&this._cache.removeKey(s.key);this._cache.save()}hasFileChanged(e){let s=!1,i=this.getFileDescriptor(e);return(!i.err||!i.notFound)&&i.changed&&(s=!0),s}getFileDescriptor(e,s){this._logger?.debug({filePath:e,options:s},"Getting file descriptor");let i,t={key:this.createFileKey(e),changed:!1,meta:{}};this._logger?.trace({key:t.key},"Created file key");let r=this._cache.getKey(t.key);r?this._logger?.trace({metaCache:r},"Found cached meta"):this._logger?.trace("No cached meta found"),t.meta=r?{...r}:{};let c=this.getAbsolutePath(e);this._logger?.trace({absolutePath:c},"Resolved absolute path");let a=s?.useCheckSum??this._useCheckSum;this._logger?.debug({useCheckSum:a},"Using checksum setting");try{if(i=u.default.statSync(c),t.meta.size=i.size,t.meta.mtime=i.mtime.getTime(),this._logger?.trace({size:t.meta.size,mtime:t.meta.mtime},"Read file stats"),a){let h=u.default.readFileSync(c);t.meta.hash=this.getHash(h),this._logger?.trace({hash:t.meta.hash},"Calculated file hash")}}catch(h){this._logger?.error({filePath:e,error:h},"Error reading file"),this.removeEntry(e);let F=!1;return h.message.includes("ENOENT")&&(F=!0,this._logger?.debug({filePath:e},"File not found")),{key:t.key,err:h,notFound:F,meta:{}}}return r?(a===!1&&r?.mtime!==t.meta?.mtime&&(t.changed=!0,this._logger?.debug({filePath:e,oldMtime:r.mtime,newMtime:t.meta.mtime},"File changed: mtime differs")),r?.size!==t.meta?.size&&(t.changed=!0,this._logger?.debug({filePath:e,oldSize:r.size,newSize:t.meta.size},"File changed: size differs")),a&&r?.hash!==t.meta?.hash&&(t.changed=!0,this._logger?.debug({filePath:e,oldHash:r.hash,newHash:t.meta.hash},"File changed: hash differs")),this._cache.setKey(t.key,t.meta),t.changed?this._logger?.info({filePath:e},"File has changed"):this._logger?.debug({filePath:e},"File unchanged"),t):(t.changed=!0,this._cache.setKey(t.key,t.meta),this._logger?.debug({filePath:e},"File not in cache, marked as changed"),t)}normalizeEntries(e){let s=[];if(e){for(let t of e){let r=this.getFileDescriptor(t);s.push(r)}return s}let i=this.cache.keys();for(let t of i){let r=this.getFileDescriptor(t);!r.notFound&&!r.err&&s.push(r)}return s}analyzeFiles(e){let s={changedFiles:[],notFoundFiles:[],notChangedFiles:[]},i=this.normalizeEntries(e);for(let t of i)t.notFound?s.notFoundFiles.push(t.key):t.changed?s.changedFiles.push(t.key):s.notChangedFiles.push(t.key);return s}getUpdatedFiles(e){let s=[],i=this.normalizeEntries(e);for(let t of i)t.changed&&s.push(t.key);return s}getFileDescriptorsByPath(e){let s=[],i=this._cache.keys();for(let t of i)if(t.startsWith(e)){let r=this.getFileDescriptor(t);s.push(r)}return s}getAbsolutePath(e){if(this.isRelativePath(e)){let s=e.replace(/\0/g,""),i=n.default.resolve(this._cwd,s);if(this._strictPaths){let t=n.default.normalize(i),r=n.default.normalize(this._cwd);if(!(t===r||t.startsWith(r+n.default.sep)))throw new Error(`Path traversal attempt blocked: "${e}" resolves outside of working directory "${this._cwd}"`)}return i}return e}getAbsolutePathWithCwd(e,s){if(this.isRelativePath(e)){let i=e.replace(/\0/g,""),t=n.default.resolve(s,i);if(this._strictPaths){let r=n.default.normalize(t),c=n.default.normalize(s);if(!(r===c||r.startsWith(c+n.default.sep)))throw new Error(`Path traversal attempt blocked: "${e}" resolves outside of working directory "${s}"`)}return t}return e}renameCacheKeys(e,s){let i=this._cache.keys();for(let t of i)if(t.startsWith(e)){let r=t.replace(e,s),c=this._cache.getKey(t);this._cache.removeKey(t),this._cache.setKey(r,c)}}};0&&(module.exports={FileEntryCache,create,createFromFile}); | ||
| "use strict";var k=Object.create;var g=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var v=Object.getPrototypeOf,A=Object.prototype.hasOwnProperty;var z=(o,e)=>{for(var s in e)g(o,s,{get:e[s],enumerable:!0})},y=(o,e,s,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of w(e))!A.call(o,t)&&t!==s&&g(o,t,{get:()=>e[t],enumerable:!(i=C(e,t))||i.enumerable});return o};var p=(o,e,s)=>(s=o!=null?k(v(o)):{},y(e||!o||!o.__esModule?g(s,"default",{value:o,enumerable:!0}):s,o)),D=o=>y(g({},"__esModule",{value:!0}),o);var K={};z(K,{FileEntryCache:()=>m,create:()=>f,createFromFile:()=>_,default:()=>d});module.exports=D(K);var F=p(require("crypto"),1),u=p(require("fs"),1),c=p(require("path"),1),l=require("flat-cache");function _(o,e){let s=c.default.basename(o),i=c.default.dirname(o);return f(s,i,e)}function f(o,e,s){let i={...s,cache:{cacheId:o,cacheDir:e}},t=new m(i);if(e){let r=`${e}/${o}`;u.default.existsSync(r)&&(t.cache=(0,l.createFromFile)(r,i.cache))}return t}var d=class{static create=f;static createFromFile=_},m=class{_cache=new l.FlatCache({useClone:!1});_useCheckSum=!1;_hashAlgorithm="md5";_cwd=process.cwd();_strictPaths=!1;_logger;_useAbsolutePathAsKey=!1;constructor(e){e?.cache&&(this._cache=new l.FlatCache(e.cache)),e?.useCheckSum&&(this._useCheckSum=e.useCheckSum),e?.hashAlgorithm&&(this._hashAlgorithm=e.hashAlgorithm),e?.cwd&&(this._cwd=e.cwd),e?.strictPaths!==void 0&&(this._strictPaths=e.strictPaths),e?.useAbsolutePathAsKey!==void 0&&(this._useAbsolutePathAsKey=e.useAbsolutePathAsKey),e?.logger&&(this._logger=e.logger)}get cache(){return this._cache}set cache(e){this._cache=e}get logger(){return this._logger}set logger(e){this._logger=e}get useCheckSum(){return this._useCheckSum}set useCheckSum(e){this._useCheckSum=e}get hashAlgorithm(){return this._hashAlgorithm}set hashAlgorithm(e){this._hashAlgorithm=e}get cwd(){return this._cwd}set cwd(e){this._cwd=e}get strictPaths(){return this._strictPaths}set strictPaths(e){this._strictPaths=e}get useAbsolutePathAsKey(){return this._useAbsolutePathAsKey}set useAbsolutePathAsKey(e){this._useAbsolutePathAsKey=e}getHash(e){return F.default.createHash(this._hashAlgorithm).update(e).digest("hex")}createFileKey(e){let s=e;return this._useAbsolutePathAsKey&&this.isRelativePath(e)&&(s=this.getAbsolutePathWithCwd(e,this._cwd)),s}isRelativePath(e){return!c.default.isAbsolute(e)}deleteCacheFile(){return this._cache.removeCacheFile()}destroy(){this._cache.destroy()}removeEntry(e){let s=this.createFileKey(e);this._cache.removeKey(s)}reconcile(){let{items:e}=this._cache;for(let s of e)this.getFileDescriptor(s.key).notFound&&this._cache.removeKey(s.key);this._cache.save()}hasFileChanged(e){let s=!1,i=this.getFileDescriptor(e);return(!i.err||!i.notFound)&&i.changed&&(s=!0),s}getFileDescriptor(e,s){this._logger?.debug({filePath:e,options:s},"Getting file descriptor");let i,t={key:this.createFileKey(e),changed:!1,meta:{}};this._logger?.trace({key:t.key},"Created file key");let r=this._cache.getKey(t.key);r?this._logger?.trace({metaCache:r},"Found cached meta"):this._logger?.trace("No cached meta found"),t.meta=r?{...r}:{};let a=this.getAbsolutePath(e);this._logger?.trace({absolutePath:a},"Resolved absolute path");let n=s?.useCheckSum??this._useCheckSum;this._logger?.debug({useCheckSum:n},"Using checksum setting");try{if(i=u.default.statSync(a),t.meta.size=i.size,t.meta.mtime=i.mtime.getTime(),this._logger?.trace({size:t.meta.size,mtime:t.meta.mtime},"Read file stats"),n){let h=u.default.readFileSync(a);t.meta.hash=this.getHash(h),this._logger?.trace({hash:t.meta.hash},"Calculated file hash")}}catch(h){this._logger?.error({filePath:e,error:h},"Error reading file"),this.removeEntry(e);let b=!1;return h.message.includes("ENOENT")&&(b=!0,this._logger?.debug({filePath:e},"File not found")),{key:t.key,err:h,notFound:b,meta:{}}}return r?(n===!1&&r?.mtime!==t.meta?.mtime&&(t.changed=!0,this._logger?.debug({filePath:e,oldMtime:r.mtime,newMtime:t.meta.mtime},"File changed: mtime differs")),r?.size!==t.meta?.size&&(t.changed=!0,this._logger?.debug({filePath:e,oldSize:r.size,newSize:t.meta.size},"File changed: size differs")),n&&r?.hash!==t.meta?.hash&&(t.changed=!0,this._logger?.debug({filePath:e,oldHash:r.hash,newHash:t.meta.hash},"File changed: hash differs")),this._cache.setKey(t.key,t.meta),t.changed?this._logger?.info({filePath:e},"File has changed"):this._logger?.debug({filePath:e},"File unchanged"),t):(t.changed=!0,this._cache.setKey(t.key,t.meta),this._logger?.debug({filePath:e},"File not in cache, marked as changed"),t)}normalizeEntries(e){let s=[];if(e){for(let t of e){let r=this.getFileDescriptor(t);s.push(r)}return s}let i=this.cache.keys();for(let t of i){let r=this.getFileDescriptor(t);!r.notFound&&!r.err&&s.push(r)}return s}analyzeFiles(e){let s={changedFiles:[],notFoundFiles:[],notChangedFiles:[]},i=this.normalizeEntries(e);for(let t of i)t.notFound?s.notFoundFiles.push(t.key):t.changed?s.changedFiles.push(t.key):s.notChangedFiles.push(t.key);return s}getUpdatedFiles(e){let s=[],i=this.normalizeEntries(e);for(let t of i)t.changed&&s.push(t.key);return s}getFileDescriptorsByPath(e){let s=[],i=this._cache.keys();for(let t of i)if(t.startsWith(e)){let r=this.getFileDescriptor(t);s.push(r)}return s}getAbsolutePath(e){if(this.isRelativePath(e)){let s=e.replace(/\0/g,""),i=c.default.resolve(this._cwd,s);if(this._strictPaths){let t=c.default.normalize(i),r=c.default.normalize(this._cwd);if(!(t===r||t.startsWith(r+c.default.sep)))throw new Error(`Path traversal attempt blocked: "${e}" resolves outside of working directory "${this._cwd}"`)}return i}return e}getAbsolutePathWithCwd(e,s){if(this.isRelativePath(e)){let i=e.replace(/\0/g,""),t=c.default.resolve(s,i);if(this._strictPaths){let r=c.default.normalize(t),a=c.default.normalize(s);if(!(r===a||r.startsWith(a+c.default.sep)))throw new Error(`Path traversal attempt blocked: "${e}" resolves outside of working directory "${s}"`)}return t}return e}renameCacheKeys(e,s){let i=this._cache.keys();for(let t of i)if(t.startsWith(e)){let r=t.replace(e,s),a=this._cache.getKey(t);this._cache.removeKey(t),this._cache.setKey(r,a)}}};0&&(module.exports={FileEntryCache,create,createFromFile}); |
+19
-7
@@ -31,2 +31,4 @@ import { Buffer } from 'node:buffer'; | ||
| strictPaths?: boolean; | ||
| /** Whether to use absolute path as cache key (default: false) */ | ||
| useAbsolutePathAsKey?: boolean; | ||
| /** Logger instance for logging (default: undefined) */ | ||
@@ -76,7 +78,7 @@ logger?: ILogger; | ||
| * @param filePath - The path to the cache file | ||
| * @param useCheckSum - Whether to use checksum to detect file changes (default: false) | ||
| * @param cwd - The current working directory for resolving relative paths (default: process.cwd()) | ||
| * @param options - create options such as useChecksum, cwd, and more | ||
| * @returns A new FileEntryCache instance | ||
| */ | ||
| declare function createFromFile(filePath: string, useCheckSum?: boolean, cwd?: string): FileEntryCache; | ||
| declare function createFromFile(filePath: string, options?: CreateOptions): FileEntryCache; | ||
| type CreateOptions = Omit<FileEntryCacheOptions, "cache">; | ||
| /** | ||
@@ -86,7 +88,6 @@ * Create a new FileEntryCache instance | ||
| * @param cacheDirectory - The directory to store the cache file (default: undefined, cache won't be persisted) | ||
| * @param useCheckSum - Whether to use checksum to detect file changes (default: false) | ||
| * @param cwd - The current working directory for resolving relative paths (default: process.cwd()) | ||
| * @param options - Whether to use checksum to detect file changes (default: false) | ||
| * @returns A new FileEntryCache instance | ||
| */ | ||
| declare function create(cacheId: string, cacheDirectory?: string, useCheckSum?: boolean, cwd?: string): FileEntryCache; | ||
| declare function create(cacheId: string, cacheDirectory?: string, options?: CreateOptions): FileEntryCache; | ||
| declare class FileEntryDefault { | ||
@@ -103,2 +104,3 @@ static create: typeof create; | ||
| private _logger?; | ||
| private _useAbsolutePathAsKey; | ||
| /** | ||
@@ -170,2 +172,12 @@ * Create a new FileEntryCache instance | ||
| /** | ||
| * Get whether to use absolute path as cache key | ||
| * @returns {boolean} Whether cache keys use absolute paths (default: false) | ||
| */ | ||
| get useAbsolutePathAsKey(): boolean; | ||
| /** | ||
| * Set whether to use absolute path as cache key | ||
| * @param {boolean} value - The value to set | ||
| */ | ||
| set useAbsolutePathAsKey(value: boolean); | ||
| /** | ||
| * Given a buffer, calculate md5 hash of its content. | ||
@@ -284,2 +296,2 @@ * @method getHash | ||
| export { type AnalyzedFiles, type FileDescriptor, type FileDescriptorMeta, FileEntryCache, type FileEntryCacheOptions, type GetFileDescriptorOptions, type ILogger, create, createFromFile, FileEntryDefault as default }; | ||
| export { type AnalyzedFiles, type CreateOptions, type FileDescriptor, type FileDescriptorMeta, FileEntryCache, type FileEntryCacheOptions, type GetFileDescriptorOptions, type ILogger, create, createFromFile, FileEntryDefault as default }; |
+19
-7
@@ -31,2 +31,4 @@ import { Buffer } from 'node:buffer'; | ||
| strictPaths?: boolean; | ||
| /** Whether to use absolute path as cache key (default: false) */ | ||
| useAbsolutePathAsKey?: boolean; | ||
| /** Logger instance for logging (default: undefined) */ | ||
@@ -76,7 +78,7 @@ logger?: ILogger; | ||
| * @param filePath - The path to the cache file | ||
| * @param useCheckSum - Whether to use checksum to detect file changes (default: false) | ||
| * @param cwd - The current working directory for resolving relative paths (default: process.cwd()) | ||
| * @param options - create options such as useChecksum, cwd, and more | ||
| * @returns A new FileEntryCache instance | ||
| */ | ||
| declare function createFromFile(filePath: string, useCheckSum?: boolean, cwd?: string): FileEntryCache; | ||
| declare function createFromFile(filePath: string, options?: CreateOptions): FileEntryCache; | ||
| type CreateOptions = Omit<FileEntryCacheOptions, "cache">; | ||
| /** | ||
@@ -86,7 +88,6 @@ * Create a new FileEntryCache instance | ||
| * @param cacheDirectory - The directory to store the cache file (default: undefined, cache won't be persisted) | ||
| * @param useCheckSum - Whether to use checksum to detect file changes (default: false) | ||
| * @param cwd - The current working directory for resolving relative paths (default: process.cwd()) | ||
| * @param options - Whether to use checksum to detect file changes (default: false) | ||
| * @returns A new FileEntryCache instance | ||
| */ | ||
| declare function create(cacheId: string, cacheDirectory?: string, useCheckSum?: boolean, cwd?: string): FileEntryCache; | ||
| declare function create(cacheId: string, cacheDirectory?: string, options?: CreateOptions): FileEntryCache; | ||
| declare class FileEntryDefault { | ||
@@ -103,2 +104,3 @@ static create: typeof create; | ||
| private _logger?; | ||
| private _useAbsolutePathAsKey; | ||
| /** | ||
@@ -170,2 +172,12 @@ * Create a new FileEntryCache instance | ||
| /** | ||
| * Get whether to use absolute path as cache key | ||
| * @returns {boolean} Whether cache keys use absolute paths (default: false) | ||
| */ | ||
| get useAbsolutePathAsKey(): boolean; | ||
| /** | ||
| * Set whether to use absolute path as cache key | ||
| * @param {boolean} value - The value to set | ||
| */ | ||
| set useAbsolutePathAsKey(value: boolean); | ||
| /** | ||
| * Given a buffer, calculate md5 hash of its content. | ||
@@ -284,2 +296,2 @@ * @method getHash | ||
| export { type AnalyzedFiles, type FileDescriptor, type FileDescriptorMeta, FileEntryCache, type FileEntryCacheOptions, type GetFileDescriptorOptions, type ILogger, create, createFromFile, FileEntryDefault as default }; | ||
| export { type AnalyzedFiles, type CreateOptions, type FileDescriptor, type FileDescriptorMeta, FileEntryCache, type FileEntryCacheOptions, type GetFileDescriptorOptions, type ILogger, create, createFromFile, FileEntryDefault as default }; |
+1
-1
@@ -1,1 +0,1 @@ | ||
| import f from"crypto";import l from"fs";import c from"path";import{createFromFile as F,FlatCache as m}from"flat-cache";function b(n,e,s){let r=c.basename(n),t=c.dirname(n);return p(r,t,e,s)}function p(n,e,s,r){let t={useCheckSum:s,cwd:r,cache:{cacheId:n,cacheDir:e}},i=new u(t);if(e){let o=`${e}/${n}`;l.existsSync(o)&&(i.cache=F(o,t.cache))}return i}var g=class{static create=p;static createFromFile=b},u=class{_cache=new m({useClone:!1});_useCheckSum=!1;_hashAlgorithm="md5";_cwd=process.cwd();_strictPaths=!0;_logger;constructor(e){e?.cache&&(this._cache=new m(e.cache)),e?.useCheckSum&&(this._useCheckSum=e.useCheckSum),e?.hashAlgorithm&&(this._hashAlgorithm=e.hashAlgorithm),e?.cwd&&(this._cwd=e.cwd),e?.strictPaths!==void 0&&(this._strictPaths=e.strictPaths),e?.logger&&(this._logger=e.logger)}get cache(){return this._cache}set cache(e){this._cache=e}get logger(){return this._logger}set logger(e){this._logger=e}get useCheckSum(){return this._useCheckSum}set useCheckSum(e){this._useCheckSum=e}get hashAlgorithm(){return this._hashAlgorithm}set hashAlgorithm(e){this._hashAlgorithm=e}get cwd(){return this._cwd}set cwd(e){this._cwd=e}get strictPaths(){return this._strictPaths}set strictPaths(e){this._strictPaths=e}getHash(e){return f.createHash(this._hashAlgorithm).update(e).digest("hex")}createFileKey(e){return e}isRelativePath(e){return!c.isAbsolute(e)}deleteCacheFile(){return this._cache.removeCacheFile()}destroy(){this._cache.destroy()}removeEntry(e){let s=this.createFileKey(e);this._cache.removeKey(s)}reconcile(){let{items:e}=this._cache;for(let s of e)this.getFileDescriptor(s.key).notFound&&this._cache.removeKey(s.key);this._cache.save()}hasFileChanged(e){let s=!1,r=this.getFileDescriptor(e);return(!r.err||!r.notFound)&&r.changed&&(s=!0),s}getFileDescriptor(e,s){this._logger?.debug({filePath:e,options:s},"Getting file descriptor");let r,t={key:this.createFileKey(e),changed:!1,meta:{}};this._logger?.trace({key:t.key},"Created file key");let i=this._cache.getKey(t.key);i?this._logger?.trace({metaCache:i},"Found cached meta"):this._logger?.trace("No cached meta found"),t.meta=i?{...i}:{};let o=this.getAbsolutePath(e);this._logger?.trace({absolutePath:o},"Resolved absolute path");let a=s?.useCheckSum??this._useCheckSum;this._logger?.debug({useCheckSum:a},"Using checksum setting");try{if(r=l.statSync(o),t.meta.size=r.size,t.meta.mtime=r.mtime.getTime(),this._logger?.trace({size:t.meta.size,mtime:t.meta.mtime},"Read file stats"),a){let h=l.readFileSync(o);t.meta.hash=this.getHash(h),this._logger?.trace({hash:t.meta.hash},"Calculated file hash")}}catch(h){this._logger?.error({filePath:e,error:h},"Error reading file"),this.removeEntry(e);let d=!1;return h.message.includes("ENOENT")&&(d=!0,this._logger?.debug({filePath:e},"File not found")),{key:t.key,err:h,notFound:d,meta:{}}}return i?(a===!1&&i?.mtime!==t.meta?.mtime&&(t.changed=!0,this._logger?.debug({filePath:e,oldMtime:i.mtime,newMtime:t.meta.mtime},"File changed: mtime differs")),i?.size!==t.meta?.size&&(t.changed=!0,this._logger?.debug({filePath:e,oldSize:i.size,newSize:t.meta.size},"File changed: size differs")),a&&i?.hash!==t.meta?.hash&&(t.changed=!0,this._logger?.debug({filePath:e,oldHash:i.hash,newHash:t.meta.hash},"File changed: hash differs")),this._cache.setKey(t.key,t.meta),t.changed?this._logger?.info({filePath:e},"File has changed"):this._logger?.debug({filePath:e},"File unchanged"),t):(t.changed=!0,this._cache.setKey(t.key,t.meta),this._logger?.debug({filePath:e},"File not in cache, marked as changed"),t)}normalizeEntries(e){let s=[];if(e){for(let t of e){let i=this.getFileDescriptor(t);s.push(i)}return s}let r=this.cache.keys();for(let t of r){let i=this.getFileDescriptor(t);!i.notFound&&!i.err&&s.push(i)}return s}analyzeFiles(e){let s={changedFiles:[],notFoundFiles:[],notChangedFiles:[]},r=this.normalizeEntries(e);for(let t of r)t.notFound?s.notFoundFiles.push(t.key):t.changed?s.changedFiles.push(t.key):s.notChangedFiles.push(t.key);return s}getUpdatedFiles(e){let s=[],r=this.normalizeEntries(e);for(let t of r)t.changed&&s.push(t.key);return s}getFileDescriptorsByPath(e){let s=[],r=this._cache.keys();for(let t of r)if(t.startsWith(e)){let i=this.getFileDescriptor(t);s.push(i)}return s}getAbsolutePath(e){if(this.isRelativePath(e)){let s=e.replace(/\0/g,""),r=c.resolve(this._cwd,s);if(this._strictPaths){let t=c.normalize(r),i=c.normalize(this._cwd);if(!(t===i||t.startsWith(i+c.sep)))throw new Error(`Path traversal attempt blocked: "${e}" resolves outside of working directory "${this._cwd}"`)}return r}return e}getAbsolutePathWithCwd(e,s){if(this.isRelativePath(e)){let r=e.replace(/\0/g,""),t=c.resolve(s,r);if(this._strictPaths){let i=c.normalize(t),o=c.normalize(s);if(!(i===o||i.startsWith(o+c.sep)))throw new Error(`Path traversal attempt blocked: "${e}" resolves outside of working directory "${s}"`)}return t}return e}renameCacheKeys(e,s){let r=this._cache.keys();for(let t of r)if(t.startsWith(e)){let i=t.replace(e,s),o=this._cache.getKey(t);this._cache.removeKey(t),this._cache.setKey(i,o)}}};export{u as FileEntryCache,p as create,b as createFromFile,g as default}; | ||
| import f from"crypto";import l from"fs";import o from"path";import{createFromFile as b,FlatCache as m}from"flat-cache";function y(a,e){let s=o.basename(a),r=o.dirname(a);return p(s,r,e)}function p(a,e,s){let r={...s,cache:{cacheId:a,cacheDir:e}},t=new u(r);if(e){let i=`${e}/${a}`;l.existsSync(i)&&(t.cache=b(i,r.cache))}return t}var g=class{static create=p;static createFromFile=y},u=class{_cache=new m({useClone:!1});_useCheckSum=!1;_hashAlgorithm="md5";_cwd=process.cwd();_strictPaths=!1;_logger;_useAbsolutePathAsKey=!1;constructor(e){e?.cache&&(this._cache=new m(e.cache)),e?.useCheckSum&&(this._useCheckSum=e.useCheckSum),e?.hashAlgorithm&&(this._hashAlgorithm=e.hashAlgorithm),e?.cwd&&(this._cwd=e.cwd),e?.strictPaths!==void 0&&(this._strictPaths=e.strictPaths),e?.useAbsolutePathAsKey!==void 0&&(this._useAbsolutePathAsKey=e.useAbsolutePathAsKey),e?.logger&&(this._logger=e.logger)}get cache(){return this._cache}set cache(e){this._cache=e}get logger(){return this._logger}set logger(e){this._logger=e}get useCheckSum(){return this._useCheckSum}set useCheckSum(e){this._useCheckSum=e}get hashAlgorithm(){return this._hashAlgorithm}set hashAlgorithm(e){this._hashAlgorithm=e}get cwd(){return this._cwd}set cwd(e){this._cwd=e}get strictPaths(){return this._strictPaths}set strictPaths(e){this._strictPaths=e}get useAbsolutePathAsKey(){return this._useAbsolutePathAsKey}set useAbsolutePathAsKey(e){this._useAbsolutePathAsKey=e}getHash(e){return f.createHash(this._hashAlgorithm).update(e).digest("hex")}createFileKey(e){let s=e;return this._useAbsolutePathAsKey&&this.isRelativePath(e)&&(s=this.getAbsolutePathWithCwd(e,this._cwd)),s}isRelativePath(e){return!o.isAbsolute(e)}deleteCacheFile(){return this._cache.removeCacheFile()}destroy(){this._cache.destroy()}removeEntry(e){let s=this.createFileKey(e);this._cache.removeKey(s)}reconcile(){let{items:e}=this._cache;for(let s of e)this.getFileDescriptor(s.key).notFound&&this._cache.removeKey(s.key);this._cache.save()}hasFileChanged(e){let s=!1,r=this.getFileDescriptor(e);return(!r.err||!r.notFound)&&r.changed&&(s=!0),s}getFileDescriptor(e,s){this._logger?.debug({filePath:e,options:s},"Getting file descriptor");let r,t={key:this.createFileKey(e),changed:!1,meta:{}};this._logger?.trace({key:t.key},"Created file key");let i=this._cache.getKey(t.key);i?this._logger?.trace({metaCache:i},"Found cached meta"):this._logger?.trace("No cached meta found"),t.meta=i?{...i}:{};let c=this.getAbsolutePath(e);this._logger?.trace({absolutePath:c},"Resolved absolute path");let n=s?.useCheckSum??this._useCheckSum;this._logger?.debug({useCheckSum:n},"Using checksum setting");try{if(r=l.statSync(c),t.meta.size=r.size,t.meta.mtime=r.mtime.getTime(),this._logger?.trace({size:t.meta.size,mtime:t.meta.mtime},"Read file stats"),n){let h=l.readFileSync(c);t.meta.hash=this.getHash(h),this._logger?.trace({hash:t.meta.hash},"Calculated file hash")}}catch(h){this._logger?.error({filePath:e,error:h},"Error reading file"),this.removeEntry(e);let d=!1;return h.message.includes("ENOENT")&&(d=!0,this._logger?.debug({filePath:e},"File not found")),{key:t.key,err:h,notFound:d,meta:{}}}return i?(n===!1&&i?.mtime!==t.meta?.mtime&&(t.changed=!0,this._logger?.debug({filePath:e,oldMtime:i.mtime,newMtime:t.meta.mtime},"File changed: mtime differs")),i?.size!==t.meta?.size&&(t.changed=!0,this._logger?.debug({filePath:e,oldSize:i.size,newSize:t.meta.size},"File changed: size differs")),n&&i?.hash!==t.meta?.hash&&(t.changed=!0,this._logger?.debug({filePath:e,oldHash:i.hash,newHash:t.meta.hash},"File changed: hash differs")),this._cache.setKey(t.key,t.meta),t.changed?this._logger?.info({filePath:e},"File has changed"):this._logger?.debug({filePath:e},"File unchanged"),t):(t.changed=!0,this._cache.setKey(t.key,t.meta),this._logger?.debug({filePath:e},"File not in cache, marked as changed"),t)}normalizeEntries(e){let s=[];if(e){for(let t of e){let i=this.getFileDescriptor(t);s.push(i)}return s}let r=this.cache.keys();for(let t of r){let i=this.getFileDescriptor(t);!i.notFound&&!i.err&&s.push(i)}return s}analyzeFiles(e){let s={changedFiles:[],notFoundFiles:[],notChangedFiles:[]},r=this.normalizeEntries(e);for(let t of r)t.notFound?s.notFoundFiles.push(t.key):t.changed?s.changedFiles.push(t.key):s.notChangedFiles.push(t.key);return s}getUpdatedFiles(e){let s=[],r=this.normalizeEntries(e);for(let t of r)t.changed&&s.push(t.key);return s}getFileDescriptorsByPath(e){let s=[],r=this._cache.keys();for(let t of r)if(t.startsWith(e)){let i=this.getFileDescriptor(t);s.push(i)}return s}getAbsolutePath(e){if(this.isRelativePath(e)){let s=e.replace(/\0/g,""),r=o.resolve(this._cwd,s);if(this._strictPaths){let t=o.normalize(r),i=o.normalize(this._cwd);if(!(t===i||t.startsWith(i+o.sep)))throw new Error(`Path traversal attempt blocked: "${e}" resolves outside of working directory "${this._cwd}"`)}return r}return e}getAbsolutePathWithCwd(e,s){if(this.isRelativePath(e)){let r=e.replace(/\0/g,""),t=o.resolve(s,r);if(this._strictPaths){let i=o.normalize(t),c=o.normalize(s);if(!(i===c||i.startsWith(c+o.sep)))throw new Error(`Path traversal attempt blocked: "${e}" resolves outside of working directory "${s}"`)}return t}return e}renameCacheKeys(e,s){let r=this._cache.keys();for(let t of r)if(t.startsWith(e)){let i=t.replace(e,s),c=this._cache.getKey(t);this._cache.removeKey(t),this._cache.setKey(i,c)}}};export{u as FileEntryCache,p as create,y as createFromFile,g as default}; |
+2
-2
| { | ||
| "name": "file-entry-cache", | ||
| "version": "11.0.0-beta.4", | ||
| "version": "11.0.0-beta.5", | ||
| "description": "A lightweight cache for file metadata, ideal for processes that work on a specific set of files and only need to reprocess files that have changed since the last run", | ||
@@ -33,3 +33,3 @@ "type": "module", | ||
| "@biomejs/biome": "^2.2.5", | ||
| "@types/node": "^24.7.0", | ||
| "@types/node": "^24.7.1", | ||
| "@vitest/coverage-v8": "^3.2.4", | ||
@@ -36,0 +36,0 @@ "pino": "^10.0.0", |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
60097
2.18%334
4.38%0
-100%