@thingts/fs-path - v1.2.2
    Preparing search index...

    Class FsPath

    Represents an absolute filesystem path (i.e. a path starting at the root with a leading separator), and provides methods for path resolution, manipulation and queries as well as (async) filesystem operations.

    FsPath instances are normalized and immutable.

    FsPath extends AbsolutePath of @thingts/path, but with added methods for filesystem access.

    Having an FsPath does not imply that a file or directory exists at that path in the filesystem; use exists, isFile, isDirectory or stat to check for existence, and use write, touch, makeDirectory, or makeTempDirectory to create files or directories.

    Methods that create or modify files or directories return a Promise<this>, allowing for chaining.

    ⚠️ In the documentation below that is inherited from AbsolutePath, examples that refer to AbsolutePath apply equally to FsPath -- in particular, the path manipulation methods like join return FsPath instances, not AbsolutePath instances.

    const p = new FsPath('/path/to/file.txt')
    await p.write('Hello, world!', { makeParents: true })
    const content = await p.read() // Reads the file content

    // With chaining
    const p2 = await new FsPath('/path/to/another.txt').write('data')

    // Multiple chaining is possible, though less ergonomic
    const p3 = await new FsPath('/path/to/yet-another.txt').write('data').then(p => p.setPermissions({ mode: 0o644 }))

    const p4 = await (await new FsPath('/path/to/yet-another.txt').write('data')).setPermissions({ mode: 0o644 })

    Hierarchy

    Index

    Constructors

    Accessors

    • get extension(): string

      Returns the extension of the filename including the leading dot, as a string. If the filename has no extension, returns an empty string.

      Note that if the filename starts with a dot (e.g. .gitignore), that dot is considered part of the stem. So .gitignore has extension '' and .gitignore.bak has extension .bak

      Returns string

    • get filename(): Filename

      The filename component (last path segment) as a Filename.

      Returns Filename

      new AbsolutePath('/a/b/c.txt').filename // 'c.txt' (Filename)
      new RelativePath('a/b/c.txt').filename // 'c.txt' (Filename)
    • get parent(): this

      The parent directory of this path.

      Returns this

      A new path instance pointing to the parent.

      new AbsolutePath('/a/b/c.txt').parent // '/a/b' (AbsolutePath)
      new RelativePath('a/b/c.txt').parent // 'a/b' (RelativePath)
    • get stem(): string

      Returns the stem of the filename, i.e. the part before the extension. If the filename has no extension, returns the entire filename

      Note that if the filename starts with a dot (e.g. .gitignore), that dot is considered part of the stem. So .gitignore and .gitignore.bak both have stem .gitignore

      Returns string

    Methods

    • Copies this file to a new location.

      Parameters

      • to: AbsolutePath

        The target path to copy to.

      • Optionalopts: { intoDir?: boolean; makeParents?: boolean }
        • OptionalintoDir?: boolean

          If true, treat to as a directory and copy the file into it. (Default: false)

        • OptionalmakeParents?: boolean

          If true, create parent directories of the target path as needed. (Default: false)

      Returns Promise<FsPath>

      A Promise resolving to a new FsPath for the path of the copy (either to or to.join(this.filename) based on opts.intoDir)

      const p1 = new FsPath('/path/to/file.txt')
      const p2 = new FsPath('/new/path/to/file.txt')
      await p1.copyTo(p2, { makeParents: true }) // Copies the file, creating parent directories as needed

      const dir = new FsPath('/new/path/')
      const p3 = await p1.copyTo(dir, { intoDir: true, makeParents: true }) // Copies the file into the directory
      console.log(p3.toString()) // /new/path/file.txt
    • Test whether this path is a descendant of the given ancestor path.

      Parameters

      • ancestor: string | AbsolutePath

        An AbsolutePath or string to check against.

      • Optionalopts: { includeSelf?: boolean }
        • OptionalincludeSelf?: boolean

          If true, return true when the paths are identical.

      Returns boolean

      True if this path descends from the ancestor, otherwise false.

      const p1 = new AbsolutePath('/project/demo')
      const p2 = new AbsolutePath('/project/demo/src/index.ts')
      console.log(p2.descendsFrom(p1)) // true
      console.log(p1.descendsFrom(p1)) // false
      console.log(p1.descendsFrom(p1, { includeSelf: true })) // true
    • Create an FsPath instance marked as as disposable, meaning the file or directory will be automatically deleted when no longer needed.

      Disposable paths will be disposed (i.e. the file or directory will be deleted) in one of three circumstances, whichever comes first:

      • Via the using declaration -- the path is disposed as soon as the declared variable goes out of scope. This is the most immediate and reliable.

      • Disposal when the FsPath object is garbage collected. As always, there's no knowing when or if this will happen.

      • Disposal on process exit.

      ⚠️ Disposal is best-effort; it may fail due to permissions or be skipped if the process exits abnormally. Failures during disposal are silently ignored.

      Returns this

      A new instance of this path, marked as disposable.

      {
      using p = new FsPath('/path/to/tempfile.txt').disposable()
      await p.write('data') // Creates the file
      ...
      } // The file is automatically removed when p goes out of scope

      const p2 = new FsPath('/path/to/tempfile2.txt').disposable()
      await p2.write('data')
      // The file will be removed eventually, on gc or process exit
    • Returns true if this path equals the other path or string

      Parameters

      • other: string | PathBase

      Returns boolean

    • Finds files and directories matching a glob pattern within this directory.

      Uses fast-glob under the hood.

      Parameters

      • pattern: string | Filename

        The glob pattern to match

      • Optionalopts: FsReadDirectoryOptions

        Options for reading directories, used by FsPath.readDirectory and FsPath.glob

        • OptionalallowMissing?: boolean

          If true, return an empty array if the directory does not exist, rather than throwing an error. (Default: false)

        • OptionalincludeDotfiles?: boolean

          If true, include dotfiles in the result. (Default: true)

        • OptionalonlyDirs?: boolean

          If true, only include directories in the result. (Default: false)

        • OptionalonlyFiles?: boolean

          If true, only include files in the result. (Default: false)

      Returns Promise<FsPath[]>

      An array of FsPath objects representing the matching entries.

      const dir = new FsPath('/path/to/dir')
      const paths = await dir.glob('**/*.js')
      for (const path of paths) {
      console.log(path.filename.toString())
      }
    • Join additional path segments to this path.

      Accepts strings or path objects; null and undefined are ignored. The resulting path is normalized.

      Parameters

      • ...segments: readonly (undefined | null | string | FilenameBase)[]

      Returns this

      A new path instance with the segments appended

      const a1 = new AbsolutePath('/project/demo')
      const a2 = a1.join('demo1/src', 'index.js') // '/project/demo/demo1/src/index.js'
      a2 instanceof AbsolutePath // true

      const r1 = new RelativePath('demo')
      const r2 = r1.join('demo1/src', 'index.js') // 'demo/demo1/src/index.js'
      r2 instanceof RelativePath // true
    • Create a directory at this path.

      Parameters

      • Optionalopts: { makeParents?: boolean }
        • OptionalmakeParents?: boolean

          If true, create parent directories as needed.

      Returns Promise<FsPath>

      A Promise resolving to this instance, for chaining.

      const p = new FsPath('/path/to/dir')
      await p.makeDirectory({ makeParents: true }) // Creates the directory and any needed parent directories
    • Move (rename) this file or directory to a new location.

      Parameters

      • to: AbsolutePath

        The target path to move to.

      • Optionalopts: { intoDir?: boolean; makeParents?: boolean }
        • OptionalintoDir?: boolean

          If true, treat to as a directory and move the file into it. (Default: false)

        • OptionalmakeParents?: boolean

          If true, create parent directories of the target path as needed. (Default: false)

      Returns Promise<FsPath>

      A Promise resolving to a new FsPath for the final path (either to or to.join(this.filename) based on opts.intoDir)

      const p1 = new FsPath('/path/to/file.txt')
      const p2 = new FsPath('/new/path/to/file.txt')
      await p1.moveTo(p2, { makeParents: true }) // Renames (moves) the file, creating parent directories as needed

      const dir = new FsPath('/new/path/')
      const p3 = await p2.moveTo(dir, { intoDir: true, makeParents: true }) // Moves the file into the directory
      console.log(p3.toString()) // /new/path/file.txt
    • Protected factory to construct a new instance of the current class, with the given path.

      Used by all mutation-like methods to return a new instance of the same class, allowing derived classes that inherit those methods to return new instances of themselves without needing to override them.

      The default implementation assumes the derived class's constructor takes a single string argument (the path). Derived classes with different constructor siguatures should override newSelf.

      Parameters

      • path: string | FilenameBase

      Returns this

    • Read the contents of the file as a string.

      Parameters

      • Optionalopts: { encoding: BufferEncoding }
        • encoding: BufferEncoding

          The file encoding. (Default: 'utf8')

      Returns Promise<string>

      The file contents as a string.

      const p = new FsPath('/path/to/file.txt')
      const content = await p.read()
    • Reads the contents of the directory.

      Parameters

      • Optionalopts: FsReadDirectoryOptions

        Options for reading directories, used by FsPath.readDirectory and FsPath.glob

        • OptionalallowMissing?: boolean

          If true, return an empty array if the directory does not exist, rather than throwing an error. (Default: false)

        • OptionalincludeDotfiles?: boolean

          If true, include dotfiles in the result. (Default: true)

        • OptionalonlyDirs?: boolean

          If true, only include directories in the result. (Default: false)

        • OptionalonlyFiles?: boolean

          If true, only include files in the result. (Default: false)

      Returns Promise<FsPath[]>

      An array of FsPath objects representing the entries in the directory.

      const dir = new FsPath('/path/to/dir')
      const paths = await dir.readDirectory()
      for (const path of paths) {
      console.log(path.filename.toString())
      }
    • Creates a readable stream for the file.

      Parameters

      • Optionalopts: { end?: number; start?: number }
        • Optionalend?: number

          The ending byte position (inclusive).

        • Optionalstart?: number

          The starting byte position (inclusive).

      Returns Promise<ReadStream>

      A readable stream for the file.

      const p = new FsPath('/path/to/file.txt')
      const stream = await p.readStream()
      stream.pipe(process.stdout) // Print file contents to stdout
    • Compute the relative path from the given base path to this path.

      Parameters

      Returns RelativePath

      A RelativePath that goes from base to this.

      const p1 = new AbsolutePath('/project/demo')
      const p2 = new AbsolutePath('/project/demo/src/index.ts')
      const rel = p2.relativeTo(p1) // 'src/index.ts' (RelativePath)
      p1.join(rel).equals(p2) // true
    • Removes the file or directory.

      Parameters

      • Optionalopts: { throwIfMissing?: boolean }
        • OptionalthrowIfMissing?: boolean

          If true, throw an error if the path does not exist. (Default: false)

      Returns Promise<FsPath>

      A Promise resolving to this instance, for chaining. (The path object remains valid even though the file or directory has been removed.)

      const p = new FsPath('/path/to/file.txt')
      await p.remove() // Removes the file if it exists, does nothing if it does not exist
      await p.remove({ throwIfMissing: true }) // Removes the file, throws an error if it does not exist
    • Replace the filename extension, keeping the stem the same. The passed can include or omit the leading dot; if omitted, it will be added.

      Parameters

      • newExt: string

        New extension, e.g. json or .json

      Returns this

      A new path with the extension replaced.

      new AbsolutePath('/a/b/c.txt').replaceExtension('json') // '/a/b/c.json' (AbsolutePath)
      new RelativePath('a/b/c.txt').replaceExtension('.json') // '/a/b/c.json' (RelativePath)
    • Replace the filename (last segment).

      Parameters

      Returns this

      A new path with the filename replaced.

    • Replace the parent directory while keeping the current filename.

      Parameters

      • newParent: string | PathBase

        Parent directory as string or another PathBase.

      Returns this

      A new path rooted at newParent with the same filename.

      new AbsolutePath('/old/file.txt').replaceParent('/new/dir') // '/new/dir/file.txt' (AbsolutePath)
      new RelativePath('old/file.txt').replaceParent('new/dir') // 'new/dir/file.txt' (RelativePath)
    • Replace the filename stem, keeping the extension the same

      Parameters

      • newStem: string

        New stem to use (extension is preserved).

      Returns this

      A new path with the stem replaced.

      new AbsolutePath('/a/b/c.txt').replaceStem('d') // '/a/b/d.txt' (AbsolutePath)
      new RelativePath('a/b/c.txt').replaceStem('d') // 'a/b/d.txt' (RelativePath)
    • Resolve additional path segments against this absolute path.

      Accepts strings, Filename, RelativePath, or AbsolutePath objects. Null and undefined segments are ignored.

      Similar to join, except that if any segment is an AbsolutePath or string starting with a path separator, the current path is discarded and resolution starts from that segment.

      Parameters

      Returns this

      A new AbsolutePath with the resolved path.

      const p1 = new AbsolutePath('/project/demos')
      const p2 = p1.resolve('demo1/src', 'index.ts') // '/project/demos/demo1/src/index.ts'
      const p3 = p1.resolve('/etc/config') // '/etc/config' (resets to absolute path)
    • Cancels disposal for this instance.

      If this instance was created via disposable(), so that file or directory would be automatically removed, calling retain() prevents that removal.

      Returns this

      A new instance of this path, unmarked as disposable.

      ⚠️ The old instance remains valid and can still be used normally. Technically the old instance continues to to be marked as disposable, but its disposal will now be a no-op.

      {
      using p = new FsPath('/path/to/tempfile.txt').disposable()
      await p.write('data') // Creates the file
      ...
      p.retain() // The file will *not* be removed when p goes out of scope
      }

      const p2 = new FsPath('/path/to/tempfile2.txt').disposable()
      await p2.write('data')
      p2.retain() // the file will *not* be automatically removed
    • Sets the permission mode of the path.

      Parameters

      • spec: FsPermissionSpec

        The permission specification. Can be the numeric mode, or an object specifying user/group/others permissions.

      • Optionalopts: { operation: "clear" | "overlay" | "assign" }
        • operation: "clear" | "overlay" | "assign"

          The operation to perform: assign the permissions exactly (default), overlay the permissions on top of the existing ones, or clear the specified permissions from the existing ones.

      Returns Promise<FsPath>

      A Promise resolving to this instance, for chaining.

      const p = new FsPath('/path/to/file')

      // Set to rw-r--r--
      await p.setPermissions({ mode: 0o644 })

      // Add write permission for all => rw-rw-rw-
      await p.setPermissions({ all: { read: true, write: true } }, { operation: 'overlay' })

      // Remove write permission for others => rw-rw-r--
      await p.setPermissions({ others: { write: true } }, { operation: 'clear' })
    • Returns the path as string.

      Returns string

    • Updates the file's access and modification times, or create an empty file if it does not exist.

      Parameters

      • Optionalopts: { makeParents?: boolean }
        • OptionalmakeParents?: boolean

          If true, create parent directories as needed. (Default: false)

      Returns Promise<FsPath>

      A Promise resolving to this instance, for chaining.

      const p = await new FsPath('/path/to/file.txt')
      await p.touch({ makeParents: true }) // Creates the file if it does not exist, creating parent directories as needed
    • Transform the filename via a callback.

      Parameters

      Returns this

      A new path with the transformed filename.

      p.transformFilename(f => f.replaceStem(f.stem + '.bak'))
      
    • Writes content to the file, replacing or appending to the existing content.

      Parameters

      • content: string | Uint8Array<ArrayBufferLike>

        The content to write (string or Uint8Array).

      • Optionalopts: { append?: boolean; encoding?: BufferEncoding; makeParents?: boolean }
        • Optionalappend?: boolean

          If true, append to the file instead of replacing it. (Default: false)

        • Optionalencoding?: BufferEncoding

          The file encoding. (Default: 'utf8' if content is string)

        • OptionalmakeParents?: boolean

          If true, create parent directories as needed. (Default: false)

      Returns Promise<FsPath>

      A Promise resolving to this instance, for chaining.

      const p = new FsPath('/path/to/file.txt')
      await p.write('Hello', { makeParents: true }) // Creates the file with content, creating parent directories as needed
      await p.write(', world!', { append: true }) // Appends to the file
    • Checks whether a string is an absolute path. (I.e., if it would be acceptable to the AbsolutePath constructor.)

      Parameters

      • filepath: string

        The string to check.

      Returns boolean

      True if the string is an absolute path, otherwise false.

    • Creates a new temporary directory under the system temporary directory.

      The directory is marked as disposable().

      Parameters

      • Optionalopts: { prefix?: string }

      Returns Promise<FsPath>