northrook/pathfinder

Resolve paths for files and directories at runtime using predefined key-value pairs

Maintainers

Package info

codeberg.org/northrook/pathfinder

Issues

pkg:composer/northrook/pathfinder

Transparency log

Statistics

Installs: 356

Dependents: 11

Suggesters: 0

dev-main 2026-08-20 08:28 UTC

This package is auto-updated.

Last update: 2026-08-20 07:28:13 UTC


README

Resolves configured parameter references into filesystem paths (Northrook\Filesystem\Path) and hyperlink references (Northrook\Reference\Href).

Implements Northrook\PathfinderInterface.

Install

composer require northrook/pathfinder

Requires PHP 8.5+, northrook/core-contracts, and northrook/php-filesystem.

Quick start

use Northrook\Pathfinder;

$pathfinder = new Pathfinder([
    'project.dir' => '/srv/app',
    'url.base'    => 'https://example.test',

    'path.cache'  => '{project.dir}/var/cache',
    'url.assets'  => '{url.base}/assets',
]);

$pathfinder->getPath('{path.cache}/items.json'); // Path → /srv/app/var/cache/items.json
$pathfinder->getHref('{url.assets}/app.css');    // Href → https://example.test/assets/app.css
$pathfinder->getHref('resources/icon.svg');      // Href → resources/icon.svg
$pathfinder->getPath('robots.txt');              // Path → robots.txt (passthrough)

References

FormMeaning
{key}Expanded parameter value
{key}/relative/suffixValue + joined suffix (URL suffixes insert before ? / #)
{key}/…/{other}Leading key joined as above; further {…} in the suffix expanded
…/{key}/…Any {key} in a non-leading form expanded left-to-right
Bare / absolute string (no {…})Passed through unchanged, then type-checked

Parameters always use braces. A bare dotted name like path.cache is a literal string — not a parameter lookup. There is no implicit join onto project.dir or url.base.

Parameter values may contain any number of {nested.key} placeholders (and literal %). Nested unknown keys inside configured values throw; unknown keys at the call site (any placeholder in the reference) return null.

Path vs Href

CallResolved shape is an hrefResolved shape is a filesystem path
getPathInvalidArgumentExceptionPath
getHrefHrefInvalidArgumentException

Href accepts safe relative references, path-absolute references, fragments, query-only references, protocol-relative links, and allowed schemes such as http, https, mailto, tel, and sms.

“Filesystem path” for getHref means Windows drive / UNC shapes (C:\…, \\server\share). POSIX absolute strings like /assets/app.css are valid hrefs.

Non-existent filesystem targets may still yield a Path — existence is checked on the object (exists(), etc.).

Null vs throw

OutcomeWhen
nullMissing / unresolvable reference (unknown {key}, empty string)
ThrowCycles, empty/{} or invalid placeholders, unbalanced {, wrong {key} remainder, path/URL shape mismatch

Href is an attribute-safe reference value object. Promote it with asUrl() when you need Url transport or structural helpers.

Constructor

use Northrook\Pathfinder\PathfinderConfig;

new Pathfinder(
    array $parameters = [],
    ?PathfinderConfig $config = null,
    ?FilesystemInterface $filesystem = null,
    ?LoggerInterface $logger = null,
);
new PathfinderConfig(
    bool $preload = false,              // call preload() in the constructor
    bool|string $useCache = false,      // false = off; true = {cacheParameter} or get_temp_path('pathfinder.cache'); string = path
    bool $commitOnDestruct = true,
    string $cacheParameter = 'path.pathfinder_cache',
);

Defaults live on PathfinderConfig::DEFAULTS and can be passed (or merged) into PathfinderConfig::from().

Construction is light unless $preload is true — the cache dump is not loaded until preload(). Call preload() after Autowire (logger, etc.) when you need the dump hydrated before the first resolve. getPath, getHref, commit, and bustCache call preload() automatically if it has not run yet.

Cache

Optional PHP dump-file persistence of resolved parameter values (placeholders already expanded). Speeds up repeated boots by skipping placeholder parsing.

  • The dump is keyed by a checksum of the raw constructor map. If that map changes, the dump is ignored and rewritten on the next commit.
  • A malformed or unreadable cache file is logged at critical and treated as empty — boot continues.
  • commit(bool $force = false): bool expands every parameter, then writes when the source checksum changed (or always when $force).
  • bustCache(): bool clears the in-memory resolved map and deletes the dump file (true when a file was removed).
  • When $commitOnDestruct is true and a cache file is configured, __destruct preloads (if needed) and commits; failures there are logged, not thrown. commitOnDestruct is ignored when caching is off.
  • When $useCache is true, the path comes from the parameter named by $cacheParameter (default path.pathfinder_cache), else get_temp_path('pathfinder.cache').

Parameter key names have no inherent path/URL meaning — prefixes like path. or url. are never trusted; only the resolved string value matters.

Path and Href

getPath returns Northrook\Filesystem\Path. getHref returns Northrook\Reference\Href.

Both are immutable value objects from core-contracts. Use Path::join() for filesystem composition. Use Href::asUrl() when you need Url::append() / with*() / mergeQuery() or HTTP helpers.

HTTP operations still live on Url, not Href.

Path

  • File::write() creates parent directories by default.
  • glob($pattern) runs patterns relative to this path as a directory base. When the path is an existing file, the base is dirname($path).

Href

ShapeBehavior
Relative / /absoluteAccepted
#fragment / ?queryAccepted
http: / https:Accepted
mailto: / tel: / sms:Accepted
javascript: / data:Rejected
Windows drive / UNC pathRejected as filesystem paths

Parameter keys

Validated via Assert::validKey() with charset alnum, ., _, \, -, :.

Rejected in keys: % and / (suffixes are never part of the key). Values must be non-empty after trim.