zena:path
import {…} from 'zena:path';
File path manipulation and inspection for forward-slash delimited paths.
This module provides two complementary APIs:
- Standalone string functions: (
join,dirname,basename,extname,normalize,relative,split,stripPrefix) operate directly on standardStringvalues. - Strongly typed path classes: (
Path,AbsolutePath,RelativePath,PathSegment,FilePath,DirectoryPath) wrapStringas extension classes to enforce path invariants at compile time with zero runtime allocation overhead.
Strongly Typed Paths ​
Using plain strings for paths can lead to subtle bugs, such as passing a relative path where an absolute path is required or joining two absolute paths together. The typed path hierarchy models path distinctions in the type system:
Path: Base extension class for any path.AbsolutePath: A path guaranteed to start with/.RelativePath: A path guaranteed not to start with/.PathSegment: A single non-empty relative component containing no/.FilePath: A path representing a file.DirectoryPath: A path representing a directory, with fluent child navigation.
Because these are Zena extension classes on String, they are erased at
runtime. A Path or AbsolutePath is represented as an unboxed String
in WebAssembly memory with no object wrappers and no virtual method tables.
Constructing and Validating Paths ​
Standard constructors validate format at runtime and throw Error on invalid
input:
let abs = new AbsolutePath('/usr/local/bin');
let rel = new RelativePath('src/main.zena');
let seg = new PathSegment('main.zena');
When input is already known to be valid (for example, output from an internal
helper), the unchecked constructors bypass validation checks:
let fastAbs = new AbsolutePath.unchecked('/etc/hosts');
Type-Safe Path Operations ​
Typed paths enforce sound combinations. For example, AbsolutePath.join()
requires a RelativePath parameter and returns an AbsolutePath:
let root = new AbsolutePath('/home/user');
let sub = new RelativePath('projects/zena');
let projectDir = root.join(sub); // AbsolutePath: '/home/user/projects/zena'
Conversions ​
A general Path can be converted to more specific types:
toAbsolutePath()andtoRelativePath()validate at runtime and throwErrorif the path does not match the target format.toFilePath()andtoDirectoryPath()are erased compile-time casts with no runtime checks.
Examples ​
import { join, dirname, basename, extname, AbsolutePath, RelativePath, DirectoryPath } from 'zena:path';
// Standalone functions on strings:
let fullPath = join(['src/lib', 'index.zena']);
let dir = dirname(fullPath);
let file = basename(fullPath);
let ext = extname(fullPath);
// Strongly typed path classes:
let project = new DirectoryPath('/workspace/app');
let src = project.dir('src');
let mainFile = src.file('main.zena');
let extStr = mainFile.extension; // '.zena'
Classes
Path
extension class Path
A strongly-typed representation of a filesystem path.
Path is the base extension class for all path types, extending String.
It provides methods for path inspection, normalization, extension handling,
and navigation.
Subclasses ​
AbsolutePath: An absolute path starting with/.RelativePath: A relative path not starting with/.PathSegment: A single non-empty relative component containing no/. (Subclass ofRelativePath.)FilePath: A path representing a file, with file-specific properties likeextension.DirectoryPath: A path representing a directory, with fluent methods (file,dir,directory) for building child paths.
Performance Characteristics ​
All path classes are Zena extension classes on String. At runtime, they are
erased to plain strings with zero heap allocation overhead, no wrappers,
and no virtual dispatch.
new(value: String)
Constructs a Path from a string.
Zero-cost compile-time cast. Performs no runtime validation check and no heap allocation.
normalize(): this
Returns a normalized copy of this path, preserving its concrete type.
dirname(): Path
Returns the directory portion of this path.
parent(): Path
Alias for dirname().
basename(suffix: String = ''): String
Returns the last component of this path.
extname(): String
Returns the file extension, or '' if none.
withExtension(newExt: String): this
Returns a copy with the extension replaced or appended, preserving concrete type.
withoutExtension(): this
Returns a copy with the extension removed, preserving concrete type.
join(rel: RelativePath): Path
Joins a relative path to this path.
split(): FixedArray<PathSegment>
Splits this path into non-empty segments.
relative(to: Path): RelativePath
Computes the relative path from this path to to.
stripPrefix(prefix: Path): RelativePath | null
Strips prefix from this path if it begins with prefix.
toAbsolutePath(): AbsolutePath
Converts this path to an AbsolutePath.
Performs a runtime check to verify the path starts with '/'. Zero heap allocation (extension classes are erased at runtime).
toRelativePath(): RelativePath
Converts this path to a RelativePath.
Performs a runtime check to verify the path does not start with '/'. Zero heap allocation (extension classes are erased at runtime).
toFilePath(): FilePath
Converts this path to a FilePath.
Zero-cost compile-time cast. Performs no runtime validation check and no heap allocation.
toDirectoryPath(): DirectoryPath
Converts this path to a DirectoryPath.
Zero-cost compile-time cast. Performs no runtime validation check and no heap allocation.
toString(): String
Returns the underlying string.
Zero-cost erased cast returning the underlying String directly with no
copy or allocation.
AbsolutePath
extension class AbsolutePath extends Path
An absolute filesystem path (starts with '/').
Subclass of Path. Enforces that the path begins with a leading forward slash.
new(value: String)
Constructs an AbsolutePath, validating that value starts with '/'.
Performs a runtime check. Zero heap allocation (erased at runtime).
new unchecked(value: String)
Constructs an AbsolutePath without runtime validation.
Use when value is already known to start with '/'.
Zero-cost compile-time cast with no runtime check and no allocation.
join(rel: RelativePath): AbsolutePath
Joins a relative path to this absolute path, producing an AbsolutePath.
dirname(): AbsolutePath
Returns the directory portion of this path as an AbsolutePath.
parent(): AbsolutePath
Alias for dirname().
toAbsolutePath(): AbsolutePath
Returns this path as an AbsolutePath.
Zero-cost identity operation (return this;). Performs no runtime check
and no allocation.
15 inherited members
Path
normalize(): this
Returns a normalized copy of this path, preserving its concrete type.
basename(suffix: String = ''): String
Returns the last component of this path.
extname(): String
Returns the file extension, or '' if none.
withExtension(newExt: String): this
Returns a copy with the extension replaced or appended, preserving concrete type.
withoutExtension(): this
Returns a copy with the extension removed, preserving concrete type.
split(): FixedArray<PathSegment>
Splits this path into non-empty segments.
relative(to: Path): RelativePath
Computes the relative path from this path to to.
stripPrefix(prefix: Path): RelativePath | null
Strips prefix from this path if it begins with prefix.
toRelativePath(): RelativePath
Converts this path to a RelativePath.
Performs a runtime check to verify the path does not start with '/'. Zero heap allocation (extension classes are erased at runtime).
toFilePath(): FilePath
Converts this path to a FilePath.
Zero-cost compile-time cast. Performs no runtime validation check and no heap allocation.
toDirectoryPath(): DirectoryPath
Converts this path to a DirectoryPath.
Zero-cost compile-time cast. Performs no runtime validation check and no heap allocation.
toString(): String
Returns the underlying string.
Zero-cost erased cast returning the underlying String directly with no
copy or allocation.
RelativePath
extension class RelativePath extends Path
A relative filesystem path (does not start with '/').
Subclass of Path. Enforces that the path does not begin with a leading
forward slash.
new(value: String)
Constructs a RelativePath, validating that value does not start with '/'.
Performs a runtime check. Zero heap allocation (erased at runtime).
new unchecked(value: String)
Constructs a RelativePath without runtime validation.
Use when value is already known not to start with '/'.
Zero-cost compile-time cast with no runtime check and no allocation.
join(rel: RelativePath): RelativePath
Joins a relative path to this relative path, producing a RelativePath.
dirname(): RelativePath
Returns the directory portion of this path as a RelativePath.
parent(): RelativePath
Alias for dirname().
toRelativePath(): RelativePath
Returns this path as a RelativePath.
Zero-cost identity operation (return this;). Performs no runtime check
and no allocation.
15 inherited members
Path
normalize(): this
Returns a normalized copy of this path, preserving its concrete type.
basename(suffix: String = ''): String
Returns the last component of this path.
extname(): String
Returns the file extension, or '' if none.
withExtension(newExt: String): this
Returns a copy with the extension replaced or appended, preserving concrete type.
withoutExtension(): this
Returns a copy with the extension removed, preserving concrete type.
split(): FixedArray<PathSegment>
Splits this path into non-empty segments.
relative(to: Path): RelativePath
Computes the relative path from this path to to.
stripPrefix(prefix: Path): RelativePath | null
Strips prefix from this path if it begins with prefix.
toAbsolutePath(): AbsolutePath
Converts this path to an AbsolutePath.
Performs a runtime check to verify the path starts with '/'. Zero heap allocation (extension classes are erased at runtime).
toFilePath(): FilePath
Converts this path to a FilePath.
Zero-cost compile-time cast. Performs no runtime validation check and no heap allocation.
toDirectoryPath(): DirectoryPath
Converts this path to a DirectoryPath.
Zero-cost compile-time cast. Performs no runtime validation check and no heap allocation.
toString(): String
Returns the underlying string.
Zero-cost erased cast returning the underlying String directly with no
copy or allocation.
PathSegment
extension class PathSegment extends RelativePath
A single path segment (non-empty, contains no '/').
Subclass of RelativePath. Represents an individual component within a path.
new(value: String)
Constructs a PathSegment, validating that value is non-empty and
contains no '/'.
Performs a runtime check. Zero heap allocation (erased at runtime).
new unchecked(value: String)
Constructs a PathSegment without runtime validation.
Use when value is already known to be a non-empty string with no '/'.
Zero-cost compile-time cast with no runtime check and no allocation.
split(): FixedArray<PathSegment>
A single segment splits into an array containing only itself.
18 inherited members
Path
normalize(): this
Returns a normalized copy of this path, preserving its concrete type.
basename(suffix: String = ''): String
Returns the last component of this path.
extname(): String
Returns the file extension, or '' if none.
withExtension(newExt: String): this
Returns a copy with the extension replaced or appended, preserving concrete type.
withoutExtension(): this
Returns a copy with the extension removed, preserving concrete type.
relative(to: Path): RelativePath
Computes the relative path from this path to to.
stripPrefix(prefix: Path): RelativePath | null
Strips prefix from this path if it begins with prefix.
toAbsolutePath(): AbsolutePath
Converts this path to an AbsolutePath.
Performs a runtime check to verify the path starts with '/'. Zero heap allocation (extension classes are erased at runtime).
toFilePath(): FilePath
Converts this path to a FilePath.
Zero-cost compile-time cast. Performs no runtime validation check and no heap allocation.
toDirectoryPath(): DirectoryPath
Converts this path to a DirectoryPath.
Zero-cost compile-time cast. Performs no runtime validation check and no heap allocation.
toString(): String
Returns the underlying string.
Zero-cost erased cast returning the underlying String directly with no
copy or allocation.
RelativePath
join(rel: RelativePath): RelativePath
Joins a relative path to this relative path, producing a RelativePath.
dirname(): RelativePath
Returns the directory portion of this path as a RelativePath.
parent(): RelativePath
Alias for dirname().
toRelativePath(): RelativePath
Returns this path as a RelativePath.
Zero-cost identity operation (return this;). Performs no runtime check
and no allocation.
FilePath
extension class FilePath extends Path
A strongly-typed filesystem path representing a file.
Subclass of Path. Provides access to file-specific properties like
extension.
new(value: String)
Constructs a FilePath from a string.
Zero-cost compile-time cast. Performs no runtime validation check and no heap allocation.
extension: String { get; }
The file extension (including leading dot), or '' if none.
19 inherited members
Path
normalize(): this
Returns a normalized copy of this path, preserving its concrete type.
dirname(): Path
Returns the directory portion of this path.
parent(): Path
Alias for dirname().
basename(suffix: String = ''): String
Returns the last component of this path.
extname(): String
Returns the file extension, or '' if none.
withExtension(newExt: String): this
Returns a copy with the extension replaced or appended, preserving concrete type.
withoutExtension(): this
Returns a copy with the extension removed, preserving concrete type.
join(rel: RelativePath): Path
Joins a relative path to this path.
split(): FixedArray<PathSegment>
Splits this path into non-empty segments.
relative(to: Path): RelativePath
Computes the relative path from this path to to.
stripPrefix(prefix: Path): RelativePath | null
Strips prefix from this path if it begins with prefix.
toAbsolutePath(): AbsolutePath
Converts this path to an AbsolutePath.
Performs a runtime check to verify the path starts with '/'. Zero heap allocation (extension classes are erased at runtime).
toRelativePath(): RelativePath
Converts this path to a RelativePath.
Performs a runtime check to verify the path does not start with '/'. Zero heap allocation (extension classes are erased at runtime).
toFilePath(): FilePath
Converts this path to a FilePath.
Zero-cost compile-time cast. Performs no runtime validation check and no heap allocation.
toDirectoryPath(): DirectoryPath
Converts this path to a DirectoryPath.
Zero-cost compile-time cast. Performs no runtime validation check and no heap allocation.
toString(): String
Returns the underlying string.
Zero-cost erased cast returning the underlying String directly with no
copy or allocation.
DirectoryPath
extension class DirectoryPath extends Path
A strongly-typed filesystem path representing a directory.
Subclass of Path. Provides convenience methods for navigating and creating
child paths.
new(value: String)
Constructs a DirectoryPath from a string.
Zero-cost compile-time cast. Performs no runtime validation check and no heap allocation.
join(segment: String): Path
Joins a child path segment to this directory.
file(name: String): FilePath
Joins a file name to this directory, returning a FilePath.
dir(name: String): DirectoryPath
Joins a child directory name to this directory, returning a DirectoryPath.
directory(name: String): DirectoryPath
Joins a child directory name to this directory, returning a DirectoryPath.
18 inherited members
Path
normalize(): this
Returns a normalized copy of this path, preserving its concrete type.
dirname(): Path
Returns the directory portion of this path.
parent(): Path
Alias for dirname().
basename(suffix: String = ''): String
Returns the last component of this path.
extname(): String
Returns the file extension, or '' if none.
withExtension(newExt: String): this
Returns a copy with the extension replaced or appended, preserving concrete type.
withoutExtension(): this
Returns a copy with the extension removed, preserving concrete type.
split(): FixedArray<PathSegment>
Splits this path into non-empty segments.
relative(to: Path): RelativePath
Computes the relative path from this path to to.
stripPrefix(prefix: Path): RelativePath | null
Strips prefix from this path if it begins with prefix.
toAbsolutePath(): AbsolutePath
Converts this path to an AbsolutePath.
Performs a runtime check to verify the path starts with '/'. Zero heap allocation (extension classes are erased at runtime).
toRelativePath(): RelativePath
Converts this path to a RelativePath.
Performs a runtime check to verify the path does not start with '/'. Zero heap allocation (extension classes are erased at runtime).
toFilePath(): FilePath
Converts this path to a FilePath.
Zero-cost compile-time cast. Performs no runtime validation check and no heap allocation.
toDirectoryPath(): DirectoryPath
Converts this path to a DirectoryPath.
Zero-cost compile-time cast. Performs no runtime validation check and no heap allocation.
toString(): String
Returns the underlying string.
Zero-cost erased cast returning the underlying String directly with no
copy or allocation.
Functions
isAbsolute
function isAbsolute(path: String): boolean
Returns true if path is an absolute path (starts with '/').
split
function split(path: String): FixedArray<PathSegment>
Splits path by the separator into non-empty segments using a two-pass
approach that returns a fixed-size array of PathSegments.
normalize
function normalize(path: String): String
Normalizes path, resolving '.' and '..' segments and collapsing
multiple consecutive slashes.
Leading '/' is preserved for absolute paths. Leading '..' segments are preserved for relative paths that navigate above their starting point.
dirname
function dirname(path: String): String
Returns the directory name of path, similar to POSIX dirname.
Trailing slashes are ignored.
basename
function basename(path: String, suffix: String = ''): String
Returns the last component of path, similar to POSIX basename.
If suffix is provided and the basename ends with suffix (and is longer
than suffix), the suffix is removed.
extname
function extname(path: String): String
Returns the extension of path from the last '.' to the end of the
filename. Returns an empty string if there is no '.' or if the '.' is the
first character of the filename (e.g. '.gitignore').
withExtension
function withExtension(path: String, newExt: String): String
Replaces or appends the extension of path.
If newExt does not start with '.', one is automatically added
(unless newExt is empty, in which case the extension is removed).
join2
function join2(a: String, b: String): String
Joins two path segments and normalizes the result.
If b is an absolute path, it replaces a.
join
function join(parts: Array<String>): String
Joins all given path segments together and normalizes the resulting path. If any segment is absolute, preceding segments are ignored.
stripPrefix
function stripPrefix(path: String, prefix: String): String | null
Strips prefix from path if path begins with prefix at a directory boundary.
Returns the remainder (without leading slash), or null if prefix does not match.
relative
function relative(from: String, to: String): String
Computes the relative path from from to to.
If both paths resolve to the same location, returns '.'.
Variables
separator
let separator: String
The path segment separator ('/').
delimiter
let delimiter: String
The platform path list delimiter (':' in POSIX/WASI).