@outfitter/file-ops 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +7 -347
- package/dist/index.js +6 -555
- package/dist/internal/atomic-write.d.ts +3 -0
- package/dist/internal/atomic-write.js +54 -0
- package/dist/internal/glob.d.ts +3 -0
- package/dist/internal/glob.js +95 -0
- package/dist/internal/locking.d.ts +3 -0
- package/dist/internal/locking.js +13 -0
- package/dist/internal/security.d.ts +2 -0
- package/dist/internal/security.js +76 -0
- package/dist/internal/shared-locking.d.ts +3 -0
- package/dist/internal/shared-locking.js +180 -0
- package/dist/internal/types.d.ts +2 -0
- package/dist/internal/types.js +1 -0
- package/dist/internal/workspace.d.ts +3 -0
- package/dist/internal/workspace.js +61 -0
- package/dist/shared/@outfitter/file-ops-3kzghhjm.d.ts +32 -0
- package/dist/shared/@outfitter/file-ops-48jsfdy3.js +104 -0
- package/dist/shared/@outfitter/file-ops-9xg8rjay.d.ts +57 -0
- package/dist/shared/@outfitter/file-ops-b3v6xcnw.d.ts +36 -0
- package/dist/shared/@outfitter/file-ops-cp4q6s4n.d.ts +34 -0
- package/dist/shared/@outfitter/file-ops-cpvpwwsr.d.ts +44 -0
- package/dist/shared/@outfitter/file-ops-f0bv7qk0.d.ts +142 -0
- package/dist/shared/@outfitter/file-ops-ss4da105.d.ts +46 -0
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,348 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Marker files/directories to search for.
|
|
10
|
-
* Search stops when any marker is found at a directory level.
|
|
11
|
-
* @defaultValue [".git", "package.json"]
|
|
12
|
-
*/
|
|
13
|
-
markers?: string[];
|
|
14
|
-
/**
|
|
15
|
-
* Stop searching at this directory boundary.
|
|
16
|
-
* The search will not continue above this path.
|
|
17
|
-
* @defaultValue filesystem root
|
|
18
|
-
*/
|
|
19
|
-
stopAt?: string;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Options for glob operations.
|
|
23
|
-
*
|
|
24
|
-
* Configure base directory, exclusion patterns, and file matching behavior.
|
|
25
|
-
*/
|
|
26
|
-
interface GlobOptions {
|
|
27
|
-
/**
|
|
28
|
-
* Base directory for glob matching.
|
|
29
|
-
* All returned paths will be absolute paths within this directory.
|
|
30
|
-
* @defaultValue process.cwd()
|
|
31
|
-
*/
|
|
32
|
-
cwd?: string;
|
|
33
|
-
/**
|
|
34
|
-
* Include files and directories starting with a dot in results.
|
|
35
|
-
* @defaultValue false
|
|
36
|
-
*/
|
|
37
|
-
dot?: boolean;
|
|
38
|
-
/**
|
|
39
|
-
* Follow symbolic links when scanning directories.
|
|
40
|
-
* @defaultValue false
|
|
41
|
-
*/
|
|
42
|
-
followSymlinks?: boolean;
|
|
43
|
-
/**
|
|
44
|
-
* Patterns to exclude from results.
|
|
45
|
-
* Supports negation with "!" prefix to re-include previously excluded files.
|
|
46
|
-
*/
|
|
47
|
-
ignore?: string[];
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Options for atomic write operations.
|
|
51
|
-
*
|
|
52
|
-
* Configure directory creation, permission handling, and file modes.
|
|
53
|
-
*/
|
|
54
|
-
interface AtomicWriteOptions {
|
|
55
|
-
/**
|
|
56
|
-
* Create parent directories if they do not exist.
|
|
57
|
-
* Uses recursive mkdir when enabled.
|
|
58
|
-
* @defaultValue true
|
|
59
|
-
*/
|
|
60
|
-
createParentDirs?: boolean;
|
|
61
|
-
/**
|
|
62
|
-
* Unix file mode for newly created files.
|
|
63
|
-
* @defaultValue 0o644
|
|
64
|
-
*/
|
|
65
|
-
mode?: number;
|
|
66
|
-
/**
|
|
67
|
-
* Preserve file permissions from existing file.
|
|
68
|
-
* If the target file does not exist, falls back to the mode option.
|
|
69
|
-
* @defaultValue false
|
|
70
|
-
*/
|
|
71
|
-
preservePermissions?: boolean;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Represents an acquired file lock.
|
|
75
|
-
*
|
|
76
|
-
* Contains metadata about the lock including the owning process ID and
|
|
77
|
-
* acquisition timestamp. Used with acquireLock and releaseLock functions.
|
|
78
|
-
*/
|
|
79
|
-
interface FileLock {
|
|
80
|
-
/** Path to the .lock file that indicates the lock */
|
|
81
|
-
lockPath: string;
|
|
82
|
-
/** Absolute path to the locked file */
|
|
83
|
-
path: string;
|
|
84
|
-
/** Process ID of the lock holder */
|
|
85
|
-
pid: number;
|
|
86
|
-
/** Unix timestamp (milliseconds) when the lock was acquired */
|
|
87
|
-
timestamp: number;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Represents an acquired shared (reader) file lock.
|
|
91
|
-
*
|
|
92
|
-
* Extends FileLock with a lock type discriminator. Multiple processes can
|
|
93
|
-
* hold shared locks simultaneously, but shared locks block exclusive locks.
|
|
94
|
-
*/
|
|
95
|
-
interface SharedFileLock extends FileLock {
|
|
96
|
-
/** Discriminator indicating this is a shared/reader lock */
|
|
97
|
-
lockType: "shared";
|
|
98
|
-
/** Unique identifier for this reader (allows multiple readers from same PID) */
|
|
99
|
-
readerId: string;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Options for lock acquisition.
|
|
103
|
-
*/
|
|
104
|
-
interface LockOptions {
|
|
105
|
-
/**
|
|
106
|
-
* Interval in milliseconds between retry attempts when waiting.
|
|
107
|
-
* @defaultValue 50
|
|
108
|
-
*/
|
|
109
|
-
retryInterval?: number;
|
|
110
|
-
/**
|
|
111
|
-
* Maximum time in milliseconds to wait for lock acquisition.
|
|
112
|
-
* If not specified, fails immediately if lock cannot be acquired.
|
|
113
|
-
*/
|
|
114
|
-
timeout?: number;
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Finds the workspace root by searching upward for marker files/directories.
|
|
118
|
-
*
|
|
119
|
-
* Searches from startPath up to the filesystem root (or stopAt if specified),
|
|
120
|
-
* returning the first directory containing any of the marker files.
|
|
121
|
-
* Default markers are ".git" and "package.json".
|
|
122
|
-
*
|
|
123
|
-
* @param startPath - Path to start searching from (can be file or directory)
|
|
124
|
-
* @param options - Search options including custom markers and stop boundary
|
|
125
|
-
* @returns Result containing absolute workspace root path, or NotFoundError if no markers found
|
|
126
|
-
*/
|
|
127
|
-
declare function findWorkspaceRoot(startPath: string, options?: FindWorkspaceRootOptions): Promise<Result<string, InstanceType<typeof NotFoundError>>>;
|
|
128
|
-
/**
|
|
129
|
-
* Gets the path relative to the workspace root.
|
|
130
|
-
*
|
|
131
|
-
* Finds the workspace root from the file's directory and returns the
|
|
132
|
-
* path relative to that root. Uses forward slashes for cross-platform consistency.
|
|
133
|
-
*
|
|
134
|
-
* @param absolutePath - Absolute path to convert to workspace-relative
|
|
135
|
-
* @returns Result containing relative path with forward slashes, or NotFoundError if no workspace found
|
|
136
|
-
*/
|
|
137
|
-
declare function getRelativePath(absolutePath: string): Promise<Result<string, InstanceType<typeof NotFoundError>>>;
|
|
138
|
-
/**
|
|
139
|
-
* Checks if a path is inside a workspace directory.
|
|
140
|
-
*
|
|
141
|
-
* Resolves both paths to absolute form and checks if path is equal to
|
|
142
|
-
* or a descendant of workspaceRoot. Does not follow symlinks.
|
|
143
|
-
*
|
|
144
|
-
* @param path - Path to check (can be relative or absolute)
|
|
145
|
-
* @param workspaceRoot - Workspace root directory to check against
|
|
146
|
-
* @returns True if path is inside or equal to workspace root, false otherwise
|
|
147
|
-
*/
|
|
148
|
-
declare function isInsideWorkspace(path: string, workspaceRoot: string): boolean;
|
|
149
|
-
/**
|
|
150
|
-
* Validates and secures a user-provided path, preventing path traversal attacks.
|
|
151
|
-
*
|
|
152
|
-
* Security checks performed:
|
|
153
|
-
* - Null bytes are rejected immediately
|
|
154
|
-
* - Path traversal sequences (..) are rejected
|
|
155
|
-
* - Absolute paths are rejected
|
|
156
|
-
* - Final resolved path is verified to remain within basePath (defense in depth)
|
|
157
|
-
*
|
|
158
|
-
* Always use this function when handling user-provided paths instead of
|
|
159
|
-
* directly using path.join with untrusted input.
|
|
160
|
-
*
|
|
161
|
-
* @param path - User-provided path to validate (must be relative)
|
|
162
|
-
* @param basePath - Base directory to resolve against
|
|
163
|
-
* @returns Result containing resolved absolute safe path, or ValidationError if path is unsafe
|
|
164
|
-
*/
|
|
165
|
-
declare function securePath(path: string, basePath: string): Result<string, InstanceType<typeof ValidationError>>;
|
|
166
|
-
/**
|
|
167
|
-
* Checks if a path is safe (no traversal, valid characters).
|
|
168
|
-
*
|
|
169
|
-
* Convenience wrapper around securePath that returns a boolean.
|
|
170
|
-
* Use this for quick validation; use securePath when you need the resolved path.
|
|
171
|
-
*
|
|
172
|
-
* @param path - Path to check (should be relative)
|
|
173
|
-
* @param basePath - Base directory to resolve against
|
|
174
|
-
* @returns True if path passes all security checks, false otherwise
|
|
175
|
-
*/
|
|
176
|
-
declare function isPathSafe(path: string, basePath: string): boolean;
|
|
177
|
-
/**
|
|
178
|
-
* Safely resolves path segments into an absolute path.
|
|
179
|
-
*
|
|
180
|
-
* Validates each segment for security issues before joining. Use this
|
|
181
|
-
* instead of path.join when any segment may come from user input.
|
|
182
|
-
*
|
|
183
|
-
* Security checks per segment:
|
|
184
|
-
* - Null bytes are rejected
|
|
185
|
-
* - Path traversal (..) is rejected
|
|
186
|
-
* - Absolute path segments are rejected
|
|
187
|
-
*
|
|
188
|
-
* @param basePath - Base directory (must be absolute)
|
|
189
|
-
* @param segments - Path segments to join (each validated individually)
|
|
190
|
-
* @returns Result containing resolved absolute path, or ValidationError if any segment is unsafe
|
|
191
|
-
*/
|
|
192
|
-
declare function resolveSafePath(basePath: string, ...segments: string[]): Result<string, InstanceType<typeof ValidationError>>;
|
|
193
|
-
/**
|
|
194
|
-
* Finds files matching a glob pattern.
|
|
195
|
-
*
|
|
196
|
-
* Uses Bun.Glob internally for fast pattern matching. Returns absolute paths.
|
|
197
|
-
* Supports standard glob syntax including recursive matching, alternation, and character classes.
|
|
198
|
-
*
|
|
199
|
-
* Pattern syntax:
|
|
200
|
-
* - Single asterisk matches any characters except path separator
|
|
201
|
-
* - Double asterisk matches any characters including path separator (recursive)
|
|
202
|
-
* - Curly braces for alternation
|
|
203
|
-
* - Square brackets for character classes
|
|
204
|
-
*
|
|
205
|
-
* @param pattern - Glob pattern to match
|
|
206
|
-
* @param options - Glob options including cwd, ignore patterns, and file type filters
|
|
207
|
-
* @returns Result containing array of absolute file paths, or InternalError on failure
|
|
208
|
-
*/
|
|
209
|
-
declare function glob(pattern: string, options?: GlobOptions): Promise<Result<string[], InstanceType<typeof InternalError>>>;
|
|
210
|
-
/**
|
|
211
|
-
* Synchronous version of glob.
|
|
212
|
-
*
|
|
213
|
-
* Use the async glob function when possible. This synchronous version
|
|
214
|
-
* blocks the event loop and should only be used in initialization code
|
|
215
|
-
* or synchronous contexts.
|
|
216
|
-
*
|
|
217
|
-
* @param pattern - Glob pattern to match
|
|
218
|
-
* @param options - Glob options including cwd, ignore patterns, and file type filters
|
|
219
|
-
* @returns Result containing array of absolute file paths, or InternalError on failure
|
|
220
|
-
*/
|
|
221
|
-
declare function globSync(pattern: string, options?: GlobOptions): Result<string[], InstanceType<typeof InternalError>>;
|
|
222
|
-
/**
|
|
223
|
-
* Acquires an exclusive advisory lock on a file.
|
|
224
|
-
*
|
|
225
|
-
* Creates a .lock file next to the target file with lock metadata (PID, timestamp).
|
|
226
|
-
* Uses atomic file creation (wx flag) to prevent race conditions.
|
|
227
|
-
*
|
|
228
|
-
* Exclusive locks block and are blocked by both shared and exclusive locks.
|
|
229
|
-
* Use shared locks (acquireSharedLock) for read-only operations.
|
|
230
|
-
*
|
|
231
|
-
* Important: This is advisory locking. All processes must cooperate by using
|
|
232
|
-
* these locking APIs. The filesystem does not enforce the lock.
|
|
233
|
-
*
|
|
234
|
-
* Prefer using withLock for automatic lock release.
|
|
235
|
-
*
|
|
236
|
-
* @param path - Absolute path to the file to lock
|
|
237
|
-
* @param options - Lock options including timeout and retry interval
|
|
238
|
-
* @returns Result containing FileLock on success, or ConflictError if already locked
|
|
239
|
-
*/
|
|
240
|
-
declare function acquireLock(path: string, options?: LockOptions): Promise<Result<FileLock, InstanceType<typeof ConflictError>>>;
|
|
241
|
-
/**
|
|
242
|
-
* Releases a file lock by removing the .lock file.
|
|
243
|
-
*
|
|
244
|
-
* Should only be called with a lock obtained from acquireLock.
|
|
245
|
-
* Prefer using withLock for automatic lock management.
|
|
246
|
-
*
|
|
247
|
-
* @param lock - Lock object returned from acquireLock
|
|
248
|
-
* @returns Result indicating success, or InternalError if lock file cannot be removed
|
|
249
|
-
*/
|
|
250
|
-
declare function releaseLock(lock: FileLock): Promise<Result<void, InstanceType<typeof InternalError>>>;
|
|
251
|
-
/**
|
|
252
|
-
* Executes a callback while holding an exclusive lock on a file.
|
|
253
|
-
*
|
|
254
|
-
* Lock is automatically released after callback completes, whether it
|
|
255
|
-
* succeeds or throws an error. This is the recommended way to use file locking.
|
|
256
|
-
*
|
|
257
|
-
* Uses advisory file locking via .lock files. The lock is NOT enforced
|
|
258
|
-
* by the filesystem - all processes must cooperate by using this API.
|
|
259
|
-
*
|
|
260
|
-
* @typeParam T - Return type of the callback
|
|
261
|
-
* @param path - Absolute path to the file to lock
|
|
262
|
-
* @param callback - Async callback to execute while holding lock
|
|
263
|
-
* @returns Result containing callback return value, ConflictError if locked, or InternalError on failure
|
|
264
|
-
*/
|
|
265
|
-
declare function withLock<T>(path: string, callback: () => Promise<T>): Promise<Result<T, InstanceType<typeof ConflictError> | InstanceType<typeof InternalError>>>;
|
|
266
|
-
/**
|
|
267
|
-
* Checks if a file is currently locked.
|
|
268
|
-
*
|
|
269
|
-
* Checks for the existence of a .lock file. Does not verify if the
|
|
270
|
-
* process holding the lock is still running (no stale lock detection).
|
|
271
|
-
*
|
|
272
|
-
* @param path - Absolute path to check
|
|
273
|
-
* @returns True if a lock file exists, false otherwise
|
|
274
|
-
*/
|
|
275
|
-
declare function isLocked(path: string): Promise<boolean>;
|
|
276
|
-
/**
|
|
277
|
-
* Writes content to a file atomically using temp-file-then-rename strategy.
|
|
278
|
-
*
|
|
279
|
-
* How it works:
|
|
280
|
-
* 1. Creates a unique temp file in the same directory
|
|
281
|
-
* 2. Writes content to temp file
|
|
282
|
-
* 3. Renames temp file to target (atomic on most filesystems)
|
|
283
|
-
* 4. Cleans up temp file on failure
|
|
284
|
-
*
|
|
285
|
-
* This prevents partial writes and file corruption. The file either
|
|
286
|
-
* contains the old content or the new content, never a partial state.
|
|
287
|
-
*
|
|
288
|
-
* @param path - Absolute path to target file
|
|
289
|
-
* @param content - String content to write
|
|
290
|
-
* @param options - Write options including directory creation and permission handling
|
|
291
|
-
* @returns Result indicating success, or InternalError on failure
|
|
292
|
-
*/
|
|
293
|
-
declare function atomicWrite(path: string, content: string, options?: AtomicWriteOptions): Promise<Result<void, InstanceType<typeof InternalError>>>;
|
|
294
|
-
/**
|
|
295
|
-
* Writes JSON data to a file atomically.
|
|
296
|
-
*
|
|
297
|
-
* Serializes data to JSON and writes using atomicWrite.
|
|
298
|
-
* Returns ValidationError if serialization fails.
|
|
299
|
-
*
|
|
300
|
-
* @typeParam T - Type of data to serialize
|
|
301
|
-
* @param path - Absolute path to target file
|
|
302
|
-
* @param data - Data to serialize and write (must be JSON-serializable)
|
|
303
|
-
* @param options - Write options including directory creation and permission handling
|
|
304
|
-
* @returns Result indicating success, ValidationError if serialization fails, or InternalError on write failure
|
|
305
|
-
*/
|
|
306
|
-
declare function atomicWriteJson<T>(path: string, data: T, options?: AtomicWriteOptions): Promise<Result<void, InstanceType<typeof InternalError> | InstanceType<typeof ValidationError>>>;
|
|
307
|
-
/**
|
|
308
|
-
* Acquires a shared (reader) lock on a file.
|
|
309
|
-
*
|
|
310
|
-
* Multiple readers can hold shared locks simultaneously. Shared locks are
|
|
311
|
-
* blocked by exclusive locks. Uses the same .lock file as exclusive locks
|
|
312
|
-
* with a JSON format that distinguishes lock types.
|
|
313
|
-
*
|
|
314
|
-
* Important: This is advisory locking. All processes must cooperate by using
|
|
315
|
-
* these locking APIs. The filesystem does not enforce the lock.
|
|
316
|
-
*
|
|
317
|
-
* @param path - Absolute path to the file to lock
|
|
318
|
-
* @param options - Lock options including timeout and retry interval
|
|
319
|
-
* @returns Result containing SharedFileLock on success, or ConflictError if blocked by exclusive lock
|
|
320
|
-
*/
|
|
321
|
-
declare function acquireSharedLock(path: string, options?: LockOptions): Promise<Result<SharedFileLock, InstanceType<typeof ConflictError>>>;
|
|
322
|
-
/**
|
|
323
|
-
* Releases a shared (reader) lock.
|
|
324
|
-
*
|
|
325
|
-
* Removes this process from the list of readers in the lock file.
|
|
326
|
-
* If this is the last reader, the lock file is deleted.
|
|
327
|
-
*
|
|
328
|
-
* @param lock - Shared lock object returned from acquireSharedLock
|
|
329
|
-
* @returns Result indicating success, or InternalError if lock file cannot be modified
|
|
330
|
-
*/
|
|
331
|
-
declare function releaseSharedLock(lock: SharedFileLock): Promise<Result<void, InstanceType<typeof InternalError>>>;
|
|
332
|
-
/**
|
|
333
|
-
* Executes a callback while holding a shared (reader) lock on a file.
|
|
334
|
-
*
|
|
335
|
-
* Lock is automatically released after callback completes, whether it
|
|
336
|
-
* succeeds or throws an error. This is the recommended way to use shared locks.
|
|
337
|
-
*
|
|
338
|
-
* Multiple readers can hold shared locks simultaneously. Use this for
|
|
339
|
-
* read-only operations that should not block other readers.
|
|
340
|
-
*
|
|
341
|
-
* @typeParam T - Return type of the callback
|
|
342
|
-
* @param path - Absolute path to the file to lock
|
|
343
|
-
* @param callback - Async callback to execute while holding lock
|
|
344
|
-
* @param options - Lock options including timeout and retry interval
|
|
345
|
-
* @returns Result containing callback return value, ConflictError if blocked, or InternalError on failure
|
|
346
|
-
*/
|
|
347
|
-
declare function withSharedLock<T>(path: string, callback: () => Promise<T>, options?: LockOptions): Promise<Result<T, InstanceType<typeof ConflictError> | InstanceType<typeof InternalError>>>;
|
|
1
|
+
import { glob, globSync } from "./shared/@outfitter/file-ops-3kzghhjm.js";
|
|
2
|
+
import { findWorkspaceRoot, getRelativePath, isInsideWorkspace } from "./shared/@outfitter/file-ops-b3v6xcnw.js";
|
|
3
|
+
import { acquireSharedLock, releaseSharedLock, withSharedLock } from "./shared/@outfitter/file-ops-cpvpwwsr.js";
|
|
4
|
+
import { isPathSafe, resolveSafePath, securePath } from "./shared/@outfitter/file-ops-ss4da105.js";
|
|
5
|
+
import { acquireLock, isLocked, releaseLock, withLock } from "./shared/@outfitter/file-ops-9xg8rjay.js";
|
|
6
|
+
import { atomicWrite, atomicWriteJson } from "./shared/@outfitter/file-ops-cp4q6s4n.js";
|
|
7
|
+
import { AtomicWriteOptions, FileLock, FindWorkspaceRootOptions, GlobOptions, LockOptions, SharedFileLock } from "./shared/@outfitter/file-ops-f0bv7qk0.js";
|
|
348
8
|
export { withSharedLock, withLock, securePath, resolveSafePath, releaseSharedLock, releaseLock, isPathSafe, isLocked, isInsideWorkspace, globSync, glob, getRelativePath, findWorkspaceRoot, atomicWriteJson, atomicWrite, acquireSharedLock, acquireLock, SharedFileLock, LockOptions, GlobOptions, FindWorkspaceRootOptions, FileLock, AtomicWriteOptions };
|