Abstract Class: DomainPath
Defined in: packages/core/src/domain/value-objects/domain-path.ts:33
Abstract base for immutable, validated domain path value objects.
Stores a non-empty sequence of path segments and provides the common navigation and comparison operations shared by all concrete path types.
Subclasses are responsible for:
- Validating and constructing paths via their own static factory methods
- Guaranteeing that
segmentsis always non-empty - Implementing
_withSegmentsto produce new instances of the concrete type
Example
class ArchivePath extends DomainPath {
private constructor(segments: readonly string[]) { super(segments) }
protected _withSegments(segments: readonly string[]): this {
return new ArchivePath(segments) as this
}
static parse(path: string): ArchivePath {
// validate and construct...
return new ArchivePath(path.split('/'))
}
}
const p = ArchivePath.parse('2024/my-feature')
p.leaf // → "my-feature"
p.parent // → ArchivePath("2024")
p.child('v2') // → ArchivePath("2024/my-feature/v2")
Extended by
Constructors
Constructor
protectednew DomainPath(segments):DomainPath
Defined in: packages/core/src/domain/value-objects/domain-path.ts:43
Stores the pre-validated segments. Must only be called from subclass static factory methods after validation.
Parameters
segments
readonly string[]
Non-empty, pre-validated array of path segments
Returns
DomainPath
Properties
_segments
protectedreadonly_segments: readonlystring[]
Defined in: packages/core/src/domain/value-objects/domain-path.ts:35
The validated, non-empty sequence of path segments.
Accessors
leaf
Get Signature
get leaf():
string
Defined in: packages/core/src/domain/value-objects/domain-path.ts:77
The last segment of the path (e.g. "oauth" for "auth/oauth").
Safe to call without null-check — subclasses guarantee non-empty segments.
Returns
string
parent
Get Signature
get parent():
this|null
Defined in: packages/core/src/domain/value-objects/domain-path.ts:89
The parent path, or null if this is a top-level (single-segment) path.
Returns the same concrete type as the receiver.
Example
`SpecPath.parse("auth/oauth").parent` → `SpecPath("auth")`
Returns
this | null
Methods
_withSegments()
abstractprotected_withSegments(segments):this
Defined in: packages/core/src/domain/value-objects/domain-path.ts:70
Creates a new instance of the concrete subtype wrapping the given segments.
This method exists because parent and child need to return the same
concrete type as the receiver (e.g. SpecPath.parent must return a
SpecPath, not a DomainPath), but the base class cannot call a subclass
constructor directly — those constructors are private by design.
Each subclass implements this as a one-liner that calls its own private
constructor. Implementations must NOT re-validate the segments — they are
already trusted (they come from the current instance or from parse).
Parameters
segments
readonly string[]
Pre-validated, non-empty array of path segments
Returns
this
A new instance of the concrete subtype
Example
// In SpecPath:
protected _withSegments(segments: readonly string[]): this {
return new SpecPath(segments) as this
}
child()
child(
segment):this
Defined in: packages/core/src/domain/value-objects/domain-path.ts:104
Returns a new path with segment appended.
The base implementation does not validate the segment — subclasses that
enforce segment constraints (e.g. SpecPath) should override this method
and apply their own validation before delegating to _withSegments.
Parameters
segment
string
The segment to append
Returns
this
A new path one level deeper, of the same concrete type
equals()
equals(
other):boolean
Defined in: packages/core/src/domain/value-objects/domain-path.ts:130
Returns whether this path is structurally equal to other.
Equality is determined by string representation.
Parameters
other
DomainPath
The path to compare against
Returns
boolean
true if both paths have the same string representation
isAncestorOf()
isAncestorOf(
other):boolean
Defined in: packages/core/src/domain/value-objects/domain-path.ts:117
Returns whether this path is a strict ancestor of other.
A path is an ancestor of other if other starts with all of this
path's segments and has at least one additional segment.
Parameters
other
DomainPath
The path to test against
Returns
boolean
true if other starts with this path and has more segments
toFsPath()
toFsPath(
sep):string
Defined in: packages/core/src/domain/value-objects/domain-path.ts:168
Returns a native filesystem path suitable for disk operations.
The caller provides the platform separator so the domain layer stays free
of Node.js dependencies. Pass path.sep from node:path in infrastructure
adapters — '/' on POSIX, '\\' on Windows.
Parameters
sep
string
The platform path separator to use between segments
Returns
string
The OS-native path string
Example
// In an infrastructure adapter:
import { sep, resolve } from 'node:path'
const fullPath = resolve(root, specPath.toFsPath(sep))
await fs.readFile(fullPath, 'utf8')
toString()
toString():
string
Defined in: packages/core/src/domain/value-objects/domain-path.ts:146
Returns the canonical slash-separated representation (e.g. "auth/oauth").
This is the domain identity of the path — always '/'-separated regardless
of the host operating system. It is suitable for serialisation, display, and
use as a map key, but NOT for filesystem operations on Windows.
Infrastructure adapters that need a native filesystem path must use toFsPath instead of this method.
Returns
string
The canonical path string