Skip to content

feat: add createAccess, error classes, and override layer#3

Merged
Apetuezekiel merged 1 commit into
mainfrom
feat/access-api
May 16, 2026
Merged

feat: add createAccess, error classes, and override layer#3
Apetuezekiel merged 1 commit into
mainfrom
feat/access-api

Conversation

@Apetuezekiel

Copy link
Copy Markdown
Owner

What

Implements the full runtime access API: error classes, override application, and createAccess.

New files:

  • src/errors.tsAccessDeniedError (carries feature, plan, requiredPlans: string[]) and InvalidOverrideError (carries reason: 'unknown_feature' | 'grant_revoke_conflict', feature). Both extend Error, set prototype correctly for cross-module instanceof, and implement toJSON() returning JSON-serializable plain objects.
  • src/overrides.tsapplyOverrides(config, resolved, overrides) validates all features in grant/revoke are declared, throws on grant ∩ revoke conflicts, then returns a new effective ResolvedPlan.
  • src/access.tscreateAccess(config, { plan, overrides? }) returning { can, cannot, guard, diff }.
    • guard throws AccessDeniedError with requiredPlans computed as all plans whose resolved feature set includes the feature
    • diff(targetPlan) returns { gains: string[], limitUpgrades: Record<string, { from, to }> } against the effective (post-override) set
    • Gracefully skips unresolvable plans when computing requiredPlans

Updated:

  • src/index.ts — exports all public symbols: createAccess, defineConfig, AccessDeniedError, InvalidOverrideError, and all types
  • src/index.test.ts — verifies the full export surface

Tests (74 total, 100% coverage):

  • src/errors.test.ts — 10 tests: instanceof, metadata fields, message content, toJSON shape, JSON round-trip
  • src/overrides.test.ts — 11 tests: grant adds feature, grant idempotent, unknown grant throws, revoke removes feature, revoke beats inheritance, unknown revoke throws, grant∩revoke conflict throws with correct reason, empty overrides, limits preserved
  • src/access.test.ts — 28 tests: can/cannot, guard happy/sad path, requiredPlans enumeration, multi-plan requiredPlans, JSON serialization, grant/revoke overrides, conflict, diff gains/exclusions, limitUpgrades including asymmetric keys and null-quota, broken plan graceful handling

Why

Implements v1 scope items 2, 3, and 4: the createAccess feature gate API, the override layer, and the structured error classes with their specified field shapes and JSON serializability guarantee.

How to verify

npm run lint       # clean
npm run typecheck  # clean
npm run test       # 74 tests, 100% coverage
npm run build      # dist/ ~5.4 KB ESM, ~5.5 KB CJS

Out of scope

  • JSON Schema generation — PR 4
  • Full README — PR 5
  • overrides.limits runtime API — deferred to v1.1
  • createUsage / usage tracking — explicitly out of v1 scope

@Apetuezekiel Apetuezekiel merged commit 8defb55 into main May 16, 2026
5 checks passed
@Apetuezekiel Apetuezekiel deleted the feat/access-api branch May 16, 2026 17:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant