@zenfs/core 0.9.6 → 0.10.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 (82) hide show
  1. package/dist/backends/AsyncStore.d.ts +3 -2
  2. package/dist/backends/AsyncStore.js +40 -33
  3. package/dist/backends/Fetch.d.ts +84 -0
  4. package/dist/backends/Fetch.js +171 -0
  5. package/dist/backends/InMemory.d.ts +1 -1
  6. package/dist/backends/Index.d.ts +7 -10
  7. package/dist/backends/Index.js +26 -24
  8. package/dist/backends/Locked.d.ts +11 -11
  9. package/dist/backends/Locked.js +50 -49
  10. package/dist/backends/Overlay.js +22 -22
  11. package/dist/backends/SyncStore.d.ts +6 -6
  12. package/dist/backends/SyncStore.js +30 -30
  13. package/dist/backends/backend.d.ts +5 -4
  14. package/dist/backends/backend.js +6 -6
  15. package/dist/backends/port/fs.d.ts +124 -0
  16. package/dist/backends/port/fs.js +241 -0
  17. package/dist/backends/port/rpc.d.ts +60 -0
  18. package/dist/backends/port/rpc.js +71 -0
  19. package/dist/backends/port/store.d.ts +30 -0
  20. package/dist/backends/port/store.js +142 -0
  21. package/dist/browser.min.js +4 -4
  22. package/dist/browser.min.js.map +4 -4
  23. package/dist/config.d.ts +9 -11
  24. package/dist/config.js +13 -13
  25. package/dist/emulation/async.d.ts +76 -77
  26. package/dist/emulation/async.js +45 -45
  27. package/dist/emulation/dir.js +8 -7
  28. package/dist/emulation/index.d.ts +1 -1
  29. package/dist/emulation/index.js +1 -1
  30. package/dist/emulation/path.d.ts +3 -2
  31. package/dist/emulation/path.js +19 -45
  32. package/dist/emulation/promises.d.ts +112 -113
  33. package/dist/emulation/promises.js +167 -173
  34. package/dist/emulation/shared.d.ts +6 -17
  35. package/dist/emulation/shared.js +9 -9
  36. package/dist/emulation/streams.js +3 -2
  37. package/dist/emulation/sync.d.ts +71 -64
  38. package/dist/emulation/sync.js +62 -63
  39. package/dist/{ApiError.d.ts → error.d.ts} +15 -15
  40. package/dist/error.js +292 -0
  41. package/dist/file.d.ts +6 -4
  42. package/dist/file.js +17 -9
  43. package/dist/filesystem.d.ts +1 -1
  44. package/dist/filesystem.js +18 -15
  45. package/dist/index.d.ts +4 -1
  46. package/dist/index.js +4 -1
  47. package/dist/mutex.js +4 -3
  48. package/dist/stats.d.ts +7 -7
  49. package/dist/stats.js +50 -10
  50. package/dist/utils.d.ts +10 -9
  51. package/dist/utils.js +15 -15
  52. package/package.json +5 -5
  53. package/readme.md +19 -11
  54. package/src/backends/AsyncStore.ts +42 -36
  55. package/src/backends/Fetch.ts +230 -0
  56. package/src/backends/Index.ts +33 -29
  57. package/src/backends/Locked.ts +50 -49
  58. package/src/backends/Overlay.ts +24 -24
  59. package/src/backends/SyncStore.ts +34 -34
  60. package/src/backends/backend.ts +13 -11
  61. package/src/backends/port/fs.ts +308 -0
  62. package/src/backends/port/readme.md +59 -0
  63. package/src/backends/port/rpc.ts +144 -0
  64. package/src/backends/port/store.ts +187 -0
  65. package/src/config.ts +25 -29
  66. package/src/emulation/async.ts +191 -199
  67. package/src/emulation/dir.ts +8 -8
  68. package/src/emulation/index.ts +1 -1
  69. package/src/emulation/path.ts +25 -49
  70. package/src/emulation/promises.ts +286 -287
  71. package/src/emulation/shared.ts +14 -23
  72. package/src/emulation/streams.ts +9 -8
  73. package/src/emulation/sync.ts +182 -182
  74. package/src/{ApiError.ts → error.ts} +91 -89
  75. package/src/file.ts +23 -13
  76. package/src/filesystem.ts +26 -22
  77. package/src/index.ts +4 -1
  78. package/src/mutex.ts +6 -4
  79. package/src/stats.ts +32 -23
  80. package/src/utils.ts +23 -24
  81. package/tsconfig.json +4 -3
  82. package/dist/ApiError.js +0 -292
