Skip to content

pattern

Literal / glob / regex string matching, compiled to a composable Predicate.

A configurable allow-list is the same shape everywhere in this repo: a list of patterns from a config field or an env var, where an operator reasonably expects to write a plain value, a * wildcard, or - when neither is enough - a real regex. Each consumer used to grow its own globToRegExp + /pattern/flags parser; this is that parser, once.

Three shapes are recognized per entry, tried in order:

  • regex - wrapped in slashes (/^x-mastra-/, with optional trailing flags). Compiled as written. An invalid regex never matches: it is skipped with a warning rather than throwing, so one bad entry cannot take a process down at startup.
  • glob - contains * or ? (x-mastra-*). Shell-style, anchored at both ends: * matches any run of characters, ? exactly one.
  • literal - anything else. Whole-string equality.

Matching is case-INSENSITIVE by default, which is what the callers want (HTTP header names and email addresses are both case-insensitive); pass caseSensitive to opt out. An empty pattern list matches NOTHING, so a caller that treats “no patterns” as “permit everything” must special-case it rather than relying on the matcher.

Browser-safe: hand-compiled to RegExp with no glob dependency, so this stays usable from a client bundle. Node code that needs path-aware globbing (/ as a segment boundary, **) wants @dbx-tools/path’s toPathMatcher instead - that one is minimatch-backed and understands path semantics.

const allowed = toPatternMatcher(["x-mastra-*", "/^x-trace-/"]);
allowed("x-mastra-thread-id"); // true
allowed("x-forwarded-user"); // false