You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If you were using absolute paths with `currentWorkingDirectory`, you'll need to update your code to use relative paths if you want portable cache files.
103
87
104
88
# Changes from v10 to v11
105
89
106
90
**BREAKING CHANGES:**
107
-
-**Removed `currentWorkingDirectory`** - This option has been completely removed from the API. Paths are now stored exactly as provided (relative or absolute).
108
-
-**Path handling changes** - The cache now stores paths exactly as they are provided:
109
-
- Relative paths remain relative in the cache
110
-
- Absolute paths remain absolute in the cache
111
-
- The same file accessed with different path formats will create separate cache entries
112
-
-**Renamed method** - `renameAbsolutePathKeys()` is now `renameCacheKeys()` to reflect that it works with any path format
113
-
-**Simplified API** - Removed `currentWorkingDirectory` parameter from all methods including `getFileDescriptor()`, `removeEntry()`, and factory functions
91
+
-**`strictPaths` now defaults to `true`** - Path traversal protection is enabled by default for security. To restore v10 behavior, explicitly set `strictPaths: false`
114
92
115
-
These changes make cache files portable when using relative paths, and simplify the API by removing path manipulation logic.
93
+
**NEW FEATURES:**
94
+
-**Added `cwd` option** - You can now specify a custom current working directory for resolving relative paths
95
+
-**Added `strictPaths` option** - Provides protection against path traversal attacks (enabled by default)
96
+
-**Improved cache portability** - When using relative paths with the same `cwd`, cache files are portable across different environments
116
97
117
98
# Changes from v9 to v10
118
99
@@ -127,13 +108,15 @@ There have been many features added and changes made to the `file-entry-cache` c
127
108
- On `FileEntryDescriptor.meta` if using typescript you need to use the `meta.data` to set additional information. This is to allow for better type checking and to avoid conflicts with the `meta` object which was `any`.
128
109
129
110
# Global Default Functions
130
-
-`create(cacheId: string, cacheDirectory?: string, useCheckSum?: boolean)` - Creates a new instance of the `FileEntryCache` class
131
-
-`createFromFile(cachePath: string, useCheckSum?: boolean)` - Creates a new instance of the `FileEntryCache` class and loads the cache from a file.
111
+
-`create(cacheId: string, cacheDirectory?: string, useCheckSum?: boolean, cwd?: string)` - Creates a new instance of the `FileEntryCache` class
112
+
-`createFromFile(cachePath: string, useCheckSum?: boolean, cwd?: string)` - Creates a new instance of the `FileEntryCache` class and loads the cache from a file.
132
113
133
114
# FileEntryCache Options (FileEntryCacheOptions)
134
115
-`useModifiedTime?` - If `true` it will use the modified time to determine if the file has changed. Default is `true`
135
116
-`useCheckSum?` - If `true` it will use a checksum to determine if the file has changed. Default is `false`
136
117
-`hashAlgorithm?` - The algorithm to use for the checksum. Default is `md5` but can be any algorithm supported by `crypto.createHash`
118
+
-`cwd?` - The current working directory for resolving relative paths. Default is `process.cwd()`
119
+
-`strictPaths?` - If `true` restricts file access to within `cwd` boundaries, preventing path traversal attacks. Default is `true`
137
120
-`cache.ttl?` - The time to live for the cache in milliseconds. Default is `0` which means no expiration
138
121
-`cache.lruSize?` - The number of items to keep in the cache. Default is `0` which means no limit
139
122
-`cache.useClone?` - If `true` it will clone the data before returning it. Default is `false`
@@ -150,17 +133,21 @@ There have been many features added and changes made to the `file-entry-cache` c
150
133
-`useCheckSum: boolean` - If `true` it will use a checksum to determine if the file has changed. Default is `false`
151
134
-`hashAlgorithm: string` - The algorithm to use for the checksum. Default is `md5` but can be any algorithm supported by `crypto.createHash`
152
135
-`getHash(buffer: Buffer): string` - Gets the hash of a buffer used for checksums
136
+
-`cwd: string` - The current working directory for resolving relative paths. Default is `process.cwd()`
137
+
-`strictPaths: boolean` - If `true` restricts file access to within `cwd` boundaries. Default is `true`
153
138
-`createFileKey(filePath: string): string` - Returns the cache key for the file path (returns the path exactly as provided).
154
139
-`deleteCacheFile(): boolean` - Deletes the cache file from disk
155
140
-`destroy(): void` - Destroys the cache. This will clear the cache in memory. If using cache persistence it will stop the interval.
156
-
-`removeEntry(filePath: string): void` - Removes an entry from the cache using the exact path provided.
141
+
-`removeEntry(filePath: string): void` - Removes an entry from the cache.
157
142
-`reconcile(): void` - Saves the cache to disk and removes any files that are no longer found.
158
143
-`hasFileChanged(filePath: string): boolean` - Checks if the file has changed. This will return `true` if the file has changed.
159
144
-`getFileDescriptor(filePath: string, options?: { useModifiedTime?: boolean, useCheckSum?: boolean }): FileEntryDescriptor` - Gets the file descriptor for the file. Please refer to the entire section on `Get File Descriptor` for more information.
160
-
-`normalizeEntries(entries: FileEntryDescriptor[]): FileEntryDescriptor[]` - Normalizes the entries to have the correct paths. This is used when loading the cache from disk.
145
+
-`normalizeEntries(files?: string[]): FileDescriptor[]` - Normalizes the entries. If no files are provided, it will return all cached entries.
161
146
-`analyzeFiles(files: string[])` will return `AnalyzedFiles` object with `changedFiles`, `notFoundFiles`, and `notChangedFiles` as FileDescriptor arrays.
162
147
-`getUpdatedFiles(files: string[])` will return an array of `FileEntryDescriptor` objects that have changed.
163
148
-`getFileDescriptorsByPath(filePath: string): FileEntryDescriptor[]` will return an array of `FileEntryDescriptor` objects that starts with the path prefix specified.
149
+
-`getAbsolutePath(filePath: string): string` - Resolves a relative path to absolute using the configured `cwd`. Returns absolute paths unchanged. When `strictPaths` is enabled, throws an error if the path resolves outside `cwd`.
150
+
-`getAbsolutePathWithCwd(filePath: string, cwd: string): string` - Resolves a relative path to absolute using a custom working directory. When `strictPaths` is enabled, throws an error if the path resolves outside the provided `cwd`.
-`meta: FileEntryMeta` - The meta data for the file. This has the following properties: `size`, `mtime`, `hash`, `data`. Note that `data` is an object that can be used to store additional information.
173
160
-`err` - If there was an error analyzing the file.
174
161
175
-
## Path Handling
162
+
## Path Handling and Current Working Directory
163
+
164
+
The cache stores paths exactly as they are provided (relative or absolute). When checking if files have changed, relative paths are resolved using the configured `cwd` (current working directory):
// But file operations resolve from: '/project/root/src/file.txt'
179
+
```
176
180
177
-
The cache stores paths exactly as they are provided:
181
+
### Cache Portability
178
182
179
-
-**Relative paths** remain relative in the cache
180
-
-**Absolute paths** remain absolute in the cache
181
-
- The same file accessed with different path formats creates **separate cache entries**
183
+
Using relative paths with a consistent `cwd` (defaults to `process.cwd()`) makes cache files portable across different machines and environments. This is especially useful for CI/CD pipelines and team development.
For maximum cache portability across different environments, use checksums (`useCheckSum: true`) along with relative paths and `cwd` which defaults to `process.cwd()`. This ensures that cache validity is determined by file content rather than modification times, which can vary across systems:
194
200
195
-
// These create two separate cache entries even though they refer to the same file
cache2.getFileDescriptor('./src/app.js'); // Still finds cached entry!
246
+
// Cache valid as long as relative structure unchanged
247
+
```
199
248
200
-
If there is an error when trying to get the file descriptor it will return an ``notFound` and `err` property with the error.
249
+
If there is an error when trying to get the file descriptor it will return a `notFound` and `err` property with the error.
201
250
202
251
```javascript
203
252
constfileEntryCache=newFileEntryCache();
@@ -211,6 +260,124 @@ if (fileDescriptor.notFound) {
211
260
}
212
261
```
213
262
263
+
# Path Security and Traversal Prevention
264
+
265
+
The `strictPaths` option provides security against path traversal attacks by restricting file access to within the configured `cwd` boundaries. **This is enabled by default (since v11)** to ensure secure defaults when processing untrusted input or when running in security-sensitive environments.
**As of v11, `strictPaths` is enabled by default** to provide secure defaults. This means:
364
+
- Path traversal attempts using `../` are blocked
365
+
- File access is restricted to within the configured `cwd`
366
+
- Null bytes in paths are automatically sanitized
367
+
368
+
### Migrating from v10 or Earlier
369
+
370
+
If you're upgrading from v10 or earlier and need to maintain the previous behavior (for example, if your code legitimately accesses parent directories), you can explicitly disable strict paths:
371
+
372
+
```javascript
373
+
constcache=newFileEntryCache({
374
+
cwd:process.cwd(),
375
+
strictPaths:false// Restore v10 behavior
376
+
});
377
+
```
378
+
379
+
However, we strongly recommend keeping `strictPaths: true` and adjusting your code to work within the security boundaries, especially when processing any untrusted input.
380
+
214
381
# Using Checksums to Determine if a File has Changed (useCheckSum)
215
382
216
383
By default the `useCheckSum` is `false`. This means that the `FileEntryCache` will use the `mtime` and `ctime` to determine if the file has changed. If you set `useCheckSum` to `true` it will use a checksum to determine if the file has changed. This is useful when you want to make sure that the file has not changed at all.
0 commit comments