@@ -1,4 +1,4 @@
1
- import { ApiError, ErrorCode } from '../ApiError.js';
1
+ import { ErrnoError, Errno } from '../error.js';
2
2
  import { BigIntStats } from '../stats.js';
3
3
  import { nop, normalizeMode } from '../utils.js';
4
4
  import { R_OK } from './constants.js';
@@ -37,7 +37,7 @@ export function stat(path, options, callback = nop) {
37
37
  callback = typeof options == 'function' ? options : callback;
38
38
  promises
39
39
  .stat(path, typeof options != 'function' ? options : {})
40
- .then((stats) => callback(null, stats))
40
+ .then(stats => callback(undefined, stats))
41
41
  .catch(callback);
42
42
  }
43
43
  stat;
@@ -45,7 +45,7 @@ export function lstat(path, options, callback = nop) {
45
45
  callback = typeof options == 'function' ? options : callback;
46
46
  promises
47
47
  .lstat(path, typeof options != 'function' ? options : {})
48
- .then(stats => callback(null, stats))
48
+ .then(stats => callback(undefined, stats))
49
49
  .catch(callback);
50
50
  }
51
51
  lstat;
@@ -75,7 +75,7 @@ export function open(path, flag, cbMode, cb = nop) {
75
75
  cb = typeof cbMode === 'function' ? cbMode : cb;
76
76
  promises
77
77
  .open(path, flag, mode)
78
- .then(handle => cb(null, handle.fd))
78
+ .then(handle => cb(undefined, handle.fd))
79
79
  .catch(cb);
80
80
  }
81
81
  open;
@@ -83,7 +83,7 @@ export function readFile(filename, options, cb = nop) {
83
83
  cb = typeof options === 'function' ? options : cb;
84
84
  promises
85
85
  .readFile(filename, typeof options === 'function' ? null : options)
86
- .then(data => cb(null, data))
86
+ .then(data => cb(undefined, data))
87
87
  .catch(cb);
88
88
  }
89
89
  readFile;
@@ -91,7 +91,7 @@ export function writeFile(filename, data, cbEncOpts, cb = nop) {
91
91
  cb = typeof cbEncOpts === 'function' ? cbEncOpts : cb;
92
92
  promises
93
93
  .writeFile(filename, data, typeof cbEncOpts != 'function' ? cbEncOpts : null)
94
- .then(() => cb(null))
94
+ .then(() => cb(undefined))
95
95
  .catch(cb);
96
96
  }
97
97
  writeFile;
@@ -107,7 +107,7 @@ export function fstat(fd, options, cb = nop) {
107
107
  cb = typeof options == 'function' ? options : cb;
108
108
  fd2file(fd)
109
109
  .stat()
110
- .then(stats => cb(null, typeof options == 'object' && options?.bigint ? new BigIntStats(stats) : stats))
110
+ .then(stats => cb(undefined, typeof options == 'object' && options?.bigint ? new BigIntStats(stats) : stats))
111
111
  .catch(cb);
112
112
  }
113
113
  fstat;
