# CapabilityRegistry Class

Expands a LicenseEntitlement's capability tokens against a table of CapabilityGrants into the concrete functions and features they grant, and answers which token, if any, covers a given function id.

# Constructors

# constructor

+ new CapabilityRegistry(table?: ReadonlyMap‹string, CapabilityGrant›): CapabilityRegistry

Defined in src/license/CapabilityRegistry.ts:33 (opens new window)

Parameters:

Name Type
table? ReadonlyMap‹string, CapabilityGrant›

Returns: CapabilityRegistry

# Methods

# capabilityOf

▸ capabilityOf(functionId: string): string | undefined

Defined in src/license/CapabilityRegistry.ts:120 (opens new window)

Returns the capability token a function id is covered by, or undefined if this registry's table does not cover it. The completeness invariant in the paired hyperformula-tests suite (unit/license/capability-registry.spec.ts) guarantees every built-in registered in the static function registry is covered by the table or the protected list — so undefined for a function known to the current instance's function registry means it is a custom, instance-registered function rather than an unlisted built-in.

Parameters:

Name Type
functionId string

Returns: string | undefined


# resolve

▸ resolve(entitlement: LicenseEntitlement): ResolvedCapabilities

Defined in src/license/CapabilityRegistry.ts:82 (opens new window)

Expands an entitlement's capability tokens into the concrete functions and features they grant. An unrestricted entitlement short-circuits to 'all' on BOTH axes without consulting the table at all. Tokens are matched case-insensitively (the table is keyed by the normalized spelling — see normalizeCapabilityToken). Every grant stands on its own — a token never refers to another — so this is a flat pass over the entitlement's own tokens; an unrecognized token is skipped without an error, and a repeated one adds nothing.

Setting 'all' on both axes here, in the same object literal, is deliberate: this is the only place entitlement.unrestricted is read, so a future edit that touches one axis and not the other has nowhere else to be caught except the per-axis fail-open tests in unit/license/capability-registry.spec.ts. The axis a change forgets fails CLOSED, not open — silently turning a working gpl-v3/legacy install into a partial denial — which is why both are pinned separately rather than with one combined assertion.

Parameters:

Name Type Description
entitlement LicenseEntitlement the entitlement to resolve, e.g. one built by hand in a test or produced by the license-key payload adapter

Returns: ResolvedCapabilities