Rules and replacements
2 minutes read
Ebb provides two synchronous, offline helpers on top of its active-data index:
rulesFor(purl, options?)returns every active lifecycle rule for a component, ordered by version range start (oldest first, ties broken cleanly byrule.id).replacementFor(purl, version)evaluatespurlatversionthroughcheckand returns the highest-precedence suggested replacement, returning a normalised PURL when a rule names a package replacement.
import { rulesFor } from "@velella/ebb/rules-for";
import { replacementFor } from "@velella/ebb/replacement";
By design, neither function reads arbitrary project files or accesses the network; only the first lookup reads Ebb's active local rule bundle, and later calls reuse the warm index.
Listing rules with rulesFor
rulesFor(purl, options?) accepts any PURL string (normalised through src/purl.ts) and returns a fresh array of matching RegistryV2Rule records, including symbol-level rules. Unknown or unflagged components return [].
The example below looks up pkg:npm/@angular/core (whose rules are stored newest-first in registry/npm.json) and also filters to "end-of-support":
import { rulesFor } from "@velella/ebb/rules-for";
const all = rulesFor("pkg:npm/@angular/core");
const unsupported = rulesFor("pkg:npm/@angular/core", { event: "end-of-support" });
console.log(
JSON.stringify(
{
allIds: all.map((rule) => rule.id),
unsupported: unsupported.map((rule) => ({
id: rule.id,
vers: rule.vers,
event: rule.event,
replacement: rule.replacement ?? null,
})),
},
null,
2,
),
);
Output:
{
"allIds": [
"npm.package.angular.core.v18-and-older.end-of-support",
"npm.package.angular.core.v19.end-of-support",
"npm.package.angular.core.v20.scheduled-end-of-life",
"npm.package.angular.core.v21.scheduled-end-of-life",
"npm.package.angular.core.v22.scheduled-end-of-life"
],
"unsupported": [
{
"id": "npm.package.angular.core.v18-and-older.end-of-support",
"vers": "vers:npm/<19.0.0-0",
"event": "end-of-support",
"replacement": "@angular/core@22"
},
{
"id": "npm.package.angular.core.v19.end-of-support",
"vers": "vers:npm/>=19.0.0-0|<20.0.0-0",
"event": "end-of-support",
"replacement": "@angular/core@22"
}
]
}
Resolving replacements with replacementFor
replacementFor(purl, version) delegates version matching and match precedence to check(purl, version) and picks the first non-empty replacement:
- When a rule names a replacement package or an explicit
pkg:URL,replacementForreturns a canonical PURL validated withsrc/purl.ts. - When a rule gives prose advice, a URL, or a non-package API identifier, it returns that string unchanged.
- When no rule matches, or when the matching rules omit a replacement, it returns
null(never"") without throwing.
import { replacementFor } from "@velella/ebb/replacement";
console.log(
JSON.stringify(
{
nodeSass: replacementFor("pkg:npm/node-sass", "9.0.0"),
babelEs2015: replacementFor("pkg:npm/babel-preset-es2015", "6.24.1"),
request: replacementFor("pkg:npm/request", "2.88.2"),
mongodb: replacementFor("pkg:generic/mongodb", "5.0.0"),
express: replacementFor("pkg:npm/express", "4.21.0"),
},
null,
2,
),
);
Output:
{
"nodeSass": "pkg:npm/sass",
"babelEs2015": "pkg:npm/%40babel/preset-env",
"request": "Native fetch or a maintained HTTP client",
"mongodb": null,
"express": null
}
API, options, and errors
src/rules-for.ts and src/replacement.ts export:
| Symbol | Module | Role |
|---|---|---|
rulesFor(purl, options?) |
@velella/ebb/rules-for |
Returns Rule[] sorted oldest-first by range start, then by rule.id, optionally filtered by options.event. |
replacementFor(purl, version) |
@velella/ebb/replacement |
Returns the normalised replacement PURL or guidance string for the highest-precedence match, or null. |
Rule |
@velella/ebb/rules-for |
Alias of RegistryV2Rule. |
RuleEvent |
@velella/ebb/rules-for |
Allowed { event } values: "deprecated", "end-of-support", "end-of-life", "removed", "scheduled-end-of-life". |
RulesForOptions |
@velella/ebb/rules-for |
{ event?: RuleEvent } |
RulesForError |
@velella/ebb/rules-for |
Thrown when options.event is not a valid lifecycle event. |
Error behavior
| Error | Thrown by | When |
|---|---|---|
PurlError |
rulesFor, replacementFor |
Input PURL is malformed (or an explicit pkg: replacement PURL in custom data is invalid). |
RulesForError |
rulesFor |
options.event is not one of the five registry lifecycle events. |
VersError |
replacementFor |
version is empty or invalid for the matched rule's version scheme. |
CheckError |
replacementFor |
Bare product name (without pkg:) is unknown or ambiguous. |