@@ -128,7 +128,7 @@ export function ftruncate(fd, lenOrCB, cb = nop) {
128
128
  cb = typeof lenOrCB === 'function' ? lenOrCB : cb;
129
129
  const file = fd2file(fd);
130
130
  if (length < 0) {
131
- throw new ApiError(ErrorCode.EINVAL);
131
+ throw new ErrnoError(Errno.EINVAL);
132
132
  }
133
133
  file.truncate(length)
134
134
  .then(() => cb())
@@ -160,7 +160,7 @@ export function fdatasync(fd, cb = nop) {
160
160
  }
161
161
  fdatasync;
162
162
  export function write(fd, data, cbPosOff, cbLenEnc, cbPos, cb = nop) {
163
- let buffer, offset, length, position = null, encoding;
163
+ let buffer, offset, length, position, encoding;
164
164
  const handle = new promises.FileHandle(fd);
165
165
  if (typeof data === 'string') {
166
166
  // Signature 1: (fd, string, [position?, [encoding?]], cb?)
@@ -179,7 +179,7 @@ export function write(fd, data, cbPosOff, cbLenEnc, cbPos, cb = nop) {
179
179
  default:
180
180
  // ...try to find the callback and get out of here!
181
181
  cb = typeof cbLenEnc === 'function' ? cbLenEnc : typeof cbPos === 'function' ? cbPos : cb;
182
- cb(new ApiError(ErrorCode.EINVAL, 'Invalid arguments.'));
182
+ cb(new ErrnoError(Errno.EINVAL, 'Invalid arguments.'));
183
183
  return;
184
184
  }
185
185
  buffer = Buffer.from(data);
@@ -188,19 +188,19 @@ export function write(fd, data, cbPosOff, cbLenEnc, cbPos, cb = nop) {
188
188
  const _cb = cb;
189
189
  handle
190
190
  .write(buffer, offset, length, position)
191
- .then(({ bytesWritten }) => _cb(null, bytesWritten, buffer.toString(encoding)))
191
+ .then(({ bytesWritten }) => _cb(undefined, bytesWritten, buffer.toString(encoding)))
192
192
  .catch(_cb);
193
193
  }
194
194
  else {
195
195
  // Signature 2: (fd, buffer, offset, length, position?, cb?)
196
- buffer = Buffer.from(data);
196
+ buffer = Buffer.from(data.buffer);
197
197
  offset = cbPosOff;
198
198
  length = cbLenEnc;
199
199
  position = typeof cbPos === 'number' ? cbPos : null;
200
200
  const _cb = (typeof cbPos === 'function' ? cbPos : cb);
201
201
  handle
202
202
  .write(buffer, offset, length, position)
203
- .then(({ bytesWritten }) => _cb(null, bytesWritten, buffer))
203
+ .then(({ bytesWritten }) => _cb(undefined, bytesWritten, buffer))
204
204
  .catch(_cb);
205
205
  }
206
206
  }
@@ -220,7 +220,7 @@ write;
220
220
  export function read(fd, buffer, offset, length, position, cb = nop) {
221
221
  new promises.FileHandle(fd)
222
222
  .read(buffer, offset, length, position)
223
- .then(({ bytesRead, buffer }) => cb(null, bytesRead, buffer))
223
+ .then(({ bytesRead, buffer }) => cb(undefined, bytesRead, buffer))
224
224
  .catch(cb);
225
225
  }
226
226
  read;
@@ -297,7 +297,7 @@ export function readdir(path, _options, cb = nop) {
297
297
  promises
298
298
  .readdir(path, options)
299
299
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
300
- .then(entries => cb(null, entries))
300
+ .then(entries => cb(undefined, entries))
301
301
  .catch(cb);
302
302
  }
303
303
  readdir;
@@ -327,7 +327,7 @@ export function readlink(path, options, callback = nop) {
327
327
  callback = typeof options == 'function' ? options : callback;
328
328
  promises
329
329
  .readlink(path)
330
- .then(result => callback(null, result))
330
+ .then(result => callback(undefined, result))
331
331
  .catch(callback);
332
332
  }
333
333
  readlink;
@@ -417,7 +417,7 @@ export function realpath(path, arg2, cb = nop) {
417
417
  cb = typeof arg2 === 'function' ? arg2 : cb;
418
418
  promises
419
419
  .realpath(path, typeof arg2 === 'function' ? null : arg2)
420
- .then(result => cb(null, result))
420
+ .then(result => cb(undefined, result))
421
421
  .catch(cb);
422
422
  }
423
423
  realpath;
@@ -430,19 +430,19 @@ export function access(path, cbMode, cb = nop) {
430
430
  .catch(cb);
431
431
  }
432
432
  access;
433
- export function watchFile(filename, optsListener, listener = nop) {
434
- throw ApiError.With('ENOSYS', filename, 'watchFile');
433
+ export function watchFile(path, optsListener, listener = nop) {
434
+ throw ErrnoError.With('ENOSYS', path.toString(), 'watchFile');
435
435
  }
436
436
  watchFile;
437
437
  /**
438
438
  * @todo Implement
439
439
  */
440
- export function unwatchFile(filename, listener = nop) {
441
- throw ApiError.With('ENOSYS', filename, 'unwatchFile');
440
+ export function unwatchFile(path, listener = nop) {
441
+ throw ErrnoError.With('ENOSYS', path.toString(), 'unwatchFile');
442
442
  }
443
443
  unwatchFile;
444
- export function watch(filename, options, listener = nop) {
445
- throw ApiError.With('ENOSYS', filename, 'watch');
444
+ export function watch(path, options, listener = nop) {
445
+ throw ErrnoError.With('ENOSYS', path.toString(), 'watch');
446
446
  }
447
447
  watch;
448
448
  /**
@@ -480,7 +480,7 @@ export function createReadStream(path, _options) {
480
480
  .catch(callback);
481
481
  },
482
482
  });
483
- stream.path = path;
483
+ stream.path = path.toString();
484
484
  return stream;
485
485
  }
486
486
  createReadStream;
@@ -499,8 +499,8 @@ export function createWriteStream(path, _options) {
499
499
  async write(chunk, encoding, callback) {
500
500
  try {
501
501
  handle || (handle = await promises.open(path, 'w', options?.mode || 0o666));
502
- await handle.write(chunk, null, encoding);
503
- callback(null);
502
+ await handle.write(chunk, 0, encoding);
503
+ callback(undefined);
504
504
  }
505
505
  catch (error) {
506
506
  await handle?.close();
@@ -521,15 +521,15 @@ export function createWriteStream(path, _options) {
521
521
  .catch(callback);
522
522
  },
523
523
  });
524
- stream.path = path;
524
+ stream.path = path.toString();
525
525
  return stream;
526
526
  }
527
527
  createWriteStream;
528
528
  export function rm(path, options, callback = nop) {
529
529
  callback = typeof options === 'function' ? options : callback;
530
530
  promises
531
- .rm(path, typeof options === 'function' ? null : options)
532
- .then(() => callback(null))
531
+ .rm(path, typeof options === 'function' ? undefined : options)
532
+ .then(() => callback(undefined))
533
533
  .catch(callback);
534
534
  }
535
535
  rm;
@@ -537,60 +537,60 @@ export function mkdtemp(prefix, options, callback = nop) {
537
537
  callback = typeof options === 'function' ? options : callback;
538
538
  promises
539
539
  .mkdtemp(prefix, typeof options != 'function' ? options : null)
540
- .then(result => callback(null, result))
540
+ .then(result => callback(undefined, result))
541
541
  .catch(callback);
542
542
  }
543
543
  mkdtemp;
544
- export function copyFile(src, dest, flags, callback) {
544
+ export function copyFile(src, dest, flags, callback = nop) {
545
545
  callback = typeof flags === 'function' ? flags : callback;
546
546
  promises
547
- .copyFile(src, dest, typeof flags === 'function' ? null : flags)
548
- .then(() => callback(null))
547
+ .copyFile(src, dest, typeof flags === 'function' ? undefined : flags)
548
+ .then(() => callback(undefined))
549
549
  .catch(callback);
550
550
  }
551
551
  copyFile;
552
552
  export function readv(fd, buffers, position, cb = nop) {
553
553
  cb = typeof position === 'function' ? position : cb;
554
554
  new promises.FileHandle(fd)
555
- .readv(buffers, typeof position === 'function' ? null : position)
556
- .then(({ buffers, bytesRead }) => cb(null, bytesRead, buffers))
555
+ .readv(buffers, typeof position === 'function' ? undefined : position)
556
+ .then(({ buffers, bytesRead }) => cb(undefined, bytesRead, buffers))
557
557
  .catch(cb);
558
558
  }
559
559
  readv;
560
560
  export function writev(fd, buffers, position, cb = nop) {
561
561
  cb = typeof position === 'function' ? position : cb;
562
562
  new promises.FileHandle(fd)
563
- .writev(buffers, typeof position === 'function' ? null : position)
564
- .then(({ buffers, bytesWritten }) => cb(null, bytesWritten, buffers))
563
+ .writev(buffers, typeof position === 'function' ? undefined : position)
564
+ .then(({ buffers, bytesWritten }) => cb(undefined, bytesWritten, buffers))
565
565
  .catch(cb);
566
566
  }
567
567
  writev;
568
568
  export function opendir(path, options, cb = nop) {
569
569
  cb = typeof options === 'function' ? options : cb;
570
570
  promises
571
- .opendir(path, typeof options === 'function' ? null : options)
572
- .then(result => cb(null, result))
571
+ .opendir(path, typeof options === 'function' ? undefined : options)
572
+ .then(result => cb(undefined, result))
573
573
  .catch(cb);
574
574
  }
575
575
  opendir;
576
- export function cp(source, destination, opts, callback) {
576
+ export function cp(source, destination, opts, callback = nop) {
577
577
  callback = typeof opts === 'function' ? opts : callback;
578
578
  promises
579
- .cp(source, destination, typeof opts === 'function' ? null : opts)
580
- .then(() => callback(null))
579
+ .cp(source, destination, typeof opts === 'function' ? undefined : opts)
580
+ .then(() => callback(undefined))
581
581
  .catch(callback);
582
582
  }
583
583
  cp;
584
584
  export function statfs(path, options, callback = nop) {
585
585
  callback = typeof options === 'function' ? options : callback;
586
586
  promises
587
- .statfs(path, typeof options === 'function' ? null : options)
588
- .then(result => callback(null, result))
587
+ .statfs(path, typeof options === 'function' ? undefined : options)
588
+ .then(result => callback(undefined, result))
589
589
  .catch(callback);
590
590
  }
591
591
  statfs;
592
592
  export async function openAsBlob(path, options) {
593
- const handle = await promises.open(path, 'r');
593
+ const handle = await promises.open(path.toString(), 'r');
594
594
  const buffer = await handle.readFile();
595
595
  await handle.close();
596
596
  return new Blob([buffer], options);
@@ -1,5 +1,5 @@
1
1
  import { readdir } from './promises.js';
2
- import { ApiError, ErrorCode } from '../ApiError.js';
2
+ import { ErrnoError, Errno } from '../error.js';
3
3
  import { readdirSync } from './sync.js';
4
4
  import { basename } from './path.js';
5
5
  export class Dirent {
@@ -38,12 +38,13 @@ export class Dirent {
38
38
  export class Dir {
39
39
  checkClosed() {
40
40
  if (this.closed) {
41
- throw new ApiError(ErrorCode.EBADF, 'Can not use closed Dir');
41
+ throw new ErrnoError(Errno.EBADF, 'Can not use closed Dir');
42
42
  }
43
43
  }
44
44
  constructor(path) {
45
45
  this.path = path;
46
46
  this.closed = false;
47
+ this._entries = [];
47
48
  }
48
49
  close(cb) {
49
50
  this.closed = true;
@@ -63,16 +64,16 @@ export class Dir {
63
64
  if (!this._entries) {
64
65
  this._entries = await readdir(this.path, { withFileTypes: true });
65
66
  }
66
- if (this._entries.length == 0) {
67
+ if (!this._entries.length) {
67
68
  return null;
68
69
  }
69
- return this._entries.shift();
70
+ return this._entries.shift() || null;
70
71
  }
71
72
  read(cb) {
72
73
  if (!cb) {
73
74
  return this._read();
74
75
  }
75
- this._read().then(value => cb(null, value));
76
+ this._read().then(value => cb(undefined, value));
76
77
  }
77
78
  /**
78
79
  * Synchronously read the next directory entry via `readdir(3)` as a `Dirent`.
@@ -83,10 +84,10 @@ export class Dir {
83
84
  if (!this._entries) {
84
85
  this._entries = readdirSync(this.path, { withFileTypes: true });
85
86
  }
86
- if (this._entries.length == 0) {
87
+ if (!this._entries.length) {
87
88
  return null;
88
89
  }
89
- return this._entries.shift();
90
+ return this._entries.shift() || null;
90
91
  }
91
92
  /**
92
93
  * Asynchronously iterates over the directory via `readdir(3)` until all entries have been read.
@@ -4,5 +4,5 @@ export * as promises from './promises.js';
4
4
  export * as constants from './constants.js';
5
5
  export * from './streams.js';
6
6
  export * from './dir.js';
7
- export { mountMapping, mounts, mount, umount } from './shared.js';
7
+ export { mountObject, mounts, mount, umount } from './shared.js';
8
8
  export { Stats, BigIntStats, StatsFs } from '../stats.js';
@@ -4,5 +4,5 @@ export * as promises from './promises.js';
4
4
  export * as constants from './constants.js';
5
5
  export * from './streams.js';
6
6
  export * from './dir.js';
7
- export { mountMapping, mounts, mount, umount } from './shared.js';
7
+ export { mountObject, mounts, mount, umount } from './shared.js';
8
8
  export { Stats, BigIntStats, StatsFs } from '../stats.js';
@@ -1,14 +1,15 @@
1
1
  /// <reference types="node" resolution-mode="require"/>
2
2
  import type { ParsedPath } from 'node:path';
3
+ export type AbsolutePath = `/${string}`;
3
4
  export declare let cwd: string;
4
5
  export declare function cd(path: string): void;
5
6
  export declare const sep = "/";
6
7
  export declare function normalizeString(path: string, allowAboveRoot: boolean): string;
7
8
  export declare function formatExt(ext: string): string;
8
- export declare function resolve(...args: string[]): string;
9
+ export declare function resolve(...parts: string[]): AbsolutePath;
9
10
  export declare function normalize(path: string): string;
10
11
  export declare function isAbsolute(path: string): boolean;
11
- export declare function join(...args: string[]): string;
12
+ export declare function join(...parts: string[]): string;
12
13
  export declare function relative(from: string, to: string): string;
13
14
  export declare function dirname(path: string): string;
14
15
  export declare function basename(path: string, suffix?: string): string;
@@ -25,11 +25,6 @@ export function cd(path) {
25
25
  cwd = resolve(cwd, path);
26
26
  }
27
27
  export const sep = '/';
28
- function validateString(str, name) {
29
- if (typeof str != 'string') {
30
- throw new TypeError(`"${name}" is not a string`);
31
- }
32
- }
33
28
  function validateObject(str, name) {
34
29
  if (typeof str != 'object') {
35
30
  throw new TypeError(`"${name}" is not an object`);
@@ -107,19 +102,18 @@ export function normalizeString(path, allowAboveRoot) {
107
102
  export function formatExt(ext) {
108
103
  return ext ? `${ext[0] === '.' ? '' : '.'}${ext}` : '';
109
104
  }
110
- export function resolve(...args) {
105
+ export function resolve(...parts) {
111
106
  let resolved = '';
112
- let absolute = false;
113
- for (let i = args.length - 1; i >= -1 && !absolute; i--) {
114
- const path = i >= 0 ? args[i] : cwd;
115
- validateString(path, `paths[${i}]`);
116
- // Skip empty entries
117
- if (!path.length) {
107
+ for (const part of [...parts.reverse(), cwd]) {
108
+ if (!part.length) {
118
109
  continue;
119
110
  }
120
- resolved = `${path}/${resolved}`;
121
- absolute = path[0] == '/';
111
+ resolved = `${part}/${resolved}`;
112
+ if (part.startsWith('/')) {
113
+ break;
114
+ }
122
115
  }
116
+ const absolute = resolved.startsWith('/');
123
117
  // At this point the path should be resolved to a full absolute path, but
124
118
  // handle relative paths to be safe (might happen when cwd fails)
125
119
  // Normalize the path
@@ -127,17 +121,16 @@ export function resolve(...args) {
127
121
  if (absolute) {
128
122
  return `/${resolved}`;
129
123
  }
130
- return resolved.length > 0 ? resolved : '/';
124
+ return resolved.length ? resolved : '/';
131
125
  }
132
126
  export function normalize(path) {
133
- validateString(path, 'path');
134
- if (path.length === 0)
127
+ if (!path.length)
135
128
  return '.';
136
- const isAbsolute = path[0] === '/';
137
- const trailingSeparator = path.at(-1) === '/';
129
+ const isAbsolute = path.startsWith('/');
130
+ const trailingSeparator = path.endsWith('/');
138
131
  // Normalize the path
139
132
  path = normalizeString(path, !isAbsolute);
140
- if (path.length === 0) {
133
+ if (!path.length) {
141
134
  if (isAbsolute)
142
135
  return '/';
143
136
  return trailingSeparator ? './' : '.';
@@ -147,30 +140,17 @@ export function normalize(path) {
147
140
  return isAbsolute ? `/${path}` : path;
148
141
  }
149
142
  export function isAbsolute(path) {
150
- validateString(path, 'path');
151
- return path.length > 0 && path[0] === '/';
143
+ return path.startsWith('/');
152
144
  }
153
- export function join(...args) {
154
- if (args.length === 0)
145
+ export function join(...parts) {
146
+ if (!parts.length)
155
147
  return '.';
156
- let joined;
157
- for (let i = 0; i < args.length; ++i) {
158
- const arg = args[i];
159
- validateString(arg, 'path');
160
- if (arg.length > 0) {
161
- if (joined === undefined)
162
- joined = arg;
163
- else
164
- joined += `/${arg}`;
165
- }
166
- }
167
- if (joined === undefined)
148
+ const joined = parts.join('/');
149
+ if (!joined?.length)
168
150
  return '.';
169
151
  return normalize(joined);
170
152
  }
171
153
  export function relative(from, to) {
172
- validateString(from, 'from');
173
- validateString(to, 'to');
174
154
  if (from === to)
175
155
  return '';
176
156
  // Trim leading forward slashes.
@@ -233,7 +213,6 @@ export function relative(from, to) {
233
213
  return `${out}${to.slice(toStart + lastCommonSep)}`;
234
214
  }
235
215
  export function dirname(path) {
236
- validateString(path, 'path');
237
216
  if (path.length === 0)
238
217
  return '.';
239
218
  const hasRoot = path[0] === '/';
@@ -258,9 +237,6 @@ export function dirname(path) {
258
237
  return path.slice(0, end);
259
238
  }
260
239
  export function basename(path, suffix) {
261
- if (suffix !== undefined)
262
- validateString(suffix, 'ext');
263
- validateString(path, 'path');
264
240
  let start = 0;
265
241
  let end = -1;
266
242
  let matchedSlash = true;
@@ -330,7 +306,6 @@ export function basename(path, suffix) {
330
306
  return path.slice(start, end);
331
307
  }
332
308
  export function extname(path) {
333
- validateString(path, 'path');
334
309
  let startDot = -1;
335
310
  let startPart = 0;
336
311
  let end = -1;
@@ -387,8 +362,7 @@ export function format(pathObject) {
387
362
  return dir === pathObject.root ? `${dir}${base}` : `${dir}/${base}`;
388
363
  }
389
364
  export function parse(path) {
390
- validateString(path, 'path');
391
- const isAbsolute = path[0] === '/';
365
+ const isAbsolute = path.startsWith('/');
392
366
  const ret = { root: isAbsolute ? '/' : '', dir: '', base: '', ext: '', name: '' };
393
367
  if (path.length === 0)
394
368
  return ret;