just-bash 2.5.0 → 2.5.1
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/bin/chunks/chunk-CTLU5QUH.js +17 -0
- package/dist/bin/chunks/{grep-WDHYDUUD.js → grep-QCXXYC54.js} +1 -1
- package/dist/bin/chunks/rg-GVIT6FTE.js +33 -0
- package/dist/bin/just-bash.js +1 -1
- package/dist/bin/shell/chunks/chunk-CTLU5QUH.js +17 -0
- package/dist/bin/shell/chunks/{grep-WDHYDUUD.js → grep-QCXXYC54.js} +1 -1
- package/dist/bin/shell/chunks/rg-GVIT6FTE.js +33 -0
- package/dist/bin/shell/shell.js +1 -1
- package/dist/bundle/browser.js +379 -375
- package/dist/bundle/chunks/chunk-OHJS5H37.js +16 -0
- package/dist/bundle/chunks/{grep-QVR5G7SC.js → grep-TUWLGQC2.js} +1 -1
- package/dist/bundle/chunks/rg-KTCMPGU6.js +32 -0
- package/dist/bundle/index.js +1 -1
- package/dist/commands/rg/file-types.d.ts +33 -7
- package/dist/commands/rg/gitignore.d.ts +32 -3
- package/dist/commands/rg/rg-options.d.ts +14 -0
- package/dist/commands/search-engine/index.d.ts +1 -1
- package/dist/commands/search-engine/regex.d.ts +10 -0
- package/dist/fs/in-memory-fs/in-memory-fs.d.ts +51 -0
- package/dist/fs/in-memory-fs/index.d.ts +1 -0
- package/dist/fs/init.d.ts +12 -0
- package/dist/fs/interface.d.ts +203 -0
- package/dist/fs/mountable-fs/index.d.ts +1 -0
- package/dist/fs/mountable-fs/mountable-fs.d.ts +108 -0
- package/dist/fs/overlay-fs/index.d.ts +1 -0
- package/dist/fs/overlay-fs/overlay-fs.d.ts +107 -0
- package/dist/fs/read-write-fs/index.d.ts +1 -0
- package/dist/fs/read-write-fs/read-write-fs.d.ts +47 -0
- package/dist/fs/utils.d.ts +17 -0
- package/package.json +2 -3
- package/dist/bin/chunks/chunk-X4WRNADE.js +0 -17
- package/dist/bin/chunks/rg-ALK3CYAN.js +0 -29
- package/dist/bin/shell/chunks/chunk-X4WRNADE.js +0 -17
- package/dist/bin/shell/chunks/rg-ALK3CYAN.js +0 -29
- package/dist/bundle/chunks/chunk-7VH6U2UX.js +0 -16
- package/dist/bundle/chunks/rg-43HLKW4V.js +0 -28
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supported buffer encodings
|
|
3
|
+
*/
|
|
4
|
+
export type BufferEncoding = "utf8" | "utf-8" | "ascii" | "binary" | "base64" | "hex" | "latin1";
|
|
5
|
+
/**
|
|
6
|
+
* File content can be string or Buffer
|
|
7
|
+
*/
|
|
8
|
+
export type FileContent = string | Uint8Array;
|
|
9
|
+
/**
|
|
10
|
+
* Options for reading files
|
|
11
|
+
*/
|
|
12
|
+
export interface ReadFileOptions {
|
|
13
|
+
encoding?: BufferEncoding | null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Options for writing files
|
|
17
|
+
*/
|
|
18
|
+
export interface WriteFileOptions {
|
|
19
|
+
encoding?: BufferEncoding;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* File system entry types
|
|
23
|
+
*/
|
|
24
|
+
export interface FileEntry {
|
|
25
|
+
type: "file";
|
|
26
|
+
content: string | Uint8Array;
|
|
27
|
+
mode: number;
|
|
28
|
+
mtime: Date;
|
|
29
|
+
}
|
|
30
|
+
export interface DirectoryEntry {
|
|
31
|
+
type: "directory";
|
|
32
|
+
mode: number;
|
|
33
|
+
mtime: Date;
|
|
34
|
+
}
|
|
35
|
+
export interface SymlinkEntry {
|
|
36
|
+
type: "symlink";
|
|
37
|
+
target: string;
|
|
38
|
+
mode: number;
|
|
39
|
+
mtime: Date;
|
|
40
|
+
}
|
|
41
|
+
export type FsEntry = FileEntry | DirectoryEntry | SymlinkEntry;
|
|
42
|
+
/**
|
|
43
|
+
* Directory entry with type information (similar to Node's Dirent)
|
|
44
|
+
* Used by readdirWithFileTypes for efficient directory listing without stat calls
|
|
45
|
+
*/
|
|
46
|
+
export interface DirentEntry {
|
|
47
|
+
name: string;
|
|
48
|
+
isFile: boolean;
|
|
49
|
+
isDirectory: boolean;
|
|
50
|
+
isSymbolicLink: boolean;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Stat result from the filesystem
|
|
54
|
+
*/
|
|
55
|
+
export interface FsStat {
|
|
56
|
+
isFile: boolean;
|
|
57
|
+
isDirectory: boolean;
|
|
58
|
+
isSymbolicLink: boolean;
|
|
59
|
+
mode: number;
|
|
60
|
+
size: number;
|
|
61
|
+
mtime: Date;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Options for mkdir operation
|
|
65
|
+
*/
|
|
66
|
+
export interface MkdirOptions {
|
|
67
|
+
recursive?: boolean;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Options for rm operation
|
|
71
|
+
*/
|
|
72
|
+
export interface RmOptions {
|
|
73
|
+
recursive?: boolean;
|
|
74
|
+
force?: boolean;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Options for cp operation
|
|
78
|
+
*/
|
|
79
|
+
export interface CpOptions {
|
|
80
|
+
recursive?: boolean;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Abstract filesystem interface that can be implemented by different backends.
|
|
84
|
+
* This allows BashEnv to work with:
|
|
85
|
+
* - InMemoryFs (in-memory, default)
|
|
86
|
+
* - Real filesystem (via node:fs)
|
|
87
|
+
* - Custom implementations (e.g., remote storage, browser IndexedDB)
|
|
88
|
+
*/
|
|
89
|
+
export interface IFileSystem {
|
|
90
|
+
/**
|
|
91
|
+
* Read the contents of a file as a string (default: utf8)
|
|
92
|
+
* @throws Error if file doesn't exist or is a directory
|
|
93
|
+
*/
|
|
94
|
+
readFile(path: string, options?: ReadFileOptions | BufferEncoding): Promise<string>;
|
|
95
|
+
/**
|
|
96
|
+
* Read the contents of a file as a Uint8Array (binary)
|
|
97
|
+
* @throws Error if file doesn't exist or is a directory
|
|
98
|
+
*/
|
|
99
|
+
readFileBuffer(path: string): Promise<Uint8Array>;
|
|
100
|
+
/**
|
|
101
|
+
* Write content to a file, creating it if it doesn't exist
|
|
102
|
+
*/
|
|
103
|
+
writeFile(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding): Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
* Append content to a file, creating it if it doesn't exist
|
|
106
|
+
*/
|
|
107
|
+
appendFile(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding): Promise<void>;
|
|
108
|
+
/**
|
|
109
|
+
* Check if a path exists
|
|
110
|
+
*/
|
|
111
|
+
exists(path: string): Promise<boolean>;
|
|
112
|
+
/**
|
|
113
|
+
* Get file/directory information
|
|
114
|
+
* @throws Error if path doesn't exist
|
|
115
|
+
*/
|
|
116
|
+
stat(path: string): Promise<FsStat>;
|
|
117
|
+
/**
|
|
118
|
+
* Create a directory
|
|
119
|
+
* @throws Error if parent doesn't exist (unless recursive) or path exists
|
|
120
|
+
*/
|
|
121
|
+
mkdir(path: string, options?: MkdirOptions): Promise<void>;
|
|
122
|
+
/**
|
|
123
|
+
* Read directory contents
|
|
124
|
+
* @returns Array of entry names (not full paths)
|
|
125
|
+
* @throws Error if path doesn't exist or is not a directory
|
|
126
|
+
*/
|
|
127
|
+
readdir(path: string): Promise<string[]>;
|
|
128
|
+
/**
|
|
129
|
+
* Read directory contents with file type information (optional)
|
|
130
|
+
* This is more efficient than readdir + stat for each entry
|
|
131
|
+
* @returns Array of DirentEntry objects with name and type
|
|
132
|
+
* @throws Error if path doesn't exist or is not a directory
|
|
133
|
+
*/
|
|
134
|
+
readdirWithFileTypes?(path: string): Promise<DirentEntry[]>;
|
|
135
|
+
/**
|
|
136
|
+
* Remove a file or directory
|
|
137
|
+
* @throws Error if path doesn't exist (unless force) or directory not empty (unless recursive)
|
|
138
|
+
*/
|
|
139
|
+
rm(path: string, options?: RmOptions): Promise<void>;
|
|
140
|
+
/**
|
|
141
|
+
* Copy a file or directory
|
|
142
|
+
* @throws Error if source doesn't exist or trying to copy directory without recursive
|
|
143
|
+
*/
|
|
144
|
+
cp(src: string, dest: string, options?: CpOptions): Promise<void>;
|
|
145
|
+
/**
|
|
146
|
+
* Move/rename a file or directory
|
|
147
|
+
*/
|
|
148
|
+
mv(src: string, dest: string): Promise<void>;
|
|
149
|
+
/**
|
|
150
|
+
* Resolve a relative path against a base path
|
|
151
|
+
*/
|
|
152
|
+
resolvePath(base: string, path: string): string;
|
|
153
|
+
/**
|
|
154
|
+
* Get all paths in the filesystem (useful for glob matching)
|
|
155
|
+
* Optional - implementations may return empty array if not supported
|
|
156
|
+
*/
|
|
157
|
+
getAllPaths(): string[];
|
|
158
|
+
/**
|
|
159
|
+
* Change file/directory permissions
|
|
160
|
+
* @throws Error if path doesn't exist
|
|
161
|
+
*/
|
|
162
|
+
chmod(path: string, mode: number): Promise<void>;
|
|
163
|
+
/**
|
|
164
|
+
* Create a symbolic link
|
|
165
|
+
* @param target - The path the symlink should point to
|
|
166
|
+
* @param linkPath - The path where the symlink will be created
|
|
167
|
+
* @throws Error if linkPath already exists
|
|
168
|
+
*/
|
|
169
|
+
symlink(target: string, linkPath: string): Promise<void>;
|
|
170
|
+
/**
|
|
171
|
+
* Create a hard link
|
|
172
|
+
* @param existingPath - The existing file to link to
|
|
173
|
+
* @param newPath - The path where the new link will be created
|
|
174
|
+
* @throws Error if existingPath doesn't exist or newPath already exists
|
|
175
|
+
*/
|
|
176
|
+
link(existingPath: string, newPath: string): Promise<void>;
|
|
177
|
+
/**
|
|
178
|
+
* Read the target of a symbolic link
|
|
179
|
+
* @throws Error if path doesn't exist or is not a symlink
|
|
180
|
+
*/
|
|
181
|
+
readlink(path: string): Promise<string>;
|
|
182
|
+
/**
|
|
183
|
+
* Get file/directory information without following symlinks
|
|
184
|
+
* @throws Error if path doesn't exist
|
|
185
|
+
*/
|
|
186
|
+
lstat(path: string): Promise<FsStat>;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Extended file initialization options with optional metadata
|
|
190
|
+
*/
|
|
191
|
+
export interface FileInit {
|
|
192
|
+
content: FileContent;
|
|
193
|
+
mode?: number;
|
|
194
|
+
mtime?: Date;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Initial files can be simple content or extended options with metadata
|
|
198
|
+
*/
|
|
199
|
+
export type InitialFiles = Record<string, FileContent | FileInit>;
|
|
200
|
+
/**
|
|
201
|
+
* Factory function type for creating filesystem instances
|
|
202
|
+
*/
|
|
203
|
+
export type FileSystemFactory = (initialFiles?: InitialFiles) => IFileSystem;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { MountableFs, type MountableFsOptions, type MountConfig, } from "./mountable-fs.js";
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { BufferEncoding, CpOptions, FileContent, FsStat, IFileSystem, MkdirOptions, ReadFileOptions, RmOptions, WriteFileOptions } from "../interface.js";
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for a mount point
|
|
4
|
+
*/
|
|
5
|
+
export interface MountConfig {
|
|
6
|
+
/** Virtual path where the filesystem is mounted */
|
|
7
|
+
mountPoint: string;
|
|
8
|
+
/** The filesystem to mount at this path */
|
|
9
|
+
filesystem: IFileSystem;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Options for creating a MountableFs
|
|
13
|
+
*/
|
|
14
|
+
export interface MountableFsOptions {
|
|
15
|
+
/** Base filesystem used for unmounted paths (defaults to InMemoryFs) */
|
|
16
|
+
base?: IFileSystem;
|
|
17
|
+
/** Initial mounts to configure */
|
|
18
|
+
mounts?: MountConfig[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A filesystem that supports mounting other filesystems at specific paths.
|
|
22
|
+
*
|
|
23
|
+
* This allows combining multiple filesystem backends into a unified namespace.
|
|
24
|
+
* For example, mounting a read-only knowledge base at /mnt/knowledge and a
|
|
25
|
+
* read-write workspace at /home/agent.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const fs = new MountableFs({ base: new InMemoryFs() });
|
|
30
|
+
* fs.mount('/mnt/knowledge', new OverlayFs({ root: "/path/to/knowledge", readOnly: true }));
|
|
31
|
+
* fs.mount('/home/agent', new ReadWriteFs({ root: "/path/to/workspace" }));
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare class MountableFs implements IFileSystem {
|
|
35
|
+
private baseFs;
|
|
36
|
+
private mounts;
|
|
37
|
+
constructor(options?: MountableFsOptions);
|
|
38
|
+
/**
|
|
39
|
+
* Mount a filesystem at the specified virtual path.
|
|
40
|
+
*
|
|
41
|
+
* @param mountPoint - The virtual path where the filesystem will be accessible
|
|
42
|
+
* @param filesystem - The filesystem to mount
|
|
43
|
+
* @throws Error if mounting at root '/' or inside an existing mount
|
|
44
|
+
*/
|
|
45
|
+
mount(mountPoint: string, filesystem: IFileSystem): void;
|
|
46
|
+
/**
|
|
47
|
+
* Unmount the filesystem at the specified path.
|
|
48
|
+
*
|
|
49
|
+
* @param mountPoint - The virtual path to unmount
|
|
50
|
+
* @throws Error if no filesystem is mounted at this path
|
|
51
|
+
*/
|
|
52
|
+
unmount(mountPoint: string): void;
|
|
53
|
+
/**
|
|
54
|
+
* Get all current mounts.
|
|
55
|
+
*/
|
|
56
|
+
getMounts(): ReadonlyArray<{
|
|
57
|
+
mountPoint: string;
|
|
58
|
+
filesystem: IFileSystem;
|
|
59
|
+
}>;
|
|
60
|
+
/**
|
|
61
|
+
* Check if a path is exactly a mount point.
|
|
62
|
+
*/
|
|
63
|
+
isMountPoint(path: string): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Validate mount path format before normalization.
|
|
66
|
+
* Rejects paths containing . or .. segments.
|
|
67
|
+
*/
|
|
68
|
+
private validateMountPath;
|
|
69
|
+
/**
|
|
70
|
+
* Validate that a mount point is allowed.
|
|
71
|
+
*/
|
|
72
|
+
private validateMount;
|
|
73
|
+
/**
|
|
74
|
+
* Normalize a path to a consistent format.
|
|
75
|
+
*/
|
|
76
|
+
private normalizePath;
|
|
77
|
+
/**
|
|
78
|
+
* Route a path to the appropriate filesystem.
|
|
79
|
+
* Returns the filesystem and the relative path within that filesystem.
|
|
80
|
+
*/
|
|
81
|
+
private routePath;
|
|
82
|
+
/**
|
|
83
|
+
* Get mount points that are immediate children of a directory.
|
|
84
|
+
*/
|
|
85
|
+
private getChildMountPoints;
|
|
86
|
+
readFile(path: string, options?: ReadFileOptions | BufferEncoding): Promise<string>;
|
|
87
|
+
readFileBuffer(path: string): Promise<Uint8Array>;
|
|
88
|
+
writeFile(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding): Promise<void>;
|
|
89
|
+
appendFile(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding): Promise<void>;
|
|
90
|
+
exists(path: string): Promise<boolean>;
|
|
91
|
+
stat(path: string): Promise<FsStat>;
|
|
92
|
+
lstat(path: string): Promise<FsStat>;
|
|
93
|
+
mkdir(path: string, options?: MkdirOptions): Promise<void>;
|
|
94
|
+
readdir(path: string): Promise<string[]>;
|
|
95
|
+
rm(path: string, options?: RmOptions): Promise<void>;
|
|
96
|
+
cp(src: string, dest: string, options?: CpOptions): Promise<void>;
|
|
97
|
+
mv(src: string, dest: string): Promise<void>;
|
|
98
|
+
resolvePath(base: string, path: string): string;
|
|
99
|
+
getAllPaths(): string[];
|
|
100
|
+
chmod(path: string, mode: number): Promise<void>;
|
|
101
|
+
symlink(target: string, linkPath: string): Promise<void>;
|
|
102
|
+
link(existingPath: string, newPath: string): Promise<void>;
|
|
103
|
+
readlink(path: string): Promise<string>;
|
|
104
|
+
/**
|
|
105
|
+
* Perform a cross-mount copy operation.
|
|
106
|
+
*/
|
|
107
|
+
private crossMountCopy;
|
|
108
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { OverlayFs, type OverlayFsOptions } from "./overlay-fs.js";
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OverlayFs - Copy-on-write filesystem backed by a real directory
|
|
3
|
+
*
|
|
4
|
+
* Reads come from the real filesystem, writes go to an in-memory layer.
|
|
5
|
+
* Changes don't persist to disk and can't escape the root directory.
|
|
6
|
+
*/
|
|
7
|
+
import type { CpOptions, DirentEntry, FsStat, IFileSystem, MkdirOptions, ReadFileOptions, RmOptions, WriteFileOptions } from "../interface.js";
|
|
8
|
+
import { type FileContent } from "../utils.js";
|
|
9
|
+
export interface OverlayFsOptions {
|
|
10
|
+
/**
|
|
11
|
+
* The root directory on the real filesystem.
|
|
12
|
+
* All paths are relative to this root and cannot escape it.
|
|
13
|
+
*/
|
|
14
|
+
root: string;
|
|
15
|
+
/**
|
|
16
|
+
* The virtual mount point where the root directory appears.
|
|
17
|
+
* Defaults to "/home/user/project".
|
|
18
|
+
*/
|
|
19
|
+
mountPoint?: string;
|
|
20
|
+
/**
|
|
21
|
+
* If true, all write operations will throw an error.
|
|
22
|
+
* Useful for truly read-only access to the filesystem.
|
|
23
|
+
* Defaults to false.
|
|
24
|
+
*/
|
|
25
|
+
readOnly?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare class OverlayFs implements IFileSystem {
|
|
28
|
+
private readonly root;
|
|
29
|
+
private readonly mountPoint;
|
|
30
|
+
private readonly readOnly;
|
|
31
|
+
private readonly memory;
|
|
32
|
+
private readonly deleted;
|
|
33
|
+
constructor(options: OverlayFsOptions);
|
|
34
|
+
/**
|
|
35
|
+
* Throws an error if the filesystem is in read-only mode.
|
|
36
|
+
*/
|
|
37
|
+
private assertWritable;
|
|
38
|
+
/**
|
|
39
|
+
* Create directory entries for the mount point path
|
|
40
|
+
*/
|
|
41
|
+
private createMountPointDirs;
|
|
42
|
+
/**
|
|
43
|
+
* Get the mount point for this overlay
|
|
44
|
+
*/
|
|
45
|
+
getMountPoint(): string;
|
|
46
|
+
/**
|
|
47
|
+
* Create a virtual directory in memory (sync, for initialization)
|
|
48
|
+
*/
|
|
49
|
+
mkdirSync(path: string, _options?: MkdirOptions): void;
|
|
50
|
+
/**
|
|
51
|
+
* Create a virtual file in memory (sync, for initialization)
|
|
52
|
+
*/
|
|
53
|
+
writeFileSync(path: string, content: string | Uint8Array): void;
|
|
54
|
+
private getDirname;
|
|
55
|
+
/**
|
|
56
|
+
* Normalize a virtual path (resolve . and .., ensure starts with /)
|
|
57
|
+
*/
|
|
58
|
+
private normalizePath;
|
|
59
|
+
/**
|
|
60
|
+
* Check if a normalized virtual path is under the mount point.
|
|
61
|
+
* Returns the relative path within the mount point, or null if not under it.
|
|
62
|
+
*/
|
|
63
|
+
private getRelativeToMount;
|
|
64
|
+
/**
|
|
65
|
+
* Convert a virtual path to a real filesystem path.
|
|
66
|
+
* Returns null if the path is not under the mount point or would escape the root.
|
|
67
|
+
*/
|
|
68
|
+
private toRealPath;
|
|
69
|
+
private dirname;
|
|
70
|
+
private ensureParentDirs;
|
|
71
|
+
/**
|
|
72
|
+
* Check if a path exists in the overlay (memory + real fs - deleted)
|
|
73
|
+
*/
|
|
74
|
+
private existsInOverlay;
|
|
75
|
+
readFile(path: string, options?: ReadFileOptions | BufferEncoding): Promise<string>;
|
|
76
|
+
readFileBuffer(path: string, seen?: Set<string>): Promise<Uint8Array>;
|
|
77
|
+
writeFile(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding): Promise<void>;
|
|
78
|
+
appendFile(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding): Promise<void>;
|
|
79
|
+
exists(path: string): Promise<boolean>;
|
|
80
|
+
stat(path: string, seen?: Set<string>): Promise<FsStat>;
|
|
81
|
+
lstat(path: string): Promise<FsStat>;
|
|
82
|
+
private resolveSymlink;
|
|
83
|
+
mkdir(path: string, options?: MkdirOptions): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Core readdir implementation that returns entries with file types.
|
|
86
|
+
* Both readdir and readdirWithFileTypes use this shared implementation.
|
|
87
|
+
*/
|
|
88
|
+
private readdirCore;
|
|
89
|
+
/**
|
|
90
|
+
* Follow symlinks to resolve the final directory path.
|
|
91
|
+
* Returns outsideOverlay: true if the symlink points outside the overlay or
|
|
92
|
+
* the resolved target doesn't exist (security - broken symlinks return []).
|
|
93
|
+
*/
|
|
94
|
+
private resolveForReaddir;
|
|
95
|
+
readdir(path: string): Promise<string[]>;
|
|
96
|
+
readdirWithFileTypes(path: string): Promise<DirentEntry[]>;
|
|
97
|
+
rm(path: string, options?: RmOptions): Promise<void>;
|
|
98
|
+
cp(src: string, dest: string, options?: CpOptions): Promise<void>;
|
|
99
|
+
mv(src: string, dest: string): Promise<void>;
|
|
100
|
+
resolvePath(base: string, path: string): string;
|
|
101
|
+
getAllPaths(): string[];
|
|
102
|
+
private scanRealFs;
|
|
103
|
+
chmod(path: string, mode: number): Promise<void>;
|
|
104
|
+
symlink(target: string, linkPath: string): Promise<void>;
|
|
105
|
+
link(existingPath: string, newPath: string): Promise<void>;
|
|
106
|
+
readlink(path: string): Promise<string>;
|
|
107
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ReadWriteFs, type ReadWriteFsOptions } from "./read-write-fs.js";
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ReadWriteFs - Direct wrapper around the real filesystem
|
|
3
|
+
*
|
|
4
|
+
* All operations go directly to the underlying Node.js filesystem.
|
|
5
|
+
* This is a true read-write filesystem with no overlay or sandboxing.
|
|
6
|
+
*/
|
|
7
|
+
import type { CpOptions, DirentEntry, FsStat, IFileSystem, MkdirOptions, ReadFileOptions, RmOptions, WriteFileOptions } from "../interface.js";
|
|
8
|
+
import { type FileContent } from "../utils.js";
|
|
9
|
+
export interface ReadWriteFsOptions {
|
|
10
|
+
/**
|
|
11
|
+
* The root directory on the real filesystem.
|
|
12
|
+
* All paths are relative to this root.
|
|
13
|
+
*/
|
|
14
|
+
root: string;
|
|
15
|
+
}
|
|
16
|
+
export declare class ReadWriteFs implements IFileSystem {
|
|
17
|
+
private readonly root;
|
|
18
|
+
constructor(options: ReadWriteFsOptions);
|
|
19
|
+
/**
|
|
20
|
+
* Convert a virtual path to a real filesystem path.
|
|
21
|
+
*/
|
|
22
|
+
private toRealPath;
|
|
23
|
+
/**
|
|
24
|
+
* Normalize a virtual path (resolve . and .., ensure starts with /)
|
|
25
|
+
*/
|
|
26
|
+
private normalizePath;
|
|
27
|
+
readFile(path: string, options?: ReadFileOptions | BufferEncoding): Promise<string>;
|
|
28
|
+
readFileBuffer(path: string): Promise<Uint8Array>;
|
|
29
|
+
writeFile(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding): Promise<void>;
|
|
30
|
+
appendFile(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding): Promise<void>;
|
|
31
|
+
exists(path: string): Promise<boolean>;
|
|
32
|
+
stat(path: string): Promise<FsStat>;
|
|
33
|
+
lstat(path: string): Promise<FsStat>;
|
|
34
|
+
mkdir(path: string, options?: MkdirOptions): Promise<void>;
|
|
35
|
+
readdir(path: string): Promise<string[]>;
|
|
36
|
+
readdirWithFileTypes(path: string): Promise<DirentEntry[]>;
|
|
37
|
+
rm(path: string, options?: RmOptions): Promise<void>;
|
|
38
|
+
cp(src: string, dest: string, options?: CpOptions): Promise<void>;
|
|
39
|
+
mv(src: string, dest: string): Promise<void>;
|
|
40
|
+
resolvePath(base: string, path: string): string;
|
|
41
|
+
getAllPaths(): string[];
|
|
42
|
+
private scanDir;
|
|
43
|
+
chmod(path: string, mode: number): Promise<void>;
|
|
44
|
+
symlink(target: string, linkPath: string): Promise<void>;
|
|
45
|
+
link(existingPath: string, newPath: string): Promise<void>;
|
|
46
|
+
readlink(path: string): Promise<string>;
|
|
47
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for filesystem implementations
|
|
3
|
+
*/
|
|
4
|
+
import type { BufferEncoding, ReadFileOptions, WriteFileOptions } from "./interface.js";
|
|
5
|
+
export type FileContent = string | Uint8Array;
|
|
6
|
+
/**
|
|
7
|
+
* Helper to convert content to Uint8Array
|
|
8
|
+
*/
|
|
9
|
+
export declare function toBuffer(content: FileContent, encoding?: BufferEncoding): Uint8Array;
|
|
10
|
+
/**
|
|
11
|
+
* Helper to convert Uint8Array to string with encoding
|
|
12
|
+
*/
|
|
13
|
+
export declare function fromBuffer(buffer: Uint8Array, encoding?: BufferEncoding | null): string;
|
|
14
|
+
/**
|
|
15
|
+
* Helper to get encoding from options
|
|
16
|
+
*/
|
|
17
|
+
export declare function getEncoding(options?: ReadFileOptions | WriteFileOptions | BufferEncoding | string | null): BufferEncoding | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "just-bash",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.1",
|
|
4
4
|
"description": "A simulated bash environment with virtual filesystem",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -30,10 +30,9 @@
|
|
|
30
30
|
"dist/*.d.ts",
|
|
31
31
|
"dist/ast/*.d.ts",
|
|
32
32
|
"dist/commands/**/*.d.ts",
|
|
33
|
-
"dist/
|
|
33
|
+
"dist/fs/**/*.d.ts",
|
|
34
34
|
"dist/interpreter/**/*.d.ts",
|
|
35
35
|
"dist/network/**/*.d.ts",
|
|
36
|
-
"dist/overlay-fs/*.d.ts",
|
|
37
36
|
"dist/parser/*.d.ts",
|
|
38
37
|
"dist/sandbox/*.d.ts",
|
|
39
38
|
"dist/utils/*.d.ts",
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
function A(r,l,u={}){let{invertMatch:f=!1,showLineNumbers:c=!1,countOnly:B=!1,countMatches:j=!1,filename:a="",onlyMatching:T=!1,beforeContext:N=0,afterContext:v=0,maxCount:w=0,contextSeparator:P="--",showColumn:M=!1,vimgrep:z=!1,showByteOffset:b=!1,replace:p=null,passthru:g=!1,multiline:R=!1}=u;if(R)return D(r,l,{invertMatch:f,showLineNumbers:c,countOnly:B,countMatches:j,filename:a,onlyMatching:T,beforeContext:N,afterContext:v,maxCount:w,contextSeparator:P,showColumn:M,showByteOffset:b,replace:p});let d=r.split(`
|
|
3
|
-
`),S=d.length,y=S>0&&d[S-1]===""?S-1:S;if(B||j){let i=0;for(let e=0;e<y;e++)if(l.lastIndex=0,j)for(let t=l.exec(d[e]);t!==null;t=l.exec(d[e]))f||i++,t[0].length===0&&l.lastIndex++;else l.test(d[e])!==f&&i++;return{output:`${a?`${a}:${i}`:String(i)}
|
|
4
|
-
`,matched:i>0,matchCount:i}}if(N===0&&v===0&&!g){let i=[],o=!1,e=0,t=0;for(let s=0;s<y&&!(w>0&&e>=w);s++){let L=d[s];if(l.lastIndex=0,l.test(L)!==f)if(o=!0,e++,T){l.lastIndex=0;for(let h=l.exec(L);h!==null;h=l.exec(L)){let I=p!==null?p:h[0],k=a?`${a}:`:"";b&&(k+=`${t+h.index}:`),c&&(k+=`${s+1}:`),M&&(k+=`${h.index+1}:`),i.push(k+I),h[0].length===0&&l.lastIndex++}}else if(z){l.lastIndex=0;for(let h=l.exec(L);h!==null;h=l.exec(L)){let I=a?`${a}:`:"";b&&(I+=`${t+h.index}:`),c&&(I+=`${s+1}:`),M&&(I+=`${h.index+1}:`),i.push(I+L),h[0].length===0&&l.lastIndex++}}else{l.lastIndex=0;let h=l.exec(L),I=h?h.index+1:1,k=L;p!==null&&(l.lastIndex=0,k=L.replace(l,p));let E=a?`${a}:`:"";b&&(E+=`${t+(h?h.index:0)}:`),c&&(E+=`${s+1}:`),M&&(E+=`${I}:`),i.push(E+k)}t+=L.length+1}return{output:i.length>0?`${i.join(`
|
|
5
|
-
`)}
|
|
6
|
-
`:"",matched:o,matchCount:e}}if(g){let i=[],o=!1,e=0;for(let t=0;t<y;t++){let s=d[t];l.lastIndex=0;let O=l.test(s)!==f;O&&(o=!0,e++);let h=O?":":"-",I=a?`${a}${h}`:"";c&&(I+=`${t+1}${h}`),i.push(I+s)}return{output:i.length>0?`${i.join(`
|
|
7
|
-
`)}
|
|
8
|
-
`:"",matched:o,matchCount:e}}let $=[],C=0,m=new Set,x=-1,n=[];for(let i=0;i<y&&!(w>0&&C>=w);i++)l.lastIndex=0,l.test(d[i])!==f&&(n.push(i),C++);for(let i of n){let o=Math.max(0,i-N);x>=0&&o>x+1&&$.push(P);for(let t=o;t<i;t++)if(!m.has(t)){m.add(t),x=t;let s=d[t];c&&(s=`${t+1}-${s}`),a&&(s=`${a}-${s}`),$.push(s)}if(!m.has(i)){m.add(i),x=i;let t=d[i];if(T){l.lastIndex=0;for(let s=l.exec(t);s!==null;s=l.exec(t)){let L=p!==null?p:s[0],O=a?`${a}:`:"";c&&(O+=`${i+1}:`),M&&(O+=`${s.index+1}:`),$.push(O+L),s[0].length===0&&l.lastIndex++}}else{let s=t;c&&(s=`${i+1}:${s}`),a&&(s=`${a}:${s}`),$.push(s)}}let e=Math.min(y-1,i+v);for(let t=i+1;t<=e;t++)if(!m.has(t)){m.add(t),x=t;let s=d[t];c&&(s=`${t+1}-${s}`),a&&(s=`${a}-${s}`),$.push(s)}}return{output:$.length>0?`${$.join(`
|
|
9
|
-
`)}
|
|
10
|
-
`:"",matched:C>0,matchCount:C}}function D(r,l,u){let{invertMatch:f,showLineNumbers:c,countOnly:B,countMatches:j,filename:a,onlyMatching:T,beforeContext:N,afterContext:v,maxCount:w,contextSeparator:P,showColumn:M,showByteOffset:z,replace:b}=u,p=r.split(`
|
|
11
|
-
`),g=p.length,R=g>0&&p[g-1]===""?g-1:g,d=[0];for(let n=0;n<r.length;n++)r[n]===`
|
|
12
|
-
`&&d.push(n+1);let S=n=>{let i=0;for(let o=0;o<d.length&&!(d[o]>n);o++)i=o;return i},y=n=>{let i=S(n);return n-d[i]+1},$=[];l.lastIndex=0;for(let n=l.exec(r);n!==null&&!(w>0&&$.length>=w);n=l.exec(r)){let i=S(n.index),o=S(n.index+Math.max(0,n[0].length-1));$.push({startLine:i,endLine:o,byteOffset:n.index,column:y(n.index),matchText:n[0]}),n[0].length===0&&l.lastIndex++}if(B||j){let n;if(j)n=f?0:$.length;else{let o=new Set;for(let e of $)for(let t=e.startLine;t<=e.endLine;t++)o.add(t);n=f?R-o.size:o.size}return{output:`${a?`${a}:${n}`:String(n)}
|
|
13
|
-
`,matched:n>0,matchCount:n}}if(f){let n=new Set;for(let o of $)for(let e=o.startLine;e<=o.endLine;e++)n.add(e);let i=[];for(let o=0;o<R;o++)if(!n.has(o)){let e=p[o];c&&(e=`${o+1}:${e}`),a&&(e=`${a}:${e}`),i.push(e)}return{output:i.length>0?`${i.join(`
|
|
14
|
-
`)}
|
|
15
|
-
`:"",matched:i.length>0,matchCount:i.length}}if($.length===0)return{output:"",matched:!1,matchCount:0};let C=new Set,m=-1,x=[];for(let n of $){let i=Math.max(0,n.startLine-N),o=Math.min(R-1,n.endLine+v);m>=0&&i>m+1&&x.push(P);for(let e=i;e<n.startLine;e++)if(!C.has(e)){C.add(e),m=e;let t=p[e];c&&(t=`${e+1}-${t}`),a&&(t=`${a}-${t}`),x.push(t)}if(T){let e=b!==null?b:n.matchText,t=a?`${a}:`:"";z&&(t+=`${n.byteOffset}:`),c&&(t+=`${n.startLine+1}:`),M&&(t+=`${n.column}:`),x.push(t+e);for(let s=n.startLine;s<=n.endLine;s++)C.add(s),m=s}else for(let e=n.startLine;e<=n.endLine&&e<R;e++)if(!C.has(e)){C.add(e),m=e;let t=p[e];b!==null&&e===n.startLine&&(l.lastIndex=0,t=t.replace(l,b));let s=a?`${a}:`:"";z&&e===n.startLine&&(s+=`${n.byteOffset}:`),c&&(s+=`${e+1}:`),M&&e===n.startLine&&(s+=`${n.column}:`),x.push(s+t)}for(let e=n.endLine+1;e<=o;e++)if(!C.has(e)){C.add(e),m=e;let t=p[e];c&&(t=`${e+1}-${t}`),a&&(t=`${a}-${t}`),x.push(t)}}return{output:x.length>0?`${x.join(`
|
|
16
|
-
`)}
|
|
17
|
-
`:"",matched:!0,matchCount:$.length}}function F(r,l){let u;switch(l.mode){case"fixed":u=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");break;case"extended":case"perl":u=r;break;default:u=G(r);break}l.wholeWord&&(u=`(?<![\\w])(?:${u})(?![\\w])`),l.lineRegexp&&(u=`^${u}$`);let f=`g${l.ignoreCase?"i":""}${l.multilineDotall?"s":""}`;return new RegExp(u,f)}function G(r){let l="",u=0;for(;u<r.length;){let f=r[u];if(f==="\\"&&u+1<r.length){let c=r[u+1];if(c==="|"||c==="("||c===")"){l+=c,u+=2;continue}else if(c==="{"||c==="}"){l+=`\\${c}`,u+=2;continue}}f==="+"||f==="?"||f==="|"||f==="("||f===")"||f==="{"||f==="}"?l+=`\\${f}`:l+=f,u++}return l}export{A as a,F as b};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import{a as O,b as R}from"./chunk-X4WRNADE.js";import{a as E,b as _,c as k}from"./chunk-GTNBSMZR.js";import"./chunk-KGOUQS5A.js";var j={js:{extensions:[".js",".mjs",".cjs",".jsx"],globs:[]},ts:{extensions:[".ts",".tsx",".mts",".cts"],globs:[]},html:{extensions:[".html",".htm",".xhtml"],globs:[]},css:{extensions:[".css",".scss",".sass",".less"],globs:[]},json:{extensions:[".json",".jsonc",".json5"],globs:[]},xml:{extensions:[".xml",".xsl",".xslt"],globs:[]},c:{extensions:[".c",".h"],globs:[]},cpp:{extensions:[".cpp",".cc",".cxx",".hpp",".hh",".hxx",".h"],globs:[]},rust:{extensions:[".rs"],globs:[]},go:{extensions:[".go"],globs:[]},zig:{extensions:[".zig"],globs:[]},java:{extensions:[".java"],globs:[]},kotlin:{extensions:[".kt",".kts"],globs:[]},scala:{extensions:[".scala",".sc"],globs:[]},clojure:{extensions:[".clj",".cljc",".cljs",".edn"],globs:[]},py:{extensions:[".py",".pyi",".pyw"],globs:[]},rb:{extensions:[".rb",".rake",".gemspec"],globs:["Rakefile","Gemfile"]},php:{extensions:[".php",".phtml",".php3",".php4",".php5"],globs:[]},perl:{extensions:[".pl",".pm",".pod",".t"],globs:[]},lua:{extensions:[".lua"],globs:[]},sh:{extensions:[".sh",".bash",".zsh",".fish"],globs:[".bashrc",".zshrc",".profile"]},bat:{extensions:[".bat",".cmd"],globs:[]},ps:{extensions:[".ps1",".psm1",".psd1"],globs:[]},yaml:{extensions:[".yaml",".yml"],globs:[]},toml:{extensions:[".toml"],globs:["Cargo.toml","pyproject.toml"]},ini:{extensions:[".ini",".cfg",".conf"],globs:[]},csv:{extensions:[".csv",".tsv"],globs:[]},md:{extensions:[".md",".markdown",".mdown",".mkd"],globs:[]},rst:{extensions:[".rst"],globs:[]},txt:{extensions:[".txt",".text"],globs:[]},tex:{extensions:[".tex",".ltx",".sty",".cls"],globs:[]},sql:{extensions:[".sql"],globs:[]},graphql:{extensions:[".graphql",".gql"],globs:[]},proto:{extensions:[".proto"],globs:[]},make:{extensions:[".mk",".mak"],globs:["Makefile","GNUmakefile","makefile"]},docker:{extensions:[],globs:["Dockerfile","Dockerfile.*","*.dockerfile"]},tf:{extensions:[".tf",".tfvars"],globs:[]}};function P(e,t){let r=e.toLowerCase();for(let s of t){let n=j[s];if(n){for(let i of n.extensions)if(r.endsWith(i))return!0;for(let i of n.globs)if(i.includes("*")){let l=i.replace(/\./g,"\\.").replace(/\*/g,".*");if(new RegExp(`^${l}$`,"i").test(e))return!0}else if(r===i.toLowerCase())return!0}}return!1}function B(){let e=[];for(let[t,r]of Object.entries(j).sort()){let s=[];for(let n of r.extensions)s.push(`*${n}`);for(let n of r.globs)s.push(n);e.push(`${t}: ${s.join(", ")}`)}return`${e.join(`
|
|
3
|
-
`)}
|
|
4
|
-
`}function A(){return{ignoreCase:!1,caseSensitive:!1,smartCase:!0,fixedStrings:!1,wordRegexp:!1,lineRegexp:!1,invertMatch:!1,multiline:!1,patterns:[],patternFiles:[],count:!1,countMatches:!1,filesWithMatches:!1,filesWithoutMatch:!1,onlyMatching:!1,maxCount:0,lineNumber:!0,noFilename:!1,nullSeparator:!1,byteOffset:!1,column:!1,vimgrep:!1,replace:null,afterContext:0,beforeContext:0,contextSeparator:"--",quiet:!1,heading:!1,passthru:!1,includeZero:!1,sort:"path",json:!1,globs:[],types:[],typesNot:[],hidden:!1,noIgnore:!1,maxDepth:1/0,followSymlinks:!1,searchZip:!1,searchBinary:!1}}function U(e){return j[e]?null:{stdout:"",stderr:`rg: unknown type: ${e}
|
|
5
|
-
Use --type-list to see available types.
|
|
6
|
-
`,exitCode:1}}var J=[{short:"g",long:"glob",target:"globs",multi:!0},{short:"t",long:"type",target:"types",multi:!0,validate:U},{short:"T",long:"type-not",target:"typesNot",multi:!0,validate:U},{short:"m",long:"max-count",target:"maxCount",parse:parseInt},{short:"e",long:"regexp",target:"patterns",multi:!0},{short:"f",long:"file",target:"patternFiles",multi:!0},{short:"r",long:"replace",target:"replace"},{long:"max-depth",target:"maxDepth",parse:parseInt},{long:"context-separator",target:"contextSeparator"}],H={i:e=>{e.ignoreCase=!0,e.caseSensitive=!1,e.smartCase=!1},"--ignore-case":e=>{e.ignoreCase=!0,e.caseSensitive=!1,e.smartCase=!1},s:e=>{e.caseSensitive=!0,e.ignoreCase=!1,e.smartCase=!1},"--case-sensitive":e=>{e.caseSensitive=!0,e.ignoreCase=!1,e.smartCase=!1},S:e=>{e.smartCase=!0,e.ignoreCase=!1,e.caseSensitive=!1},"--smart-case":e=>{e.smartCase=!0,e.ignoreCase=!1,e.caseSensitive=!1},F:e=>{e.fixedStrings=!0},"--fixed-strings":e=>{e.fixedStrings=!0},w:e=>{e.wordRegexp=!0},"--word-regexp":e=>{e.wordRegexp=!0},x:e=>{e.lineRegexp=!0},"--line-regexp":e=>{e.lineRegexp=!0},v:e=>{e.invertMatch=!0},"--invert-match":e=>{e.invertMatch=!0},U:e=>{e.multiline=!0},"--multiline":e=>{e.multiline=!0},c:e=>{e.count=!0},"--count":e=>{e.count=!0},"--count-matches":e=>{e.countMatches=!0},l:e=>{e.filesWithMatches=!0},"--files-with-matches":e=>{e.filesWithMatches=!0},"--files-without-match":e=>{e.filesWithoutMatch=!0},o:e=>{e.onlyMatching=!0},"--only-matching":e=>{e.onlyMatching=!0},q:e=>{e.quiet=!0},"--quiet":e=>{e.quiet=!0},N:e=>{e.lineNumber=!1},"--no-line-number":e=>{e.lineNumber=!1},I:e=>{e.noFilename=!0},"--no-filename":e=>{e.noFilename=!0},0:e=>{e.nullSeparator=!0},"--null":e=>{e.nullSeparator=!0},b:e=>{e.byteOffset=!0},"--byte-offset":e=>{e.byteOffset=!0},"--column":e=>{e.column=!0,e.lineNumber=!0},"--vimgrep":e=>{e.vimgrep=!0,e.column=!0,e.lineNumber=!0},"--json":e=>{e.json=!0},"--hidden":e=>{e.hidden=!0},"--no-ignore":e=>{e.noIgnore=!0},L:e=>{e.followSymlinks=!0},"--follow":e=>{e.followSymlinks=!0},z:e=>{e.searchZip=!0},"--search-zip":e=>{e.searchZip=!0},a:e=>{e.searchBinary=!0},"--text":e=>{e.searchBinary=!0},"--heading":e=>{e.heading=!0},"--passthru":e=>{e.passthru=!0},"--include-zero":e=>{e.includeZero=!0}},V=new Set(["n","--line-number"]);function X(e){e.hidden?e.searchBinary=!0:e.noIgnore?e.hidden=!0:e.noIgnore=!0}function K(e,t,r){let s=e[t];for(let n of J){if(s.startsWith(`--${n.long}=`)){let i=s.slice(`--${n.long}=`.length),l=D(r,n,i);return l?{newIndex:t,error:l}:{newIndex:t}}if(n.short&&s===`-${n.short}`||s===`--${n.long}`){if(t+1>=e.length)return null;let i=e[t+1],l=D(r,n,i);return l?{newIndex:t+1,error:l}:{newIndex:t+1}}}return null}function D(e,t,r){if(t.validate){let n=t.validate(r);if(n)return n}let s=t.parse?t.parse(r):r;t.multi?e[t.target].push(s):e[t.target]=s}function Q(e,t){let r=e[t];if(r==="--sort"&&t+1<e.length){let s=e[t+1];if(s==="path"||s==="none")return{value:s,newIndex:t+1}}if(r.startsWith("--sort=")){let s=r.slice(7);if(s==="path"||s==="none")return{value:s,newIndex:t}}return null}function ee(e,t){let r=e[t],s=r.match(/^-([ABC])(\d+)$/);return s?{flag:s[1],value:parseInt(s[2],10),newIndex:t}:(r==="-A"||r==="-B"||r==="-C")&&t+1<e.length?{flag:r[1],value:parseInt(e[t+1],10),newIndex:t+1}:null}function te(e){let t=e.match(/^-m(\d+)$/);return t?parseInt(t[1],10):null}function q(e){let t=A(),r=null,s=[],n=-1,i=-1,l=-1,o=!1;for(let a=0;a<e.length;a++){let c=e[a];if(c.startsWith("-")&&c!=="-"){let u=ee(e,a);if(u){let{flag:f,value:m,newIndex:x}=u;f==="A"?n=Math.max(n,m):f==="B"?i=Math.max(i,m):l=m,a=x;continue}let h=te(c);if(h!==null){t.maxCount=h;continue}let d=K(e,a,t);if(d){if(d.error)return{success:!1,error:d.error};a=d.newIndex;continue}let g=Q(e,a);if(g){t.sort=g.value,a=g.newIndex;continue}let p=c.startsWith("--")?[c]:c.slice(1).split("");for(let f of p){if(V.has(f)){t.lineNumber=!0,o=!0;continue}if(f==="u"||f==="--unrestricted"){X(t);continue}let m=H[f];if(m){m(t);continue}if(f.startsWith("--"))return{success:!1,error:k("rg",f)};if(f.length===1)return{success:!1,error:k("rg",`-${f}`)}}}else r===null?r=c:s.push(c)}return(n>=0||l>=0)&&(t.afterContext=Math.max(n>=0?n:0,l>=0?l:0)),(i>=0||l>=0)&&(t.beforeContext=Math.max(i>=0?i:0,l>=0?l:0)),r!==null&&t.patterns.push(r),(t.column||t.vimgrep)&&(o=!0),{success:!0,options:t,paths:s,explicitLineNumbers:o}}import{gunzipSync as se}from"node:zlib";var W=class{patterns=[];basePath;constructor(t="/"){this.basePath=t}parse(t){let r=t.split(`
|
|
7
|
-
`);for(let s of r){let n=s.replace(/\s+$/,"");if(!n||n.startsWith("#"))continue;let i=!1;n.startsWith("!")&&(i=!0,n=n.slice(1));let l=!1;n.endsWith("/")&&(l=!0,n=n.slice(0,-1));let o=!1;n.startsWith("/")?(o=!0,n=n.slice(1)):n.includes("/")&&!n.startsWith("**/")&&(o=!0);let a=this.patternToRegex(n,o);this.patterns.push({pattern:s,regex:a,negated:i,directoryOnly:l,rooted:o})}}patternToRegex(t,r){let s="";r?s="^":s="(?:^|/)";let n=0;for(;n<t.length;){let i=t[n];if(i==="*")t[n+1]==="*"?t[n+2]==="/"?(s+="(?:.*/)?",n+=3):(n+2>=t.length,s+=".*",n+=2):(s+="[^/]*",n++);else if(i==="?")s+="[^/]",n++;else if(i==="["){let l=n+1;for(l<t.length&&t[l]==="!"&&l++,l<t.length&&t[l]==="]"&&l++;l<t.length&&t[l]!=="]";)l++;if(l<t.length){let o=t.slice(n,l+1);o.startsWith("[!")&&(o=`[^${o.slice(2)}`),s+=o,n=l+1}else s+="\\[",n++}else i==="/"?(s+="/",n++):(s+=i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n++)}return s+="(?:/.*)?$",new RegExp(s)}matches(t,r){let s=t.replace(/^\.\//,"");s=s.replace(/^\//,"");let n=!1;for(let i of this.patterns)i.directoryOnly&&!r||i.regex.test(s)&&(n=!i.negated);return n}getBasePath(){return this.basePath}},M=class{parsers=[];fs;rootPath;constructor(t,r){this.fs=t,this.rootPath=r}async load(t){let r=[],s=t;for(;s.startsWith(this.rootPath)||s===this.rootPath;){r.unshift(s);let n=this.fs.resolvePath(s,"..");if(n===s)break;s=n}for(let n of r)for(let i of[".gitignore",".ignore"]){let l=this.fs.resolvePath(n,i);try{let o=await this.fs.readFile(l),a=new W(n);a.parse(o),this.parsers.push(a)}catch{}}}matches(t,r){for(let s of this.parsers){let n=s.getBasePath();if(!t.startsWith(n))continue;let i=t.slice(n.length).replace(/^\//,"");if(s.matches(i,r))return!0}return!1}static isCommonIgnored(t){return new Set(["node_modules",".git",".svn",".hg","__pycache__",".pytest_cache",".mypy_cache","venv",".venv","dist","build",".next",".nuxt","target",".cargo"]).has(t)}};async function z(e,t){let r=new M(e,t);return await r.load(t),r}function ne(e){return e.length>=2&&e[0]===31&&e[1]===139}async function G(e){let{ctx:t,options:r,paths:s,explicitLineNumbers:n}=e,i=[...r.patterns];for(let p of r.patternFiles)try{let f=t.fs.resolvePath(t.cwd,p),x=(await t.fs.readFile(f)).split(`
|
|
8
|
-
`).filter(y=>y.length>0);i.push(...x)}catch{return{stdout:"",stderr:`rg: ${p}: No such file or directory
|
|
9
|
-
`,exitCode:2}}if(i.length===0)return{stdout:"",stderr:`rg: no pattern given
|
|
10
|
-
`,exitCode:2};let l=s.length===0?["."]:s,o=re(r,i),a;try{a=ie(i,r,o)}catch{return{stdout:"",stderr:`rg: invalid regex: ${i.join(", ")}
|
|
11
|
-
`,exitCode:2}}let c=null;r.noIgnore||(c=await z(t.fs,t.cwd));let{files:u,singleExplicitFile:h}=await le(t,l,r,c);if(u.length===0)return{stdout:"",stderr:"",exitCode:1};let d=!r.noFilename&&(!h||u.length>1),g=r.lineNumber;return n||(h&&u.length===1&&(g=!1),r.onlyMatching&&(g=!1)),oe(t,u,a,r,d,g)}function re(e,t){return e.caseSensitive?!1:e.ignoreCase?!0:e.smartCase?!t.some(r=>/[A-Z]/.test(r)):!1}function ie(e,t,r){let s;return e.length===1?s=e[0]:s=e.map(n=>t.fixedStrings?n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"):`(?:${n})`).join("|"),R(s,{mode:t.fixedStrings&&e.length===1?"fixed":"perl",ignoreCase:r,wholeWord:t.wordRegexp,lineRegexp:t.lineRegexp,multiline:t.multiline})}async function le(e,t,r,s){let n=[],i=0,l=0;for(let a of t){let c=e.fs.resolvePath(e.cwd,a);try{let u=await e.fs.stat(c);u.isFile?(i++,Y(a,r,s,c)&&n.push(a)):u.isDirectory&&(l++,await Z(e,a,c,0,r,s,n))}catch{}}return{files:r.sort==="path"?n.sort():n,singleExplicitFile:i===1&&l===0}}async function Z(e,t,r,s,n,i,l){if(!(s>=n.maxDepth))try{let o=e.fs.readdirWithFileTypes?await e.fs.readdirWithFileTypes(r):(await e.fs.readdir(r)).map(a=>({name:a,isFile:void 0}));for(let a of o){let c=a.name;if(!n.hidden&&c.startsWith(".")||!n.noIgnore&&M.isCommonIgnored(c))continue;let u=t==="."?c:`${t}/${c}`,h=e.fs.resolvePath(r,c),d,g,p=!1;if(a.isFile!==void 0&&"isDirectory"in a){let m=a;if(p=m.isSymbolicLink===!0,p&&!n.followSymlinks)continue;if(p&&n.followSymlinks)try{let x=await e.fs.stat(h);d=x.isFile,g=x.isDirectory}catch{continue}else d=m.isFile,g=m.isDirectory}else try{let m=e.fs.lstat?await e.fs.lstat(h):await e.fs.stat(h);if(p=m.isSymbolicLink===!0,p&&!n.followSymlinks)continue;let x=p&&n.followSymlinks?await e.fs.stat(h):m;d=x.isFile,g=x.isDirectory}catch{continue}i?.matches(h,g)||(g?await Z(e,u,h,s+1,n,i,l):d&&Y(u,n,i,h)&&l.push(u))}}catch{}}function Y(e,t,r,s){let n=e.split("/").pop()||e;if(r?.matches(s,!1)||t.types.length>0&&!P(n,t.types)||t.typesNot.length>0&&P(n,t.typesNot))return!1;if(t.globs.length>0){let i=t.globs.filter(o=>!o.startsWith("!")),l=t.globs.filter(o=>o.startsWith("!")).map(o=>o.slice(1));if(i.length>0){let o=!1;for(let a of i)if(I(n,a)||I(e,a)){o=!0;break}if(!o)return!1}for(let o of l)if(o.startsWith("/")){let a=o.slice(1);if(I(e,a))return!1}else if(I(n,o)||I(e,o))return!1}return!0}function I(e,t){let r="^";for(let s=0;s<t.length;s++){let n=t[s];if(n==="*")t[s+1]==="*"?(r+=".*",s++):r+="[^/]*";else if(n==="?")r+="[^/]";else if(n==="["){let i=s+1;for(i<t.length&&t[i]==="!"&&i++,i<t.length&&t[i]==="]"&&i++;i<t.length&&t[i]!=="]";)i++;if(i<t.length){let l=t.slice(s,i+1);l.startsWith("[!")&&(l=`[^${l.slice(2)}`),r+=l,s=i}else r+="\\["}else r+=n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}return r+="$",new RegExp(r).test(e)}async function ae(e,t,r,s){try{if(s.searchZip&&r.endsWith(".gz")){let l=await e.fs.readFileBuffer(t);if(ne(l))try{let o=se(l),a=new TextDecoder().decode(o),c=a.slice(0,8192);return{content:a,isBinary:c.includes("\0")}}catch{return null}}let n=await e.fs.readFile(t),i=n.slice(0,8192);return{content:n,isBinary:i.includes("\0")}}catch{return null}}async function oe(e,t,r,s,n,i){let l="",o=!1,a=[],c=0,u=0,h=0,d=50;e:for(let f=0;f<t.length;f+=d){let m=t.slice(f,f+d),x=await Promise.all(m.map(async y=>{let S=e.fs.resolvePath(e.cwd,y),w=await ae(e,S,y,s);if(!w)return null;let{content:b,isBinary:N}=w;if(h+=b.length,N&&!s.searchBinary)return null;let F=n&&!s.heading?y:"",C=O(b,r,{invertMatch:s.invertMatch,showLineNumbers:i,countOnly:s.count,countMatches:s.countMatches,filename:F,onlyMatching:s.onlyMatching,beforeContext:s.beforeContext,afterContext:s.afterContext,maxCount:s.maxCount,contextSeparator:s.contextSeparator,showColumn:s.column,vimgrep:s.vimgrep,showByteOffset:s.byteOffset,replace:s.replace,passthru:s.passthru,multiline:s.multiline});return s.json&&C.matched?{file:y,result:C,content:b,isBinary:!1}:{file:y,result:C}}));for(let y of x){if(!y)continue;let{file:S,result:w}=y;if(w.matched){if(o=!0,u++,c+=w.matchCount,s.quiet&&!s.json)break e;if(s.json&&!s.quiet){let b=y.content||"";a.push(JSON.stringify({type:"begin",data:{path:{text:S}}}));let N=b.split(`
|
|
12
|
-
`);r.lastIndex=0;let F=0;for(let C=0;C<N.length;C++){let $=N[C];r.lastIndex=0;let T=[];for(let v=r.exec($);v!==null;v=r.exec($)){let L={match:{text:v[0]},start:v.index,end:v.index+v[0].length};s.replace!==null&&(L.replacement={text:s.replace}),T.push(L),v[0].length===0&&r.lastIndex++}if(T.length>0){let v={type:"match",data:{path:{text:S},lines:{text:`${$}
|
|
13
|
-
`},line_number:C+1,absolute_offset:F,submatches:T}};a.push(JSON.stringify(v))}F+=$.length+1}a.push(JSON.stringify({type:"end",data:{path:{text:S},binary_offset:null,stats:{elapsed:{secs:0,nanos:0,human:"0s"},searches:1,searches_with_match:1,bytes_searched:b.length,bytes_printed:0,matched_lines:w.matchCount,matches:w.matchCount}}}))}else if(s.filesWithMatches){let b=s.nullSeparator?"\0":`
|
|
14
|
-
`;l+=`${S}${b}`}else s.filesWithoutMatch||(s.heading&&n&&(l+=`${S}
|
|
15
|
-
`),l+=w.output)}else if(s.filesWithoutMatch){let b=s.nullSeparator?"\0":`
|
|
16
|
-
`;l+=`${S}${b}`}else s.includeZero&&(s.count||s.countMatches)&&(l+=w.output)}}s.json&&(a.push(JSON.stringify({type:"summary",data:{elapsed_total:{secs:0,nanos:0,human:"0s"},stats:{elapsed:{secs:0,nanos:0,human:"0s"},searches:t.length,searches_with_match:u,bytes_searched:h,bytes_printed:0,matched_lines:c,matches:c}}})),l=`${a.join(`
|
|
17
|
-
`)}
|
|
18
|
-
`);let g=s.quiet&&!s.json?"":l,p;return s.filesWithoutMatch?p=l.length>0?0:1:p=o?0:1,{stdout:g,stderr:"",exitCode:p}}var ce={name:"rg",summary:"recursively search for a pattern",usage:"rg [OPTIONS] PATTERN [PATH ...]",description:`rg (ripgrep) recursively searches directories for a regex pattern.
|
|
19
|
-
Unlike grep, rg is recursive by default and respects .gitignore files.
|
|
20
|
-
|
|
21
|
-
EXAMPLES:
|
|
22
|
-
rg foo Search for 'foo' in current directory
|
|
23
|
-
rg foo src/ Search in src/ directory
|
|
24
|
-
rg -i foo Case-insensitive search
|
|
25
|
-
rg -w foo Match whole words only
|
|
26
|
-
rg -t js foo Search only JavaScript files
|
|
27
|
-
rg -g '*.ts' foo Search files matching glob
|
|
28
|
-
rg --hidden foo Include hidden files
|
|
29
|
-
rg -l foo List files with matches only`,options:["-e, --regexp PATTERN search for PATTERN (can be used multiple times)","-f, --file FILE read patterns from FILE, one per line","-i, --ignore-case case-insensitive search","-s, --case-sensitive case-sensitive search (overrides smart-case)","-S, --smart-case smart case (default: case-insensitive unless pattern has uppercase)","-F, --fixed-strings treat pattern as literal string","-w, --word-regexp match whole words only","-x, --line-regexp match whole lines only","-v, --invert-match select non-matching lines","-r, --replace TEXT replace matches with TEXT","-c, --count print count of matching lines per file"," --count-matches print count of individual matches per file","-l, --files-with-matches print only file names with matches"," --files-without-match print file names without matches","-o, --only-matching print only matching parts","-m, --max-count NUM stop after NUM matches per file","-q, --quiet suppress output, exit 0 on match","-n, --line-number print line numbers (default: on)","-N, --no-line-number do not print line numbers","-I, --no-filename suppress the prefixing of file names","-0, --null use NUL as filename separator","-b, --byte-offset show byte offset of each match"," --column show column number of first match"," --vimgrep show results in vimgrep format"," --json show results in JSON Lines format","-A NUM print NUM lines after each match","-B NUM print NUM lines before each match","-C NUM print NUM lines before and after each match"," --context-separator SEP separator for context groups (default: --)","-U, --multiline match patterns across lines","-z, --search-zip search in compressed files (gzip only)","-g, --glob GLOB include files matching GLOB","-t, --type TYPE only search files of TYPE (e.g., js, py, ts)","-T, --type-not TYPE exclude files of TYPE","-L, --follow follow symbolic links","-u, --unrestricted reduce filtering (-u: no ignore, -uu: +hidden, -uuu: +binary)","-a, --text search binary files as text"," --hidden search hidden files and directories"," --no-ignore don't respect .gitignore/.ignore files"," --max-depth NUM maximum search depth"," --sort TYPE sort files (path, none)"," --heading show file path above matches"," --passthru print all lines (non-matches use - separator)"," --include-zero include files with 0 matches in count output"," --type-list list all available file types"," --help display this help and exit"]},Ne={name:"rg",async execute(e,t){if(_(e))return E(ce);if(e.includes("--type-list"))return{stdout:B(),stderr:"",exitCode:0};let r=q(e);return r.success?G({ctx:t,options:r.options,paths:r.paths,explicitLineNumbers:r.explicitLineNumbers}):r.error}};export{Ne as rgCommand};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
function A(r,l,u={}){let{invertMatch:f=!1,showLineNumbers:c=!1,countOnly:B=!1,countMatches:j=!1,filename:a="",onlyMatching:T=!1,beforeContext:N=0,afterContext:v=0,maxCount:w=0,contextSeparator:P="--",showColumn:M=!1,vimgrep:z=!1,showByteOffset:b=!1,replace:p=null,passthru:g=!1,multiline:R=!1}=u;if(R)return D(r,l,{invertMatch:f,showLineNumbers:c,countOnly:B,countMatches:j,filename:a,onlyMatching:T,beforeContext:N,afterContext:v,maxCount:w,contextSeparator:P,showColumn:M,showByteOffset:b,replace:p});let d=r.split(`
|
|
3
|
-
`),S=d.length,y=S>0&&d[S-1]===""?S-1:S;if(B||j){let i=0;for(let e=0;e<y;e++)if(l.lastIndex=0,j)for(let t=l.exec(d[e]);t!==null;t=l.exec(d[e]))f||i++,t[0].length===0&&l.lastIndex++;else l.test(d[e])!==f&&i++;return{output:`${a?`${a}:${i}`:String(i)}
|
|
4
|
-
`,matched:i>0,matchCount:i}}if(N===0&&v===0&&!g){let i=[],o=!1,e=0,t=0;for(let s=0;s<y&&!(w>0&&e>=w);s++){let L=d[s];if(l.lastIndex=0,l.test(L)!==f)if(o=!0,e++,T){l.lastIndex=0;for(let h=l.exec(L);h!==null;h=l.exec(L)){let I=p!==null?p:h[0],k=a?`${a}:`:"";b&&(k+=`${t+h.index}:`),c&&(k+=`${s+1}:`),M&&(k+=`${h.index+1}:`),i.push(k+I),h[0].length===0&&l.lastIndex++}}else if(z){l.lastIndex=0;for(let h=l.exec(L);h!==null;h=l.exec(L)){let I=a?`${a}:`:"";b&&(I+=`${t+h.index}:`),c&&(I+=`${s+1}:`),M&&(I+=`${h.index+1}:`),i.push(I+L),h[0].length===0&&l.lastIndex++}}else{l.lastIndex=0;let h=l.exec(L),I=h?h.index+1:1,k=L;p!==null&&(l.lastIndex=0,k=L.replace(l,p));let E=a?`${a}:`:"";b&&(E+=`${t+(h?h.index:0)}:`),c&&(E+=`${s+1}:`),M&&(E+=`${I}:`),i.push(E+k)}t+=L.length+1}return{output:i.length>0?`${i.join(`
|
|
5
|
-
`)}
|
|
6
|
-
`:"",matched:o,matchCount:e}}if(g){let i=[],o=!1,e=0;for(let t=0;t<y;t++){let s=d[t];l.lastIndex=0;let O=l.test(s)!==f;O&&(o=!0,e++);let h=O?":":"-",I=a?`${a}${h}`:"";c&&(I+=`${t+1}${h}`),i.push(I+s)}return{output:i.length>0?`${i.join(`
|
|
7
|
-
`)}
|
|
8
|
-
`:"",matched:o,matchCount:e}}let $=[],C=0,m=new Set,x=-1,n=[];for(let i=0;i<y&&!(w>0&&C>=w);i++)l.lastIndex=0,l.test(d[i])!==f&&(n.push(i),C++);for(let i of n){let o=Math.max(0,i-N);x>=0&&o>x+1&&$.push(P);for(let t=o;t<i;t++)if(!m.has(t)){m.add(t),x=t;let s=d[t];c&&(s=`${t+1}-${s}`),a&&(s=`${a}-${s}`),$.push(s)}if(!m.has(i)){m.add(i),x=i;let t=d[i];if(T){l.lastIndex=0;for(let s=l.exec(t);s!==null;s=l.exec(t)){let L=p!==null?p:s[0],O=a?`${a}:`:"";c&&(O+=`${i+1}:`),M&&(O+=`${s.index+1}:`),$.push(O+L),s[0].length===0&&l.lastIndex++}}else{let s=t;c&&(s=`${i+1}:${s}`),a&&(s=`${a}:${s}`),$.push(s)}}let e=Math.min(y-1,i+v);for(let t=i+1;t<=e;t++)if(!m.has(t)){m.add(t),x=t;let s=d[t];c&&(s=`${t+1}-${s}`),a&&(s=`${a}-${s}`),$.push(s)}}return{output:$.length>0?`${$.join(`
|
|
9
|
-
`)}
|
|
10
|
-
`:"",matched:C>0,matchCount:C}}function D(r,l,u){let{invertMatch:f,showLineNumbers:c,countOnly:B,countMatches:j,filename:a,onlyMatching:T,beforeContext:N,afterContext:v,maxCount:w,contextSeparator:P,showColumn:M,showByteOffset:z,replace:b}=u,p=r.split(`
|
|
11
|
-
`),g=p.length,R=g>0&&p[g-1]===""?g-1:g,d=[0];for(let n=0;n<r.length;n++)r[n]===`
|
|
12
|
-
`&&d.push(n+1);let S=n=>{let i=0;for(let o=0;o<d.length&&!(d[o]>n);o++)i=o;return i},y=n=>{let i=S(n);return n-d[i]+1},$=[];l.lastIndex=0;for(let n=l.exec(r);n!==null&&!(w>0&&$.length>=w);n=l.exec(r)){let i=S(n.index),o=S(n.index+Math.max(0,n[0].length-1));$.push({startLine:i,endLine:o,byteOffset:n.index,column:y(n.index),matchText:n[0]}),n[0].length===0&&l.lastIndex++}if(B||j){let n;if(j)n=f?0:$.length;else{let o=new Set;for(let e of $)for(let t=e.startLine;t<=e.endLine;t++)o.add(t);n=f?R-o.size:o.size}return{output:`${a?`${a}:${n}`:String(n)}
|
|
13
|
-
`,matched:n>0,matchCount:n}}if(f){let n=new Set;for(let o of $)for(let e=o.startLine;e<=o.endLine;e++)n.add(e);let i=[];for(let o=0;o<R;o++)if(!n.has(o)){let e=p[o];c&&(e=`${o+1}:${e}`),a&&(e=`${a}:${e}`),i.push(e)}return{output:i.length>0?`${i.join(`
|
|
14
|
-
`)}
|
|
15
|
-
`:"",matched:i.length>0,matchCount:i.length}}if($.length===0)return{output:"",matched:!1,matchCount:0};let C=new Set,m=-1,x=[];for(let n of $){let i=Math.max(0,n.startLine-N),o=Math.min(R-1,n.endLine+v);m>=0&&i>m+1&&x.push(P);for(let e=i;e<n.startLine;e++)if(!C.has(e)){C.add(e),m=e;let t=p[e];c&&(t=`${e+1}-${t}`),a&&(t=`${a}-${t}`),x.push(t)}if(T){let e=b!==null?b:n.matchText,t=a?`${a}:`:"";z&&(t+=`${n.byteOffset}:`),c&&(t+=`${n.startLine+1}:`),M&&(t+=`${n.column}:`),x.push(t+e);for(let s=n.startLine;s<=n.endLine;s++)C.add(s),m=s}else for(let e=n.startLine;e<=n.endLine&&e<R;e++)if(!C.has(e)){C.add(e),m=e;let t=p[e];b!==null&&e===n.startLine&&(l.lastIndex=0,t=t.replace(l,b));let s=a?`${a}:`:"";z&&e===n.startLine&&(s+=`${n.byteOffset}:`),c&&(s+=`${e+1}:`),M&&e===n.startLine&&(s+=`${n.column}:`),x.push(s+t)}for(let e=n.endLine+1;e<=o;e++)if(!C.has(e)){C.add(e),m=e;let t=p[e];c&&(t=`${e+1}-${t}`),a&&(t=`${a}-${t}`),x.push(t)}}return{output:x.length>0?`${x.join(`
|
|
16
|
-
`)}
|
|
17
|
-
`:"",matched:!0,matchCount:$.length}}function F(r,l){let u;switch(l.mode){case"fixed":u=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");break;case"extended":case"perl":u=r;break;default:u=G(r);break}l.wholeWord&&(u=`(?<![\\w])(?:${u})(?![\\w])`),l.lineRegexp&&(u=`^${u}$`);let f=`g${l.ignoreCase?"i":""}${l.multilineDotall?"s":""}`;return new RegExp(u,f)}function G(r){let l="",u=0;for(;u<r.length;){let f=r[u];if(f==="\\"&&u+1<r.length){let c=r[u+1];if(c==="|"||c==="("||c===")"){l+=c,u+=2;continue}else if(c==="{"||c==="}"){l+=`\\${c}`,u+=2;continue}}f==="+"||f==="?"||f==="|"||f==="("||f===")"||f==="{"||f==="}"?l+=`\\${f}`:l+=f,u++}return l}export{A as a,F as b};
|