sandbox-fs 1.0.0 → 1.1.0

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.
Files changed (60) hide show
  1. package/README.md +16 -0
  2. package/dist/FSModule.d.ts.map +1 -1
  3. package/dist/FSModule.js +81 -18
  4. package/dist/FSModule.js.map +1 -1
  5. package/dist/PathMapper.d.ts.map +1 -1
  6. package/dist/PathMapper.js +147 -41
  7. package/dist/PathMapper.js.map +1 -1
  8. package/dist/VirtualFileSystem.d.ts.map +1 -1
  9. package/dist/VirtualFileSystem.js +27 -1
  10. package/dist/VirtualFileSystem.js.map +1 -1
  11. package/dist/operations/newer.d.ts.map +1 -1
  12. package/dist/operations/newer.js +32 -3
  13. package/dist/operations/newer.js.map +1 -1
  14. package/dist/operations/read.d.ts.map +1 -1
  15. package/dist/operations/read.js +100 -14
  16. package/dist/operations/read.js.map +1 -1
  17. package/dist/utils/ErrorFilter.d.ts.map +1 -1
  18. package/dist/utils/ErrorFilter.js +21 -24
  19. package/dist/utils/ErrorFilter.js.map +1 -1
  20. package/dist/wrappers/VirtualDir.d.ts.map +1 -1
  21. package/dist/wrappers/VirtualDir.js +36 -35
  22. package/dist/wrappers/VirtualDir.js.map +1 -1
  23. package/dist/wrappers/VirtualDirent.d.ts.map +1 -1
  24. package/dist/wrappers/VirtualDirent.js +28 -9
  25. package/dist/wrappers/VirtualDirent.js.map +1 -1
  26. package/package.json +8 -4
  27. package/dist/FSModule.d.ts +0 -153
  28. package/dist/PathMapper.d.ts +0 -30
  29. package/dist/PathModule.d.ts +0 -69
  30. package/dist/ResourceTracker.d.ts +0 -74
  31. package/dist/VirtualFileSystem.d.ts +0 -145
  32. package/dist/index.d.ts +0 -9
  33. package/dist/operations/newer.d.ts +0 -36
  34. package/dist/operations/read.d.ts +0 -24
  35. package/dist/operations/symlink.d.ts +0 -8
  36. package/dist/operations/write.d.ts +0 -29
  37. package/dist/utils/ErrorFilter.d.ts +0 -6
  38. package/dist/utils/callbackify.d.ts +0 -9
  39. package/dist/wrappers/VirtualDir.d.ts +0 -34
  40. package/dist/wrappers/VirtualDirent.d.ts +0 -21
  41. package/example.js +0 -95
  42. package/example.ts +0 -32
  43. package/src/FSModule.ts +0 -546
  44. package/src/PathMapper.ts +0 -102
  45. package/src/PathModule.ts +0 -142
  46. package/src/ResourceTracker.ts +0 -162
  47. package/src/VirtualFileSystem.ts +0 -172
  48. package/src/index.ts +0 -9
  49. package/src/operations/newer.ts +0 -223
  50. package/src/operations/read.ts +0 -319
  51. package/src/operations/symlink.ts +0 -31
  52. package/src/operations/write.ts +0 -189
  53. package/src/utils/ErrorFilter.ts +0 -57
  54. package/src/utils/callbackify.ts +0 -54
  55. package/src/wrappers/VirtualDir.ts +0 -84
  56. package/src/wrappers/VirtualDirent.ts +0 -60
  57. package/test-data/example.txt +0 -1
  58. package/test-data/subdir/nested.txt +0 -1
  59. package/tsconfig.example.json +0 -8
  60. package/tsconfig.json +0 -21
@@ -1,319 +0,0 @@
1
- import * as fs from 'fs';
2
- import type { PathMapper } from '../PathMapper';
3
- import type { ResourceTracker } from '../ResourceTracker';
4
- import { filterError } from '../utils/ErrorFilter';
5
- import { VirtualDir } from '../wrappers/VirtualDir';
6
-
7
- /**
8
- * Create access denied error for write operations
9
- */
10
- function createEACCESError(syscall: string, path: string): NodeJS.ErrnoException {
11
- const error = new Error(`${syscall}: operation not permitted, ${syscall} '${path}'`) as NodeJS.ErrnoException;
12
- error.code = 'EACCES';
13
- error.errno = -13;
14
- error.syscall = syscall;
15
- error.path = path;
16
- return error;
17
- }
18
-
19
- /**
20
- * Wrap an async operation with error filtering and closed check
21
- */
22
- async function wrapOperation<T>(
23
- operation: () => Promise<T>,
24
- pathMapper: PathMapper,
25
- resourceTracker: ResourceTracker
26
- ): Promise<T> {
27
- resourceTracker.assertNotClosed();
28
- try {
29
- return await operation();
30
- } catch (error) {
31
- throw filterError(error as Error, pathMapper);
32
- }
33
- }
34
-
35
- /**
36
- * Read file operations
37
- */
38
- export function createReadFileOperation(pathMapper: PathMapper, resourceTracker: ResourceTracker) {
39
- return async (virtualPath: string, options?: any): Promise<Buffer | string> => {
40
- return wrapOperation(async () => {
41
- const realPath = pathMapper.toRealPath(virtualPath);
42
-
43
- // Handle AbortSignal if present
44
- if (options?.signal) {
45
- resourceTracker.registerAbortListener(options.signal, () => {});
46
- }
47
-
48
- return fs.promises.readFile(realPath, options);
49
- }, pathMapper, resourceTracker);
50
- };
51
- }
52
-
53
- export function createReaddirOperation(pathMapper: PathMapper, resourceTracker: ResourceTracker) {
54
- return async (virtualPath: string, options?: any): Promise<string[] | Buffer[] | fs.Dirent[]> => {
55
- return wrapOperation(async () => {
56
- const realPath = pathMapper.toRealPath(virtualPath);
57
-
58
- if (options?.signal) {
59
- resourceTracker.registerAbortListener(options.signal, () => {});
60
- }
61
-
62
- return fs.promises.readdir(realPath, options);
63
- }, pathMapper, resourceTracker);
64
- };
65
- }
66
-
67
- export function createStatOperation(pathMapper: PathMapper, resourceTracker: ResourceTracker) {
68
- return async (virtualPath: string, options?: any): Promise<fs.Stats> => {
69
- return wrapOperation(async () => {
70
- const realPath = pathMapper.toRealPath(virtualPath);
71
-
72
- if (options?.signal) {
73
- resourceTracker.registerAbortListener(options.signal, () => {});
74
- }
75
-
76
- const stats = await fs.promises.stat(realPath, options);
77
-
78
- // Return EACCES for symlinks
79
- if (stats.isSymbolicLink()) {
80
- throw createEACCESError('stat', virtualPath);
81
- }
82
-
83
- return stats;
84
- }, pathMapper, resourceTracker);
85
- };
86
- }
87
-
88
- export function createLstatOperation(pathMapper: PathMapper, resourceTracker: ResourceTracker) {
89
- return async (virtualPath: string, options?: any): Promise<fs.Stats> => {
90
- return wrapOperation(async () => {
91
- const realPath = pathMapper.toRealPath(virtualPath);
92
-
93
- if (options?.signal) {
94
- resourceTracker.registerAbortListener(options.signal, () => {});
95
- }
96
-
97
- const stats = await fs.promises.lstat(realPath, options);
98
-
99
- // Return EACCES for symlinks
100
- if (stats.isSymbolicLink()) {
101
- throw createEACCESError('lstat', virtualPath);
102
- }
103
-
104
- return stats;
105
- }, pathMapper, resourceTracker);
106
- };
107
- }
108
-
109
- export function createAccessOperation(pathMapper: PathMapper, resourceTracker: ResourceTracker) {
110
- return async (virtualPath: string, mode?: number): Promise<void> => {
111
- return wrapOperation(async () => {
112
- const realPath = pathMapper.toRealPath(virtualPath);
113
- return fs.promises.access(realPath, mode);
114
- }, pathMapper, resourceTracker);
115
- };
116
- }
117
-
118
- export function createRealpathOperation(pathMapper: PathMapper, resourceTracker: ResourceTracker) {
119
- return async (virtualPath: string, options?: any): Promise<string | Buffer> => {
120
- return wrapOperation(async () => {
121
- const realPath = pathMapper.toRealPath(virtualPath);
122
-
123
- if (options?.signal) {
124
- resourceTracker.registerAbortListener(options.signal, () => {});
125
- }
126
-
127
- const resolvedRealPath = await fs.promises.realpath(realPath, options);
128
-
129
- // Convert back to virtual path
130
- const resolvedStr = Buffer.isBuffer(resolvedRealPath) ? resolvedRealPath.toString() : resolvedRealPath;
131
- const resolvedVirtualPath = pathMapper.toVirtualPath(resolvedStr);
132
-
133
- // Return as buffer if encoding option is 'buffer'
134
- if (options && typeof options === 'object' && options.encoding === 'buffer') {
135
- return Buffer.from(resolvedVirtualPath) as any;
136
- }
137
- return resolvedVirtualPath as any;
138
- }, pathMapper, resourceTracker);
139
- };
140
- }
141
-
142
- export function createOpenOperation(pathMapper: PathMapper, resourceTracker: ResourceTracker) {
143
- return async (virtualPath: string, flags?: string | number, mode?: number): Promise<number> => {
144
- return wrapOperation(async () => {
145
- // Check if flags indicate write mode
146
- const flagsStr = typeof flags === 'number' ? flags.toString() : (flags || 'r');
147
- const isWriteMode = /w|a|\+/.test(flagsStr.toString());
148
-
149
- if (isWriteMode) {
150
- throw createEACCESError('open', virtualPath);
151
- }
152
-
153
- const realPath = pathMapper.toRealPath(virtualPath);
154
- const fd = await fs.promises.open(realPath, flags, mode);
155
-
156
- // Track the file descriptor
157
- resourceTracker.trackFD(fd.fd, {
158
- virtualPath,
159
- realPath,
160
- flags: flags || 'r',
161
- mode,
162
- isStream: false,
163
- });
164
-
165
- return fd.fd;
166
- }, pathMapper, resourceTracker);
167
- };
168
- }
169
-
170
- export function createReadOperation(pathMapper: PathMapper, resourceTracker: ResourceTracker) {
171
- return async (
172
- fd: number,
173
- buffer: NodeJS.ArrayBufferView,
174
- offset: number,
175
- length: number,
176
- position: number | null
177
- ): Promise<{ bytesRead: number; buffer: NodeJS.ArrayBufferView }> => {
178
- return wrapOperation(async () => {
179
- // Verify FD is tracked
180
- if (!resourceTracker.isTracked(fd)) {
181
- const error = new Error('bad file descriptor') as NodeJS.ErrnoException;
182
- error.code = 'EBADF';
183
- error.errno = -9;
184
- error.syscall = 'read';
185
- throw error;
186
- }
187
-
188
- // Use fs.read with callback wrapped in promise
189
- return new Promise<{ bytesRead: number; buffer: NodeJS.ArrayBufferView }>((resolve, reject) => {
190
- fs.read(fd, buffer, offset, length, position, (err, bytesRead) => {
191
- if (err) reject(err);
192
- else resolve({ bytesRead, buffer });
193
- });
194
- });
195
- }, pathMapper, resourceTracker);
196
- };
197
- }
198
-
199
- export function createCloseOperation(pathMapper: PathMapper, resourceTracker: ResourceTracker) {
200
- return async (fd: number): Promise<void> => {
201
- return wrapOperation(async () => {
202
- // Untrack before closing
203
- resourceTracker.untrackFD(fd);
204
- return new Promise<void>((resolve, reject) => {
205
- fs.close(fd, (err) => {
206
- if (err) reject(err);
207
- else resolve();
208
- });
209
- });
210
- }, pathMapper, resourceTracker);
211
- };
212
- }
213
-
214
- export function createFstatOperation(pathMapper: PathMapper, resourceTracker: ResourceTracker) {
215
- return async (fd: number, options?: any): Promise<fs.Stats> => {
216
- return wrapOperation(async () => {
217
- if (!resourceTracker.isTracked(fd)) {
218
- const error = new Error('bad file descriptor') as NodeJS.ErrnoException;
219
- error.code = 'EBADF';
220
- error.errno = -9;
221
- error.syscall = 'fstat';
222
- throw error;
223
- }
224
-
225
- if (options?.signal) {
226
- resourceTracker.registerAbortListener(options.signal, () => {});
227
- }
228
-
229
- // @ts-ignore - fstat exists but types may not match perfectly
230
- return fs.promises.fstat(fd, options);
231
- }, pathMapper, resourceTracker);
232
- };
233
- }
234
-
235
- export function createOpendirOperation(pathMapper: PathMapper, resourceTracker: ResourceTracker) {
236
- return async (virtualPath: string, options?: any): Promise<VirtualDir> => {
237
- return wrapOperation(async () => {
238
- const realPath = pathMapper.toRealPath(virtualPath);
239
-
240
- if (options?.signal) {
241
- resourceTracker.registerAbortListener(options.signal, () => {});
242
- }
243
-
244
- const realDir = await fs.promises.opendir(realPath, options);
245
- return new VirtualDir(realDir, virtualPath, pathMapper);
246
- }, pathMapper, resourceTracker);
247
- };
248
- }
249
-
250
- export function createExistsOperation(pathMapper: PathMapper, resourceTracker: ResourceTracker) {
251
- return async (virtualPath: string): Promise<boolean> => {
252
- resourceTracker.assertNotClosed();
253
- try {
254
- const realPath = pathMapper.toRealPath(virtualPath);
255
- await fs.promises.access(realPath);
256
- return true;
257
- } catch {
258
- return false;
259
- }
260
- };
261
- }
262
-
263
- export function createCreateReadStreamOperation(pathMapper: PathMapper, resourceTracker: ResourceTracker) {
264
- return (virtualPath: string, options?: any): fs.ReadStream => {
265
- resourceTracker.assertNotClosed();
266
-
267
- let realPath: string;
268
- try {
269
- realPath = pathMapper.toRealPath(virtualPath);
270
- } catch (error) {
271
- // Create a dummy stream that will emit an error
272
- const stream = new (require('stream').Readable)({
273
- read() {}
274
- }) as fs.ReadStream;
275
-
276
- process.nextTick(() => {
277
- stream.destroy(filterError(error as Error, pathMapper));
278
- });
279
-
280
- return stream;
281
- }
282
-
283
- const realStream = fs.createReadStream(realPath, options);
284
-
285
- // Track the stream
286
- resourceTracker.trackStream(realStream);
287
-
288
- // Untrack when closed
289
- realStream.on('close', () => {
290
- resourceTracker.untrackStream(realStream);
291
- });
292
-
293
- // Create a proxy to override the path property and filter errors
294
- const streamProxy = new Proxy(realStream, {
295
- get(target, prop) {
296
- if (prop === 'path') {
297
- return virtualPath;
298
- }
299
-
300
- if (prop === 'on' || prop === 'once') {
301
- return function(event: string, listener: any) {
302
- if (event === 'error') {
303
- // Wrap error listener to filter errors
304
- const wrappedListener = (error: Error) => {
305
- listener(filterError(error, pathMapper));
306
- };
307
- return target[prop as 'on'](event, wrappedListener);
308
- }
309
- return target[prop as 'on'](event, listener);
310
- };
311
- }
312
-
313
- return target[prop as keyof fs.ReadStream];
314
- }
315
- });
316
-
317
- return streamProxy;
318
- };
319
- }
@@ -1,31 +0,0 @@
1
- /**
2
- * All symlink operations return EACCES (access denied)
3
- * This module provides all symlink-related fs operations
4
- */
5
-
6
- function createEACCESError(syscall: string, path: string): NodeJS.ErrnoException {
7
- const error = new Error(`${syscall}: operation not permitted, ${syscall} '${path}'`) as NodeJS.ErrnoException;
8
- error.code = 'EACCES';
9
- error.errno = -13;
10
- error.syscall = syscall;
11
- error.path = path;
12
- return error;
13
- }
14
-
15
- export function createSymlinkOperation() {
16
- return async (target: string, path: string, type?: string): Promise<void> => {
17
- throw createEACCESError('symlink', path);
18
- };
19
- }
20
-
21
- export function createLinkOperation() {
22
- return async (existingPath: string, newPath: string): Promise<void> => {
23
- throw createEACCESError('link', newPath);
24
- };
25
- }
26
-
27
- export function createReadlinkOperation() {
28
- return async (path: string, options?: any): Promise<string | Buffer> => {
29
- throw createEACCESError('readlink', path);
30
- };
31
- }
@@ -1,189 +0,0 @@
1
- /**
2
- * All write operations return EACCES (access denied)
3
- * This module provides all write-related fs operations
4
- */
5
-
6
- function createEACCESError(syscall: string, path: string): NodeJS.ErrnoException {
7
- const error = new Error(`${syscall}: operation not permitted, ${syscall} '${path}'`) as NodeJS.ErrnoException;
8
- error.code = 'EACCES';
9
- error.errno = -13;
10
- error.syscall = syscall;
11
- error.path = path;
12
- return error;
13
- }
14
-
15
- export function createWriteFileOperation() {
16
- return async (path: string, data: any, options?: any): Promise<void> => {
17
- throw createEACCESError('open', path);
18
- };
19
- }
20
-
21
- export function createAppendFileOperation() {
22
- return async (path: string, data: any, options?: any): Promise<void> => {
23
- throw createEACCESError('open', path);
24
- };
25
- }
26
-
27
- export function createMkdirOperation() {
28
- return async (path: string, options?: any): Promise<void | string> => {
29
- throw createEACCESError('mkdir', path);
30
- };
31
- }
32
-
33
- export function createRmdirOperation() {
34
- return async (path: string, options?: any): Promise<void> => {
35
- throw createEACCESError('rmdir', path);
36
- };
37
- }
38
-
39
- export function createRmOperation() {
40
- return async (path: string, options?: any): Promise<void> => {
41
- throw createEACCESError('rm', path);
42
- };
43
- }
44
-
45
- export function createUnlinkOperation() {
46
- return async (path: string): Promise<void> => {
47
- throw createEACCESError('unlink', path);
48
- };
49
- }
50
-
51
- export function createRenameOperation() {
52
- return async (oldPath: string, newPath: string): Promise<void> => {
53
- throw createEACCESError('rename', oldPath);
54
- };
55
- }
56
-
57
- export function createCopyFileOperation() {
58
- return async (src: string, dest: string, mode?: number): Promise<void> => {
59
- throw createEACCESError('copyfile', dest);
60
- };
61
- }
62
-
63
- export function createTruncateOperation() {
64
- return async (path: string, len?: number): Promise<void> => {
65
- throw createEACCESError('open', path);
66
- };
67
- }
68
-
69
- export function createFtruncateOperation() {
70
- return async (fd: number, len?: number): Promise<void> => {
71
- const error = new Error('ftruncate: operation not permitted') as NodeJS.ErrnoException;
72
- error.code = 'EACCES';
73
- error.errno = -13;
74
- error.syscall = 'ftruncate';
75
- throw error;
76
- };
77
- }
78
-
79
- export function createChmodOperation() {
80
- return async (path: string, mode: string | number): Promise<void> => {
81
- throw createEACCESError('chmod', path);
82
- };
83
- }
84
-
85
- export function createFchmodOperation() {
86
- return async (fd: number, mode: string | number): Promise<void> => {
87
- const error = new Error('fchmod: operation not permitted') as NodeJS.ErrnoException;
88
- error.code = 'EACCES';
89
- error.errno = -13;
90
- error.syscall = 'fchmod';
91
- throw error;
92
- };
93
- }
94
-
95
- export function createLchmodOperation() {
96
- return async (path: string, mode: string | number): Promise<void> => {
97
- throw createEACCESError('lchmod', path);
98
- };
99
- }
100
-
101
- export function createChownOperation() {
102
- return async (path: string, uid: number, gid: number): Promise<void> => {
103
- throw createEACCESError('chown', path);
104
- };
105
- }
106
-
107
- export function createFchownOperation() {
108
- return async (fd: number, uid: number, gid: number): Promise<void> => {
109
- const error = new Error('fchown: operation not permitted') as NodeJS.ErrnoException;
110
- error.code = 'EACCES';
111
- error.errno = -13;
112
- error.syscall = 'fchown';
113
- throw error;
114
- };
115
- }
116
-
117
- export function createLchownOperation() {
118
- return async (path: string, uid: number, gid: number): Promise<void> => {
119
- throw createEACCESError('lchown', path);
120
- };
121
- }
122
-
123
- export function createUtimesOperation() {
124
- return async (path: string, atime: string | number | Date, mtime: string | number | Date): Promise<void> => {
125
- throw createEACCESError('utime', path);
126
- };
127
- }
128
-
129
- export function createFutimesOperation() {
130
- return async (fd: number, atime: string | number | Date, mtime: string | number | Date): Promise<void> => {
131
- const error = new Error('futime: operation not permitted') as NodeJS.ErrnoException;
132
- error.code = 'EACCES';
133
- error.errno = -13;
134
- error.syscall = 'futime';
135
- throw error;
136
- };
137
- }
138
-
139
- export function createLutimesOperation() {
140
- return async (path: string, atime: string | number | Date, mtime: string | number | Date): Promise<void> => {
141
- throw createEACCESError('lutime', path);
142
- };
143
- }
144
-
145
- export function createWriteOperation() {
146
- return async (fd: number, buffer: any, offset?: any, length?: any, position?: any): Promise<any> => {
147
- const error = new Error('write: operation not permitted') as NodeJS.ErrnoException;
148
- error.code = 'EACCES';
149
- error.errno = -13;
150
- error.syscall = 'write';
151
- throw error;
152
- };
153
- }
154
-
155
- export function createWritevOperation() {
156
- return async (fd: number, buffers: NodeJS.ArrayBufferView[], position?: number): Promise<any> => {
157
- const error = new Error('writev: operation not permitted') as NodeJS.ErrnoException;
158
- error.code = 'EACCES';
159
- error.errno = -13;
160
- error.syscall = 'writev';
161
- throw error;
162
- };
163
- }
164
-
165
- export function createCreateWriteStreamOperation() {
166
- return (path: string, options?: any): never => {
167
- throw createEACCESError('open', path);
168
- };
169
- }
170
-
171
- export function createFsyncOperation() {
172
- return async (fd: number): Promise<void> => {
173
- const error = new Error('fsync: operation not permitted') as NodeJS.ErrnoException;
174
- error.code = 'EACCES';
175
- error.errno = -13;
176
- error.syscall = 'fsync';
177
- throw error;
178
- };
179
- }
180
-
181
- export function createFdatasyncOperation() {
182
- return async (fd: number): Promise<void> => {
183
- const error = new Error('fdatasync: operation not permitted') as NodeJS.ErrnoException;
184
- error.code = 'EACCES';
185
- error.errno = -13;
186
- error.syscall = 'fdatasync';
187
- throw error;
188
- };
189
- }
@@ -1,57 +0,0 @@
1
- import type { PathMapper } from "../PathMapper";
2
-
3
- /**
4
- * Filter error messages to replace real paths with virtual paths
5
- */
6
- export function filterError(error: Error, pathMapper: PathMapper): Error {
7
- const realRoot = pathMapper.getRoot();
8
-
9
- // Create a regex to match the real root path
10
- // Escape special regex characters and handle both forward and back slashes
11
- const escapedRoot = realRoot.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
12
- const rootPattern = new RegExp(escapedRoot.replace(/\\/g, "\\\\"), "g");
13
-
14
- // Filter the error message
15
- if (error.message) {
16
- error.message = error.message.replace(rootPattern, "");
17
- }
18
-
19
- // Filter the stack trace
20
- if (error.stack) {
21
- error.stack = error.stack.replace(rootPattern, "");
22
- }
23
-
24
- // Filter the path property if it exists
25
- const errWithPath = error as NodeJS.ErrnoException;
26
- if (errWithPath.path && typeof errWithPath.path === "string") {
27
- try {
28
- // Try to convert real path to virtual path
29
- if (pathMapper.isWithinRoot(errWithPath.path)) {
30
- errWithPath.path = pathMapper.toVirtualPath(errWithPath.path);
31
- } else {
32
- // If outside root, just strip the root prefix
33
- errWithPath.path = errWithPath.path.replace(rootPattern, "");
34
- }
35
- } catch {
36
- // If conversion fails, just strip the root prefix
37
- errWithPath.path = errWithPath.path.replace(rootPattern, "");
38
- }
39
- }
40
-
41
- // Filter the dest property if it exists (for copy operations)
42
- if ("dest" in errWithPath && typeof errWithPath.dest === "string") {
43
- try {
44
- const destStr = errWithPath.dest as string;
45
- if (pathMapper.isWithinRoot(destStr)) {
46
- (errWithPath as any).dest = pathMapper.toVirtualPath(destStr);
47
- } else {
48
- (errWithPath as any).dest = destStr.replace(rootPattern, "");
49
- }
50
- } catch {
51
- const destStr = errWithPath.dest as string;
52
- (errWithPath as any).dest = destStr.replace(rootPattern, "");
53
- }
54
- }
55
-
56
- return error;
57
- }
@@ -1,54 +0,0 @@
1
- /**
2
- * Convert a promise-based function to a callback-based function
3
- */
4
- export function callbackify<T extends any[], R>(
5
- fn: (...args: T) => Promise<R>
6
- ): (...args: [...T, (err: Error | null, result?: R) => void]) => void {
7
- return function (this: any, ...args: any[]) {
8
- // Extract callback from arguments
9
- const callback = args[args.length - 1];
10
-
11
- if (typeof callback !== 'function') {
12
- throw new TypeError('The last argument must be a callback function');
13
- }
14
-
15
- // Get the actual arguments (without callback)
16
- const actualArgs = args.slice(0, -1) as T;
17
-
18
- // Call the promise function
19
- fn.apply(this, actualArgs)
20
- .then((result) => {
21
- // Call callback with no error
22
- callback(null, result);
23
- })
24
- .catch((err) => {
25
- // Call callback with error
26
- callback(err);
27
- });
28
- };
29
- }
30
-
31
- /**
32
- * Callbackify for void-returning promises
33
- */
34
- export function callbackifyVoid<T extends any[]>(
35
- fn: (...args: T) => Promise<void>
36
- ): (...args: [...T, (err: Error | null) => void]) => void {
37
- return function (this: any, ...args: any[]) {
38
- const callback = args[args.length - 1];
39
-
40
- if (typeof callback !== 'function') {
41
- throw new TypeError('The last argument must be a callback function');
42
- }
43
-
44
- const actualArgs = args.slice(0, -1) as T;
45
-
46
- fn.apply(this, actualArgs)
47
- .then(() => {
48
- callback(null);
49
- })
50
- .catch((err) => {
51
- callback(err);
52
- });
53
- };
54
- }